spring |Spring Security安全框架 —— 认证流程实现
文章目录
- 开头
- 简介
- 环境搭建
- 入门使用
- 1、认证
- 1、实体类
- 2、Controller层
- 3、Service层
- 3.1、接口
- 3.2、实现类
- 3.3、实现类:UserDetailsServiceImpl
- 4、Mapper层
- 3、自定义token认证filter
- 注意事项
- 小结
开头
- Spring Security 官方网址:Spring Security官网
开头贴官网,有事找官方!

简介
介绍的话不多说,就一句:
-
Spring Security 是一个安全管理框架。
- 一般用于中大型项目。小项目使用shiro,shiro上手简单。
- 不过,一般是这样。小项目练手用也是相当可以的。
好吧!这是三句话,没跑。
环境搭建
基于SpringBoot3搭建的项目,妥妥好用。
| 组件 | SpringBoot2.X | SpringBoot3.X |
|---|---|---|
| JDK | JDK 8、9 | JDK 17+ |
| JPA | JPA2.0+ | JPA3.0+ |
| Servlet | Servlet 3.1+ | Servlet 5.0 |
| Spring | Spring Framework 5+ | Spring Framework 6+ |
| Gradle | Gradle 4.x | Gradle7.3 |
1、依赖导入
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.4</version></parent><!-- spring web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
<!-- spring Security--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.7</version></dependency><!-- mysql驱动--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency>
2、配置文件
spring:datasource:url: jdbc:mysql://localhost:3306/dataBase?characterEncoding=utf-8&serverTimezone=Asia/Shanghaiusername: rootpassword: passworddriver-class-name: com.mysql.cj.jdbc.Driver
# mybatisPlus 配置
mybatis-plus:configuration:map-underscore-to-camel-case: true# 日志log-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:db-config:# 逻辑删除logic-delete-field: delFaglogic-delete-value: 1logic-not-delete-value: 0# 主键自增id-type: auto
入门使用
1、认证
废话不多说,贴个认证流程图:

