- SpringSecurity认证的逻辑规则
启动项目时,SpringBoot自动检索所有带@Configuration
的注解,所以就将我们的WebSecurityConfig
给加载了,这个config中,我们需要在configure(AuthenticationManagerBuilder auth)
方法中注册一个继承自UserDetailsService
的接口,这个接口中只有一个方法,那就是使用username
获取到数据库中用户信息并返回成UserDetail
实体。这个方法需要我们按照我们的不同业务场景重写
WebSecurityConfig
1 | java复制代码 |
MyUserDetailsService
1 | java复制代码 |
其实如果去掉上面的将自定义的JWT过滤器加入到过滤链中的话,这个认证过程已经完成了。使用下面的代码就可以调用起整个认证程序。
核心代码
1 | ini复制代码authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userDto.getUsername(), userDto.getPassword())); |
这一行就会将username和password放到认证程序中进行认证。
也就是需要我们自己也逻辑让他去触发这个代码的实现。就可以自动完成认证程序了。就会触发使用username获取到数据库用户信息,然后经过密码加密比对之后会将认证结果返回。
我们整合JWT其实也很简单,其实就是将JWT的登录部分的操作,使用过滤器封装,将该过滤器放到整个认证的过滤链中
- 自定义JWT过滤器的配置
SpringSecurity过滤器的配置无非以下几个条件
- 该过滤器过滤什么样的API请求(也就是说什么样的API请求会触发该过滤器执行)。配置被过滤的请求API
- 该过滤器做什么事
- 该过滤器执行成功以及执行失败的各种情况该怎么做
- 该过滤器执行的时机是什么样的,也就是在过滤链之前还是之后执行
先解决逻辑上以上三个问题的答案
- 我们需要拦截认证请求,肯定是形如
xxx/login/xxx
这种API接口的请求啦 - 这个过滤器会做什么事呢?
- 首先,我们需要进行用户名密码的基础验证,也就是合不合法
- 我们需要调用起
SpringSecurity
的默认认证程序 - 认证程序执行成功之后,我们需要按照用户的信息以JWT的规则生成一个JWTToken并将其放入response中返回回去
- 认证程序执行失败,也就是用户登录失败,我们也需要将返回信息封装起来返回给用户
- 执行成功,我们需要返回给用户JWTToken信息。执行失败,我们也要友好提示用户
- 如果排除其他的业务场景干扰,目前过滤链只有进行鉴权时候才使用。所以针对不同的业务场景,这个过滤器放的地方其实是不一样的。(之后我们的另一个JWTToken校验的过滤器应该需要在这个认证的过滤器之后(两个其实并不捕捉同样的APi所以不会依次执行。也不用太考虑这个问题))(我记得SpringCloud中的zuul网关的过滤器是可以自定义级别的。但是目前在SpringSecurity中尚未发现这种功能)
针对以上解答,下面用代码来做展示(ps:序号依次对应上面)
- 配置过滤器过滤地址
1 | java复制代码 /** |
- 配置过滤器职能
1 | java复制代码 @Override |
- 执行失败与成功,分别是2中的
unsuccessfulAuthentication
和successfulAuthentication
方法 - 配置过滤链执行的位置
1 | scss复制代码在WebSecurityConfig中的configure(HttpSecurity http)方法中 |
完成了以上的配置,前台就可以使用/login/user
来进行登录操作了。登录成功会返回一个JSON对象来供前端判断成功与否
全部代码奉上,随意写的注释有点多,不看的可以给删掉
- WebSecurityConfig
1 | java复制代码import org.springframework.beans.factory.annotation.Autowired; |
- JWTAuthenticationFilter
1 | java复制代码import com.alibaba.fastjson.JSONObject; |
- MyUserDetailsService
1 | java复制代码import com.huanong.avatarma.basic.dao.UsersRepository; |
- Users
1 | typescript复制代码@Data |
- Result
1 | kotlin复制代码import lombok.Data; |
- JwtUtil
1 | java复制代码/** |
- ResponseUtil、ResultUtil、repository等不做展示。需要的可以联系我,这个是基础性的东西
- 依赖
1 | xml复制代码<dependency> |
本文转载自: 掘金