前言
在项目中安全框架是必不可少的,在微服务架构中更是尤为重要,我们项目中将安全模块单独抽离了一个公共模块出来,因为在我的项目架构中 需要用到的SpringSecurity 至少有三个地方 boss服务 admin服务 user服务(saas)模式的一个微服务架构
模块结构
主要分为 base服务(提供数据,可以部署多份进行负载均衡) boss模块 admin模块 gateway模块 以及公共模块其中就包含我们今天的主角 安全模块。
我们在TokenLoginFilter
中继承 AbstractAuthenticationProcessingFilter
抽象类 重写 attemptAuthentication方法 在里面分别指定验证器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@Override public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException { if (!httpServletRequest.getMethod().equals( "POST" )) { throw new AuthenticationServiceException( "Authentication method not supported: " + httpServletRequest.getMethod()); } User user = new ObjectMapper().readValue( httpServletRequest.getInputStream(), User. class ); //处理验证码 AbstractAuthenticationToken authRequest = null ; switch (user.getType()) { //租户登录 case "1" : authRequest = new TenantAuthenticationToken(user.getUsername(), user.getPassword()); break ; //平台登录 case "2" : authRequest = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()); break ; } setDetails(httpServletRequest, authRequest); return this .getAuthenticationManager().authenticate(authRequest); } |
其中TenantDetailsAuthenticationProvider
租户验证器(admin) 和UsernamePasswordAuthenticationProvider
平台验证器(boss)
这里当然还可以再加其他的验证器,比如后面如果还有app的话就可以在配置一个专门来做app端权限验证的验证器。
下面我们看看令牌的续期是怎么实现的: 令牌是由jwt生成 和 redis 配合使用,每一次亲求进来检查token是否合法的同时校验一下token的剩余时间是否大于一个阈值,如果小于阈值我们进行reids 中的令牌刷新时间让用户无感知续约。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/** * 验证令牌有效期,相差不足20分钟,自动刷新缓存 * @param loginUser * @return 令牌 */ public void verifyToken(OnlineUserInfo loginUser,Integer type) { long expireTime = loginUser.getExpireTime(); long currentTime = System.currentTimeMillis(); long chazhu= expireTime - currentTime; if (chazhu <= MILLIS_MINUTE_TEN) { refreshToken(loginUser,type); } } |
在访问过滤器中进行校验就可以了,这样就可以做到用户无感知令牌续约。
安全验证模块目前是再每个服务上面引入使用,后面会考虑在网关层做鉴权处理。
最后贴一下 WebSecurityConfigBugVip
这个配置类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
@Configuration @EnableWebSecurity public class WebSecurityConfigBugVip extends WebSecurityConfigurerAdapter { private TokenManager tokenManager; @Autowired private TenantDetailsAuthenticationProvider userDetailsAuthenticationProvider; @Autowired private UsernamePasswordAuthenticationProvider usernamePasswordAuthenticationProvider; @Autowired @Qualifier ( "authenticationManagerBean" ) private AuthenticationManager authenticationManager; /** * 装配自定义的Provider * @param auth */ @Override public void configure(AuthenticationManagerBuilder auth){ auth.authenticationProvider(userDetailsAuthenticationProvider); //将我们自定义的认证器配置进来 auth.authenticationProvider(usernamePasswordAuthenticationProvider); //默认的认证器 } @Autowired public WebSecurityConfigBugVip(TokenManager tokenManager, RedisTemplate redisTemplate) { this .tokenManager = tokenManager; this .redisTemplate = redisTemplate; } /** * 配置设置 * * @param http * @throws Exception */ @Override protected void configure(HttpSecurity http) throws Exception { http.exceptionHandling() .authenticationEntryPoint( new UnauthorizedEntryPoint()) .and().csrf().disable() .addFilterAt(tokenLoginFilter(), UsernamePasswordAuthenticationFilter. class ) .authorizeRequests() //配置需要放行的请求 .antMatchers( "/swagger-ui.html/**" , "/v2/**" , "/webjars/**" , "/swagger-resources/**" , "/boss/verifi/getCode" , "/boss/verifi/checkVrrifyCode" , "/boss/sysuser/write" , "/boss/sysuser/read" ).permitAll() .anyRequest().authenticated() .and().logout().logoutUrl( "/boss/acl/logout" ) .and().logout().logoutUrl( "/admin/acl/logout" ) .addLogoutHandler( new TokenLogoutHandler(tokenManager, redisTemplate)).and() .addFilter( new TokenAuthenticationFilter(authenticationManager(), tokenManager, redisTemplate)).httpBasic(); //设置访问过滤器 } /** *token过滤器 */ @Bean public TokenLoginFilter tokenLoginFilter() { TokenLoginFilter filter = new TokenLoginFilter(); filter.setAuthenticationManager(authenticationManager); return filter; } /** * 处理注入 AuthenticationManager失败问题 * @return * @throws Exception */ @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super .authenticationManagerBean(); } } |
以上就是SpringSecurity微服务实战之公共模块详解的详细内容,更多关于SpringSecurity微服务公共模块的资料请关注服务器之家其它相关文章!
原文链接:https://juejin.cn/post/7135603061614968869