From f669d1b9687f131496fc2ee73a27bc466c299fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=A2=E6=9C=AC=E4=BC=9F?= Date: Mon, 11 Apr 2022 13:40:11 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20Introducing=20new=20features.=20cl?= =?UTF-8?q?ose=20#3794=20=E3=80=90=E6=96=B0=E9=9C=80=E6=B1=82=E3=80=91?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E9=94=99=E8=AF=AF=E6=AC=A1=E6=95=B0=E9=99=90?= =?UTF-8?q?=E5=88=B6=EF=BC=8C=E8=BF=9E=E7=BB=AD=E7=99=BB=E5=BD=95=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E9=94=81=E5=AE=9A=E8=B4=A6=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...AuthenticationFailureLockEventHandler.java | 89 +++++++++++++++++++ ...AuthenticationFailureLogEventHandler.java} | 2 +- ...AuthenticationSuccessLockEventHandler.java | 64 +++++++++++++ ...AuthenticationSuccessLogEventHandler.java} | 6 +- .../common/core/constant/CacheConstants.java | 5 ++ .../AuthenticationFailureEventListener.java | 10 +-- .../AuthenticationSuccessEventListener.java | 8 +- .../admin/api/feign/RemoteUserService.java | 10 +++ .../admin/controller/SysUserController.java | 11 +++ .../pigx/admin/service/SysUserService.java | 7 ++ .../service/impl/SysUserServiceImpl.java | 14 +++ 11 files changed, 214 insertions(+), 12 deletions(-) create mode 100644 pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureLockEventHandler.java rename pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/{PigxAuthenticationFailureEventHandler.java => PigxAuthenticationFailureLogEventHandler.java} (96%) create mode 100644 pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessLockEventHandler.java rename pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/{PigxAuthenticationSuccessEventHandler.java => PigxAuthenticationSuccessLogEventHandler.java} (94%) diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureLockEventHandler.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureLockEventHandler.java new file mode 100644 index 000000000..c6336f901 --- /dev/null +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureLockEventHandler.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ + +package com.pig4cloud.pigx.auth.handler; + +import com.pig4cloud.pigx.admin.api.feign.RemoteUserService; +import com.pig4cloud.pigx.common.core.constant.CacheConstants; +import com.pig4cloud.pigx.common.core.constant.SecurityConstants; +import com.pig4cloud.pigx.common.core.util.KeyStrResolver; +import com.pig4cloud.pigx.common.data.resolver.ParamResolver; +import com.pig4cloud.pigx.common.security.handler.AuthenticationFailureHandler; +import lombok.AllArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.concurrent.TimeUnit; + +/** + * @author lengleng + * @date 2022-04-11 + * + * 登录操作次数锁定功能 + */ +@Slf4j +@Component +@AllArgsConstructor +public class PigxAuthenticationFailureLockEventHandler implements AuthenticationFailureHandler { + + private final RedisTemplate redisTemplate; + + private final KeyStrResolver tenantKeyStrResolver; + + private final RemoteUserService userService; + + /** + * 密码错误超过 5 此自动锁定 + *