1、SpringSecurity Config类
//整点实在的,一整套流程,绝对全面。
@Configuration
@EnableWebSecurity
public class SecurityConfig {@Autowiredprivate AuthenticationTokenFilter tokenFilter;@Autowiredprivate AuthenticationEntryPointImpl authenticationEntryPoint;/*PasswordEncoder是一个用于密码加密的接口,它封装了多种主流的加密方法,它们用于密码的安全存储和校验。但计算开销也相对较大,因此在面对高并发性能要求的大型信息系统时:推荐使用会话、OAuth、Token等短期加密策略来实现系统的信息安全。*/@Beanpublic PasswordEncoder getPasswordEncoder(){return new BCryptPasswordEncoder();}/*负责注册为应用程序提供认证服务的 。*/@Beanpublic AuthenticationManager authenticationManager(AuthenticationConfiguration config ) throws Exception {return config.getAuthenticationManager();}/*Security Filter是通过FilterChainProxy而不是DelegatingFilterProxy注册进SecurityFilterChain的。 过滤器链,配置*/@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception{http.csrf(csrf -> csrf.disable()); //关闭csrf防护http.authorizeHttpRequests(auth ->auth.requestMatchers("/user/login")//请求路径匹配.permitAll()//放行,不作拦截.anyRequest()//其他请求.authenticated());//认证// 自定义token 认证,用于登录后续请求放行。通过springSecurity上下文判断http.addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class);return http.build();}
1、实体类
//主要就是用:username和 password
@Data
public class SysUser implements Serializable {private static final long serialVersionUID = 662137028719131857L;private Long id;
/*** 用户名*/private String username;
/*** 昵称*/private String nickname;
/*** 密码*/private String password;
/*** 用户类型:0:普通 1:管理员*/private String type;
/*** 账号状态:0:正常 1:停用*/private String status;
/*** 邮箱*/private String email;
/*** 手机号*/private String phoneNumber;
/*** 用户性别(0:男 1:女 2 :匿名)*/private String sex;
/*** 头像*/private String avatar;private Integer isDelete;}
2、Controller层
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate SysUserService userService;@PostMapping("/login")public R login(@RequestBody SysUser user){return userService.login(user);}
}
3、Service层
3.1、接口
public interface SysUserService extends IService<SysUser> {/*** 登录* @param user* @return*/R login(SysUser user);
}
3.2、实现类
@Service
public class SysUserServiceImpl extends ServiceImpl<UserMapper, SysUser> implements SysUserService {@Autowiredprivate AuthenticationManager authenticationManager;@Overridepublic R login(SysUser user) {//重写userDetailsService 处理UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword());Authentication authenticate = authenticationManager.authenticate(authenticationToken);if(Objects.isNull(authenticate)){throw new AppException(AppExceptionMsgEnum.LOGIN_ERROR);}//jwt令牌信息//……LoginUser loginuser = (LoginUser) authenticate.getPrincipal();//自定义返回return R.success(loginuser.getUser());}
}
3.3、实现类:UserDetailsServiceImpl
- 用于用户信息认证处理
@Service
public class UserDetailsServiceImpl implements UserDetailsService {@Autowiredprivate UserMapper userMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(SysUser::getUsername,username);SysUser userResult = userMapper.selectOne(queryWrapper);if(Objects.isNull(userResult)){throw new AppException(AppExceptionMsgEnum.LOGIN_ERROR);}return new LoginUser(userResult);}
}
4、Mapper层
public interface UserMapper extends BaseMapper<SysUser> {
}
3、自定义token认证filter
@Component
public class AuthenticationTokenFilter extends OncePerRequestFilter {@Autowiredprivate UserMapper userMapper;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException, ServletException, IOException {//获取tokenString token = request.getHeader("token");String uri = request.getRequestURI();if(uri.equals("/gate/logout")){filterChain.doFilter(request,response);return;}//放行未携带token 的请求,交由后面拦截器处理if (token == null) {filterChain.doFilter(request,response);return;}//获取用户信息,这里由于没有使用jwt,所以仿制了一下SysUser user = new SysUser();user.setUsername(token);LoginUser loginUser = new LoginUser();loginUser.setUser(user);UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null,null);//存储到SecurityContextHolderSecurityContextHolder.getContext().setAuthentication(authenticationToken);//放行filterChain.doFilter(request,response);}}
注意事项
- 认证失败后,会抛出异常。使用全局异常处理器 + 自定义异常 使用。
- 自定义返回类
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)// 属性为NULL 不序列化
public class R<T> {private int status;// private boolean success;private String message;private T data;@JSONField(format="yyyy-MM-dd HH:mm:ss")private DateTime time;/*** 正确result* @param data* @param <T>* @return*/public static <T> R<T> success(T data){R<T> r = new R<>();
// r.success = true;r.status = 200;r.data = data;r.message = "successful";r.time = DateTime.now();return r;}public static <T> R<T> success(String msg ,T data){R<T> r = new R<>();
// r.success = true;r.status = 200;r.data = data;r.message = msg;r.time = DateTime.now();return r;}/*** 错误result* @param msg* @param status* @param <T>* @return*/public static <T> R<T> error(String msg,int status){R<T> r = new R<>();
// r.success = false;r.status = status;r.message = msg;r.time = DateTime.now();return r;}/*** 错误result* @param msg* @param <T>* @return*/public static <T> R<T> error(String msg){R<T> r = new R<>();
// r.success = false;r.message = msg;r.time = DateTime.now();return r;}public static <T> R<T> error(AppExceptionMsgEnum appExceptionMsg){R<T> r = new R<>();
// r.success = false;r.status = appExceptionMsg.getStatus();r.message = appExceptionMsg.getMsg();r.time = DateTime.now();return r;}}
- 全局异常处理器
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {@ExceptionHandler(value = BadCredentialsException.class)public static <T> R<T> badCredentialsException(BadCredentialsException e) throws InterruptedException {return R.error(AppExceptionMsgEnum.LOGIN_ERROR);}@ExceptionHandler(value = Exception.class)public static <T> R<T> exceptionHandle(Exception e) throws InterruptedException {if(e instanceof AppException){AppException app = (AppException) e;return R.error(app.getMsg(),app.getStatus());}return R.error(e.toString(),500);}
}
- 自定义异常
@EqualsAndHashCode(callSuper = true)
@Data
public class AppException extends RuntimeException{private int status;private String msg;public AppException(AppExceptionMsgEnum appExceptionMsgEnum) {this.status = appExceptionMsgEnum.getStatus();this.msg = appExceptionMsgEnum.getMsg();}
}
- 异常枚举类
public enum AppExceptionMsgEnum {//成功SUCCESS(200,"操作成功"),//失败NEED_LOGIN(401,"需要登录后操作"),NO_OPERATION_AUTH(403,"无权限操作"),USERNAME_EXIST(501,"用户名已存在"),PHONE_NUMBER_EXITS(502,"手机号已存在"),EMAIL_EXIST(503,"邮箱已存在"),REQUIRED_USERNAME(504,"必须填写用户名"),LOGIN_ERROR(505," 用户名或密码错误"),WRONG_PAGE_PARAM(506,"wrong page param"),CONTENT_NOT_NULL(507,"评论内容不能为空"),FILENAME_ERROR(508,"上传文件错误"),ONLY_UPDATE_SELF(509,"只能修改自己的信息"),SERVER_ERROR(500,"SERVER ERROR");private int status;private String msg;AppExceptionMsgEnum(int status, String msg) {this.status = status;this.msg = msg;}public int getStatus() {return status;}public String getMsg() {return msg;}
}
例如:
- API
- 支持模型类型
小结
-
SpringSecurity5.7.0之前
- 常见的 Spring HTTP Security 配置类都会继承一个 WebSecurityConfigureAdapter 类。
-
从 5.7.0-M2 起,WebSecurityConfigureAdapter 被废弃了,不推荐使用。
- 组件化开始,更加灵活。
-
基础认证功能完成。完结撒花!!

相关文章:
spring |Spring Security安全框架 —— 认证流程实现
文章目录 开头简介环境搭建入门使用1、认证1、实体类2、Controller层3、Service层3.1、接口3.2、实现类3.3、实现类:UserDetailsServiceImpl 4、Mapper层3、自定义token认证filter 注意事项小结 开头 Spring Security 官方网址:Spring Security官网 开…...
Django+vue自动化测试平台---正式开源!!!
自动化测试:接口、Web UI 与 App 的全面探索 在此郑重声明:本文内容未经本人同意,不得随意转载。若有违者,必将追究其法律责任。同时,禁止对相关源码进行任何形式的售卖行为,本内容仅供学习使用。 Git 地…...
电子电气架构 --- 智能网联汽车未来是什么样子?
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…...
docker安装elasticsearch(es)+kibana
目录 docker安装elasticsearch 一.准备工作 1.打开docker目录 2.创建elasticsearch目录 3.打开elasticsearch目录 4.拉取elasticsearch镜像 5.检查镜像 二.挂载目录 1.创建数据挂载目录 2.创建配置挂载目录 3.创建插件挂载目录 4.权限授权 三.编辑配置 1.打开con…...
大厂面试真题-说说redis的雪崩、击穿和穿透
缓存雪崩、击穿、穿透是缓存系统中常见的三种问题,它们都会对系统的性能和稳定性造成严重影响。以下是对这三种问题的详细解释以及相应的解决方案: 一、缓存雪崩 问题解释: 缓存雪崩指的是因为某些原因导致缓存中大量的数据同时失效或过期…...
【Spring】获取Cookie和Session(@CookieValue()和@SessionAttribute())
获取 Cookie 传统获取 Cookie 这是没有 Spring 的时候,用 Servlet 来获取(获取所有的 Cookie) Spring MVC 是基于 Servlet API 构建的原始 Web 框架,也是在 Servlet 的基础上实现的 RequestMapping("/getcookie") …...
【C++打怪之路Lv8】-- string类
🌈 个人主页:白子寰 🔥 分类专栏:重生之我在学Linux,C打怪之路,python从入门到精通,数据结构,C语言,C语言题集👈 希望得到您的订阅和支持~ 💡 坚持…...
【JS】node.js压缩文件的方式
在 Node.js 中,有多种方法可以压缩文件。以下是几种常见的压缩方式及其对应的代码示例: 使用 archiver 压缩成 ZIP 文件使用 zlib 压缩成 GZIP 文件使用 tar 压缩成 TAR 文件 1. 使用 archiver 压缩成 ZIP 文件 archiver 是一个功能强大的库ÿ…...
2024免费mac苹果电脑清理垃圾软件CleanMyMac X4.15.8
对于苹果电脑用户来说,设备上积累的垃圾文件可能会导致存储空间变得紧张,影响电脑的性能和使用体验。尤其是那些经常下载和安装新应用、编辑视频或处理大量照片的用户,更容易感受到存储空间的压力。面对这种情况,寻找一种有效的苹…...
MPA-SVM多变量回归预测|海洋捕食者优化算法-支持向量机|Matalb
目录 一、程序及算法内容介绍: 基本内容: 亮点与优势: 二、实际运行效果: 三、算法介绍: 四、完整程序下载: 一、程序及算法内容介绍: 基本内容: 本代码基于Matlab平台编译&am…...
【uni-app】HBuilderX安装uni-ui组件
目录 1、官网找到入口 2、登录帐号 3、打开HuilderX 4、选择要应用的项目 5、查看是否安装完成 6、按需安装 7、安装完毕要重启 8、应用 前言:uniapp项目使用uni-ui组件方式很多,有npm安装等,或直接创建uni-ui项目,使用un…...
ROS2 通信三大件之动作 -- Action
通信最后一个,也是不太容易理解的方式action,复杂且重要 1、创建action数据结构 创建工作空间和模块就不多说了 在模块 src/action_moudle/action/Counter.action 下创建文件 Counter.action int32 target # Goal: 目标 --- int32 current_value…...
大数据治理:构建数据驱动的智能决策体系
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
k8s微服务
一 、什么是微服务 用控制器来完成集群的工作负载,那么应用如何暴漏出去?需要通过微服务暴漏出去后才能被访问 Service是一组提供相同服务的Pod对外开放的接口。 借助Service,应用可以实现服务发现和负载均衡。 service默认只支持4层负载均…...
【Java】Java 的反射机制(一):反射概述
Java 的反射机制(一):反射概述 1.反射概述1.1 静态语言 / 动态语言1.1.1 动态语言1.1.2 静态语言 1.2 Java Reflection1.3 Java 反射机制提供的功能1.4 反射的优点和缺陷1.5 反射相关的主要 API1.6 代码示例 2.Class 类2.1 什么是 Class 类2.…...
Monorepo pnpm 模式管理多个 web 项目
Monorepo pnpm 模式管理多个 web 项目 Monorepo pnpm 模式管理多个 web 项目项目地址git flow 工作流程pnpm workspace.npmrc初始化项目架构引入Husky规范git提交配置eslint和prettiereslint 配置prettier 配置 配置lint-staged创建项目创建shared项目全局安装 vue在 packages …...
2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,看是有点意料之外,其实也在情理之中。
近日,2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,这是历史上首次出现这样的情况。这项奖项原本只授予对自然现象和物质的物理学研究作出重大贡献的科学家,如今却将全球范围内对机器学习和神经网络的研究和开发作为了一种能…...
《深入理解 C++策略模式的变体:编程灵活性的新维度》
在 C编程的广阔领域中,设计模式起着至关重要的作用,它们为软件架构提供了可复用的解决方案。其中,策略模式是一种非常强大的设计模式,它允许算法的行为在运行时根据不同的策略进行改变。而策略模式的变体则进一步扩展了其灵活性和…...
一起体验AI动手实验,OceanBase 2024 年度发布会精彩预告
2024年OceanBase年度发布会将于10月23日在北京望京凯悦酒店举行。此次大会围绕“不止于记录”的主题,共同探讨当前数据库领域的前沿话题,包含主论坛、分论坛、AI 动手实训营、开源技术交流会等多个环节,诚邀全国各地的企业和开发者共同参与&a…...
Download Vmware Fusion (free for person)
1. web link ProductFiles - Support Portal - Broadcom support portal 2. Register user (Required) use your email to register a account 3. login and download note: the username is the email name....
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
