河南安阳吧,宁波seo优化外包公司,昌大建设集团,做网站所需要的公司细责及条款一.简介
Spring Security 是 Spring家族中的一个安全管理框架。相比与另外一个安全框架Shiro#xff0c;它提供了更丰富的功能#xff0c;社区资源也比Shiro丰富。
认证#xff1a;验证当前访问系统的是不是本系统的用户#xff0c;并且要确认具体是哪个用户 授权…一.简介
Spring Security 是 Spring家族中的一个安全管理框架。相比与另外一个安全框架Shiro它提供了更丰富的功能社区资源也比Shiro丰富。
认证验证当前访问系统的是不是本系统的用户并且要确认具体是哪个用户 授权经过认证后判断当前用户是否有权限进行某个操作
依赖 dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-security/artifactId /dependency 引入依赖后我们在尝试去访问之前的接口就会自动跳转到一个SpringSecurity的默认登陆页面默认用户名是user,密码会输出在控制台。
必须登陆之后才能对接口进行访问。 二.认证
1.登陆校验流程 2.SpringSecurity完整流程
SpringSecurity的原理其实就是一个过滤器链内部包含了提供各种功能的过滤器 UsernamePasswordAuthenticationFilter:负责处理我们在登陆页面填写了用户名密码后的登陆请求。入门案例的认证工作主要有它负责。 ExceptionTranslationFilter处理过滤器链中抛出的任何AccessDeniedException和AuthenticationException。 FilterSecurityInterceptor负责权限校验的过滤器。
3.认证流程详解 Authentication接口: 它的实现类表示当前访问系统的用户封装了用户相关信息。AuthenticationManager接口定义了认证Authentication的方法UserDetailsService接口加载用户特定数据的核心接口。里面定义了一个根据用户名查询用户信息的方法。UserDetails接口提供核心用户信息。通过UserDetailsService根据用户名获取处理的用户信息要封装成UserDetails对象返回。然后将这些信息封装到Authentication对象中。
思路分析
认证 校验 登录
①自定义登录接口
调用ProviderManager的方法进行认证 如果认证通过生成jwt
把用户信息存入redis中
②自定义UserDetailsService
在这个实现类中去查询数据库
校验
①定义Jwt认证过滤器
获取token
解析token获取其中的userid
从redis中获取用户信息
存入SecurityContextHolder
创建一个类实现UserDetailsService接口重写其中的方法。根据用户名从数据库中查询用户信息 Service public class UserDetailsServiceImpl implements UserDetailsService { Autowired private UserMapper userMapper; Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //根据用户名查询用户信息 LambdaQueryWrapperUser wrapper new LambdaQueryWrapper(); wrapper.eq(User::getUserName,username); User user userMapper.selectOne(wrapper); //如果查询不到数据就通过抛出异常来给出提示 if(Objects.isNull(user)){ throw new RuntimeException(用户名或密码错误); } //TODO 根据用户查询权限信息 添加到LoginUser中 //把对应的用户信息包括去权限信息封装成UserDetails对象返回 return new LoginUser(user); } 因为UserDetailsService方法的返回值是UserDetails类型所以需要定义一个类实现该接口把用户信息封装在其中。
Data
NoArgsConstructor
AllArgsConstructor
public class LoginUser implements UserDetails {private User user;Overridepublic Collection? extends GrantedAuthority getAuthorities() {return null;}Overridepublic String getPassword() {return user.getPassword();}Overridepublic String getUsername() {return user.getUserName();}Overridepublic boolean isAccountNonExpired() {return true;}Overridepublic boolean isAccountNonLocked() {return true;}Overridepublic boolean isCredentialsNonExpired() {return true;}Overridepublic boolean isEnabled() {return true;}
}注意如果要测试需要往用户表中写入用户数据并且如果你想让用户的密码是明文存储需要在密码前加{noop}。
三.密码加密存储
默认使用的PasswordEncoder要求数据库中的密码格式为{id}password 。它会根据id去判断密码的加密方式。但是我们一般不会采用这种方式。所以就需要替换PasswordEncoder。 我们一般使用SpringSecurity为我们提供的BCryptPasswordEncoder。 我们只需要使用把BCryptPasswordEncoder对象注入Spring容器中SpringSecurity就会使用该PasswordEncoder来进行密码校验。我们可以定义一个SpringSecurity的配置类SpringSecurity要求这个配置类要继承WebSecurityConfigurerAdapter。 Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { // 密码加密方式 //创建BCryptPasswordEncoder注入容器 Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } } 后面注入便可private final PasswordEncoder passwordEncoder;
passwordEncoder.encode() 进行加密 返回加密的字符串 .matches() 密码校验 登录密码明文和 数据库密文进行比较 5.登录接口 接下来我们需要自定义登陆接口然后让SpringSecurity对这个接口放行,让用户访问这个接口的时候不用登录也能访问。
在接口中我们通过AuthenticationManager的authenticate方法来进行用户认证,所以需要在SecurityConfig中配置把AuthenticationManager注入容器。
认证成功的话要生成一个jwt放入响应中返回。并且为了让用户下回请求时能通过jwt识别出具体的是哪个用户我们需要把用户信息存入redis可以把用户id作为key。 加密createJWT:三种id,加密的数据过期时间或者就传一个加密数据 token中存放的数据(json格式) 把对象转json格式字符串然后加密 解密parseJWT(jwt字符串).var claims.getSubject().var RestController
public class LoginController {Autowiredprivate LoginServcie loginServcie;PostMapping(/user/login)public ResponseResult login(RequestBody User user){return loginServcie.login(user);}
}