Spring boot Security OAuth2监听用户登录成功或失败
1:登陆成功监听
@Component public class AuthenticationSuccessEventListener implements ApplicationListener<AuthenticationSuccessEvent> { @Autowired private RedisCacheUtil redisCacheUtil; @Override public void onApplicationEvent(AuthenticationSuccessEvent authenticationSuccessEvent) { /** 获取请求参数 */ HttpServletRequest request = WebUtil.getRequest(); /** 从请求头获取租户ID */ String headerTenant = request.getHeader(TokenUtil.TENANT_HEADER_KEY); /** 从参数获取租户ID */ String paramTenant = request.getParameter(TokenUtil.TENANT_PARAM_KEY); /** 业务检验逻辑,这个按照自己的业务进行处理 start */ if (StringUtil.isAllBlank(headerTenant, paramTenant)) { throw new UserDeniedAuthorizationException(TokenUtil.TENANT_NOT_FOUND); } /** 业务检验逻辑,这个按照自己的业务进行处理 end */ String tenantId = StringUtils.isBlank(headerTenant) ? paramTenant : headerTenant; /** 获取用户信息-账号/密码 */ Object principal = authenticationSuccessEvent.getAuthentication().getPrincipal(); if(principal instanceof UserDetails){ UserDetails bladeUserDetails = (UserDetails) authenticationSuccessEvent.getAuthentication().getPrincipal(); String account = bladeUserDetails.getUsername(); /** rendis的key */ String accountNumKey= LoginUtil.getAccountNumKey(tenantId, account); /** 登陆成功之后删除redis里面登陆失败的记录 */ redisCacheUtil.del(accountNumKey); } }
2:登陆失败监听方法一(实现接口)
@Component public class AuthenticationFailureListener implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> { @Autowired private LoginConfineConfig loginConfineConfig; @Autowired private RedisCacheUtil redisCacheUtil; @Override public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent authenticationFailureBadCredentialsEvent) { /** 获取请求参数 */ HttpServletRequest request = WebUtil.getRequest(); /** 从请求头获取租户ID */ String headerTenant = request.getHeader(TokenUtil.TENANT_HEADER_KEY); /** 从参数获取租户ID */ String paramTenant = request.getParameter(TokenUtil.TENANT_PARAM_KEY); /** 业务检验逻辑,这个按照自己的业务进行处理 start */ if (StringUtil.isAllBlank(headerTenant, paramTenant)) { throw new UserDeniedAuthorizationException(TokenUtil.TENANT_NOT_FOUND); } /** 业务检验逻辑,这个按照自己的业务进行处理 end */ String tenantId = StringUtils.isBlank(headerTenant) ? paramTenant : headerTenant; /** 获取登陆账号 */ String account = authenticationFailureBadCredentialsEvent.getAuthentication().getPrincipal().toString(); /** 记录错误次数key */ String accountNumKey = LoginUtil.getAccountNumKey(tenantId, account); /** 获取配置的过期时间 */ long accountVerdueTime = loginConfineConfig.getAccountVerdueTime(); /** 获取配置的错误登陆次数 */ long accountLoginNum = loginConfineConfig.getAccountLoginNum(); /** 从redis获取登陆失败信息 */ Object o = redisCacheUtil.get(accountNumKey); if(o==null){ /** set进redis-有过期时间 */ //redisCacheUtil.setNew(accountNumKey,1,accountVerdueTime); /** 永久 */ redisCacheUtil.setNew(accountNumKey,1); }else { /** 获取失败次数,该方法进行了增量,详情看后面的redis代码 */ long accountNum = redisCacheUtil.incr(accountNumKey); if(accountNum >= accountLoginNum){ throw new UserDeniedAuthorizationException(String.format(TokenUtil.USER_OVERDUE_LOGIN_NUM_PROHIBIT,accountLoginNum)); } } } }
3:登陆失败监听方法二(注解实现)
@Component public class AuthenticationFailureListener { @EventListener public void onFailure(AuthenticationFailureBadCredentialsEvent failure) { /** 这里的逻辑处理参考实现一 */ System.out.println("这里是通过注解实现登陆失败监听器"); } }
4.上面提到的reids
public boolean setNew(String key, Object value) { try { ValueOperations<String, String> operations = redisTemplate.opsForValue(); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); operations.set(key, value.toString()); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean setNew(String key, Object value, long time) { try { ValueOperations<String, String> operations = redisTemplate.opsForValue(); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); operations.set(key, value.toString(), time, TimeUnit.SECONDS); return true; } catch (Exception e) { e.printStackTrace(); return false; } } public long incr(String key) { ValueOperations<String, String> operations = redisTemplate.opsForValue(); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); return operations.increment(key); }