springboot3整合SpringSecurity实现登录校验与权限认证(万字超详细讲解)
目录
身份认证:
1、创建一个spring boot项目,并导入一些初始依赖:
2、由于我们加入了spring-boot-starter-security的依赖,所以security就会自动生效了。这时直接编写一个controller控制器,并编写一个接口进行测试:
3、自定义用户的登录认证:
4、使用(SecurityFilterChain)过滤器, 配置用户登录的接口可以暴露出来,被所有人都正常的访问(还应在暴露一个注册接口,但我这里就先不写了)
5、将项目运行起来(我同时还写了一个普通的test方法,类型是get,没有放行,用于测试能不能拦截到):
6、自定义一个登录页面:
7、退出接口
权限校验:
1、基于请求:
2、基于方法:
目前市面上常用的安全框架有:
Spring Security、Shiro,还有一个国人开发的框架目前也备受好评:SaToken
但是与spring boot项目融合度最高的还是Spring Security,所以目前我们讲解一下基于spring boot项目来整合spring security来实现常用的登录校验与权限认证;
Spring Security(安全框架)
1、介绍
Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。
如果项目中需要进行权限管理,具有多个角色和多种权限,我们可以使用Spring Security。
采用的是责任链的设计模式,是一堆过滤器链的组合,它有一条很长的过滤器链。
2、功能
Authentication (认证),就是用户登录
Authorization (授权),判断用户拥有什么权限,可以访问什么资源
安全防护,跨站脚本攻击,session攻击等
非常容易结合Springboot项目进行使用,本次就着重与实现认证和授权这两个功能
版本spring boot3.1.16、spring security6.x
身份认证:
1、创建一个spring boot项目,并导入一些初始依赖:
org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-starter-web com.alibaba fastjson 2.0.21 com.mysql mysql-connector-j runtime org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.springframework.security spring-security-test test
2、由于我们加入了 spring-boot-starter-security 的依赖,所以ecurity就会自动生效了。这时直接编写一个controller控制器,并编写一个接口进行测试:
可以看到我们在访问这个接口时出现了拦截,必须要我们进行登录之后才能访问;
那么接下来我们就来实现第一个功能:用户登录认证;
3、自定义用户的登录认证:
Spring Security 6.x 的认证实现流程如下:
- 用户提交登录请求
- Spring Security 将请求交给 UsernamePasswordAuthenticationFilter 过滤器处理。
- UsernamePasswordAuthenticationFilter 获取请求中的用户名和密码,并生成一个 AuthenticationToken 对象,将其交给 AuthenticationManager 进行认证。
- AuthenticationManager 通过 UserDetailsService 获取用户信息,然后使用 PasswordEncoder 对用户密码进行校验。
- 如果密码正确,AuthenticationManager 会生成一个认证通过的 Authentication 对象,并返回给 UsernamePasswordAuthenticationFilter 过滤器。如果密码不正确,则 AuthenticationManager 抛出一个 AuthenticationException 异常。
- UsernamePasswordAuthenticationFilter 将 Authentication 对象交给 SecurityContextHolder 进行管理,并调用 AuthenticationSuccessHandler 处理认证成功的情况。
- 如果认证失败,UsernamePasswordAuthenticationFilter 会调用 AuthenticationFailureHandler 处理认证失败的情况。
看起来有点复杂,其实写起来很简单的。spring security的底层就是一堆的过滤器来是实现的,而我们只需要编写一些重要的过滤器即可,其他的就用spring security默认的实现,只要不影响我们正常的登录功能即可。
(创建一个用户表用来进行登录实现,注意这个表中的用户名不能重复,我们将用户名作为每一个用户的唯一凭证,就如同人的手机号或者身份证号一样)表的结构非常简单,一些配置我这里就不在描述了(实体类、mapper、service、controller等)
认证的实现流程:
1、创建一个MyUserDetailsService类来实现SpringSecurity的UserDetailsService接口
(这里进行用户登录和授权的逻辑处理)
UserDetailsService:此接口中定义了登录服务方法,用来实现登录逻辑。方法的返回值是UserDetails,也是spring security框架定义中的一个接口,用来存储用户信息,我们可以自定义一个类用来实现这个接口,将来返回的时候就返回我们自定义的用户实体类。
实现UserDetailsService接口
@Component public class MyUserDetailsService implements UserDetailsService { /* * UserDetailsService:提供查询用户功能,如根据用户名查询用户,并返回UserDetails *UserDetails,SpringSecurity定义的类, 记录用户信息,如用户名、密码、权限等 * */ @Autowired private SysUserMapper sysUserMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //根据用户名从数据库中查询用户 SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper() .eq(username != null, SysUser::getUsername, username)); if (sysUser==null){ throw new UsernameNotFoundException("用户不存在"); } MySysUserDetails mySysUserDetails=new MySysUserDetails(sysUser); return mySysUserDetails; } }
(在原有数据库表的基础上)实现UserDetails接口:
@Data @AllArgsConstructor @NoArgsConstructor public class MySysUserDetails implements UserDetails { private Integer id; private String username; private String password; // 用户拥有的权限集合,我这里先设置为null,将来会再更改的 @Override public Collection