+ * @param authenticationException 登录的authentication 对象 + * @param authentication 登录的authenticationException 对象 + * @param request 请求 + * @param response 响应 + */ + @Async + @Override + @SneakyThrows + public void handle(AuthenticationException authenticationException, Authentication authentication, + HttpServletRequest request, HttpServletResponse response) { + // 只处理账号密码错误异常 + if (!(authenticationException instanceof BadCredentialsException)) { + return; + } + + String username = authentication.getName(); + String key = String.format("%s:%s:%s", CacheConstants.LOGIN_ERROR_TIMES, tenantKeyStrResolver.key(), username); + Long deltaTimes = ParamResolver.getLong("LOGIN_ERROR_TIMES", 5L); + Long times = redisTemplate.opsForValue().increment(key); + + // 自动过期时间 + Long deltaTime = ParamResolver.getLong("DELTA_TIME", 1L); + redisTemplate.expire(key, deltaTime, TimeUnit.HOURS); + + if (deltaTimes <= times) { + userService.lockUser(username, SecurityConstants.FROM_IN); + } + } + +} diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureEventHandler.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureLogEventHandler.java similarity index 96% rename from pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureEventHandler.java rename to pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureLogEventHandler.java index a43b85fa4..f27f52915 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureEventHandler.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationFailureLogEventHandler.java @@ -44,7 +44,7 @@ import javax.servlet.http.HttpServletResponse; @Slf4j @Component @AllArgsConstructor -public class PigxAuthenticationFailureEventHandler implements AuthenticationFailureHandler { +public class PigxAuthenticationFailureLogEventHandler implements AuthenticationFailureHandler { private final RemoteLogService logService; diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessLockEventHandler.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessLockEventHandler.java new file mode 100644 index 000000000..df9f86743 --- /dev/null +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessLockEventHandler.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ + +package com.pig4cloud.pigx.auth.handler; + +import com.pig4cloud.pigx.common.core.constant.CacheConstants; +import com.pig4cloud.pigx.common.core.util.KeyStrResolver; +import com.pig4cloud.pigx.common.security.handler.AuthenticationSuccessHandler; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.Async; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author lengleng + * @date 2022-04-11 + * + * 登录操作次数锁定清楚功能 + */ +@Slf4j +@Component +@AllArgsConstructor +public class PigxAuthenticationSuccessLockEventHandler implements AuthenticationSuccessHandler { + + private final RedisTemplate redisTemplate; + + private final KeyStrResolver tenantKeyStrResolver; + + /** + * 处理登录成功方法 + *

+ * 获取到登录的authentication 对象 + * @param authentication 登录对象 + * @param request 请求 + * @param response 返回 + */ + @Async + @Override + public void handle(Authentication authentication, HttpServletRequest request, HttpServletResponse response) { + String username = authentication.getName(); + String key = String.format("%s:%s:%s", CacheConstants.LOGIN_ERROR_TIMES, tenantKeyStrResolver.key(), username); + redisTemplate.delete(key); + } + +} diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessEventHandler.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessLogEventHandler.java similarity index 94% rename from pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessEventHandler.java rename to pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessLogEventHandler.java index a59d44762..d4d804500 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessEventHandler.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessLogEventHandler.java @@ -36,12 +36,14 @@ import javax.servlet.http.HttpServletResponse; /** * @author lengleng - * @date 2018/10/8 + * @date 2022-04-11 + * + * 登录成功日志记录 */ @Slf4j @Component @AllArgsConstructor -public class PigxAuthenticationSuccessEventHandler implements AuthenticationSuccessHandler { +public class PigxAuthenticationSuccessLogEventHandler implements AuthenticationSuccessHandler { private final RemoteLogService logService; diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CacheConstants.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CacheConstants.java index a377086a6..50b2938ce 100644 --- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CacheConstants.java +++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/CacheConstants.java @@ -95,4 +95,9 @@ public interface CacheConstants { */ String CLIENT_FLAG = "client_config_flag"; + /** + * 登录错误次数 + */ + String LOGIN_ERROR_TIMES = "login_error_times"; + } diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationFailureEventListener.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationFailureEventListener.java index fe755e79d..79e11ea69 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationFailureEventListener.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationFailureEventListener.java @@ -29,6 +29,7 @@ import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.List; /** * @author lengleng @@ -37,7 +38,7 @@ import javax.servlet.http.HttpServletResponse; public class AuthenticationFailureEventListener implements ApplicationListener { @Autowired(required = false) - private AuthenticationFailureHandler failureHandler; + private List failureHandlerList; /** * Handle an application event. @@ -58,10 +59,9 @@ public class AuthenticationFailureEventListener implements ApplicationListener failureHandler.handle(authenticationException, authentication, request, response)); } } diff --git a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationSuccessEventListener.java b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationSuccessEventListener.java index 5ba683725..85962a21c 100644 --- a/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationSuccessEventListener.java +++ b/pigx-common/pigx-common-security/src/main/java/com/pig4cloud/pigx/common/security/listener/AuthenticationSuccessEventListener.java @@ -29,6 +29,7 @@ import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.util.List; /** * @author lengleng @@ -37,7 +38,7 @@ import javax.servlet.http.HttpServletResponse; public class AuthenticationSuccessEventListener implements ApplicationListener { @Autowired(required = false) - private AuthenticationSuccessHandler successHandler; + private List successHandlerList; /** * Handle an application event. @@ -46,13 +47,12 @@ public class AuthenticationSuccessEventListener implements ApplicationListener successHandler.handle(authentication, request, response)); } } diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteUserService.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteUserService.java index b7fc90263..b437fd05c 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteUserService.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/feign/RemoteUserService.java @@ -27,6 +27,7 @@ import com.pig4cloud.pigx.common.core.util.R; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestHeader; import java.util.List; @@ -64,4 +65,13 @@ public interface RemoteUserService { @GetMapping("/user/ancestor/{username}") R> ancestorUsers(@PathVariable("username") String username); + /** + * 锁定用户 + * @param username 用户名 + * @param from 调用标识 + * @return + */ + @PutMapping("/user/lock/{username}") + R lockUser(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM) String from); + } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java index e174f3acb..86049758c 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysUserController.java @@ -201,4 +201,15 @@ public class SysUserController { return userService.importUser(excelVOList, bindingResult); } + /** + * 锁定指定用户 + * @param username 用户名 + * @return R + */ + @Inner + @PutMapping("/lock/{username}") + public R lockUser(@PathVariable String username) { + return userService.lockUser(username); + } + } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java index ac38eba8d..8e9ae3add 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysUserService.java @@ -117,4 +117,11 @@ public interface SysUserService extends IService { */ R registerUser(UserDTO userDto); + /** + * 锁定用户 + * @param username + * @return + */ + R lockUser(String username); + } diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java index 804b10ce5..15c74dd5a 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysUserServiceImpl.java @@ -370,4 +370,18 @@ public class SysUserServiceImpl extends ServiceImpl impl return R.ok(saveUser(userDto)); } + /** + * 锁定用户 + * @param username 用户名 + * @return + */ + @Override + @CacheEvict(value = CacheConstants.USER_DETAILS, key = "#username") + public R lockUser(String username) { + SysUser sysUser = baseMapper.selectOne(Wrappers.lambdaQuery().eq(SysUser::getUsername, username)); + sysUser.setLockFlag(CommonConstants.STATUS_LOCK); + baseMapper.updateById(sysUser); + return R.ok(); + } + }