SpringSecurity微服务实战之公共模块详解
目录
- 前言
- 模块结构
前言
在项目中安全框架是必不可少的,在微服务架构中更是尤为重要,我们项目中将安全模块单独抽离了一个公共模块出来,因为在我的项目架构中 需要用到的SpringSecurity 至少有三个地方 boss服务 admin服务 user服务(saas)模式的一个微服务架构
模块结构
主要分为 base服务(提供数据,可以部署多份进行负载均衡) boss模块 admin模块 gateway模块 以及公共模块其中就包含我们今天的主角 安全模块。
我们在TokenLoginFilter
中继承 AbstractAuthenticationProcessingFilter
抽象类 重写 attemptAuthentication方法 在里面分别指定验证器
@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 中的令牌刷新时间让用户无感知续约。
/** * 验证令牌有效期,相差不足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
这个配置类
@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微服务公共模块的资料请关注我们其它相关文章!