From f8249b1191aff726f65cd710cb2ea02176ef12eb Mon Sep 17 00:00:00 2001 From: fshenye <512914587@qq.com> Date: Fri, 21 Oct 2022 15:04:03 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=96=B0=E5=A2=9E=E8=B4=A6=E5=8F=B7?= =?UTF-8?q?=E9=94=81=E5=AE=9A=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...AuthenticationFailureLockEventHandler.java | 11 +++--- .../cloud/common/core/util/NumberUtil.java | 4 +++ .../config/UserAccountProperties.java | 35 +++++++++++++++++++ .../common/security/service/SictUser.java | 12 ++++++- .../service/SictUserDetailsServiceImpl.java | 19 ++++++++-- .../main/resources/META-INF/spring.factories | 1 + 6 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/config/UserAccountProperties.java diff --git a/cloud-auth/src/main/java/cn/sh/stc/sict/cloud/auth/handler/SictAuthenticationFailureLockEventHandler.java b/cloud-auth/src/main/java/cn/sh/stc/sict/cloud/auth/handler/SictAuthenticationFailureLockEventHandler.java index e6056d7..9d29714 100644 --- a/cloud-auth/src/main/java/cn/sh/stc/sict/cloud/auth/handler/SictAuthenticationFailureLockEventHandler.java +++ b/cloud-auth/src/main/java/cn/sh/stc/sict/cloud/auth/handler/SictAuthenticationFailureLockEventHandler.java @@ -2,8 +2,8 @@ package cn.sh.stc.sict.cloud.auth.handler; import cn.sh.stc.sict.cloud.common.core.constant.RedisCacheConstant; +import cn.sh.stc.sict.cloud.common.security.config.UserAccountProperties; import cn.sh.stc.sict.cloud.common.security.handler.AuthenticationFailureHandler; -import cn.sh.stc.sict.cloud.upms.feign.RemoteUserService; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -28,8 +28,7 @@ import java.util.concurrent.TimeUnit; public class SictAuthenticationFailureLockEventHandler implements AuthenticationFailureHandler { private final RedisTemplate redisTemplate; - - private final RemoteUserService remoteUserService; + private final UserAccountProperties userAccountProperties; /** * 密码错误超过 5 此自动锁定 @@ -45,16 +44,14 @@ public class SictAuthenticationFailureLockEventHandler implements Authentication public void handle(AuthenticationException authenticationException, Authentication authentication, HttpServletRequest request, HttpServletResponse response) { // 只处理账号密码错误异常 - if (!(authenticationException instanceof BadCredentialsException)) { + if (!(authenticationException instanceof BadCredentialsException) && userAccountProperties.getLimitFlag()) { return; } String username = authentication.getName(); String key = String.format("%s:%s", RedisCacheConstant.LOGIN_ERROR_TIMES, username); - Long deltaTimes = 5L; Long times = redisTemplate.opsForValue().increment(key); // 自动过期时间 - Long deltaTime = 30L; - redisTemplate.expire(key, deltaTime, TimeUnit.MINUTES); + redisTemplate.expire(key, userAccountProperties.getLimitTime(), TimeUnit.MINUTES); } } diff --git a/cloud-common/cloud-common-core/src/main/java/cn/sh/stc/sict/cloud/common/core/util/NumberUtil.java b/cloud-common/cloud-common-core/src/main/java/cn/sh/stc/sict/cloud/common/core/util/NumberUtil.java index 315ab0d..75bafab 100644 --- a/cloud-common/cloud-common-core/src/main/java/cn/sh/stc/sict/cloud/common/core/util/NumberUtil.java +++ b/cloud-common/cloud-common-core/src/main/java/cn/sh/stc/sict/cloud/common/core/util/NumberUtil.java @@ -1,6 +1,7 @@ package cn.sh.stc.sict.cloud.common.core.util; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import java.math.BigDecimal; import java.math.BigInteger; @@ -118,4 +119,7 @@ public class NumberUtil { } + public static Long getLongValue(String value) { + return StrUtil.isBlank(value) ? 0L : Long.parseLong(value); + } } diff --git a/cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/config/UserAccountProperties.java b/cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/config/UserAccountProperties.java new file mode 100644 index 0000000..4e96159 --- /dev/null +++ b/cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/config/UserAccountProperties.java @@ -0,0 +1,35 @@ +package cn.sh.stc.sict.cloud.common.security.config; + +import cn.hutool.core.util.ObjectUtil; +import cn.sh.stc.sict.cloud.common.core.util.NumberUtil; +import lombok.Data; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Component; + +/** + * 用户账号 配置属性 + */ +@Data +@Component +@RefreshScope +@ConditionalOnExpression("!'${user}'.isEmpty()") +@ConfigurationProperties(prefix = "user.account") +public class UserAccountProperties { + private Boolean limitFlag; + private Long limitCount; + private Long limitTime; + + public Boolean getLimitFlag() { + return !ObjectUtil.isNull(this.limitFlag) && this.limitFlag; + } + + public Long getLimitCount(){ + return NumberUtil.isNullOrZero(this.limitCount) ? 5L : this.limitCount; + } + + public Long getLimitTime() { + return NumberUtil.isNullOrZero(this.limitTime) ? 30L : this.limitTime; + } +} diff --git a/cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/service/SictUser.java b/cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/service/SictUser.java index c32436f..dc4a258 100644 --- a/cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/service/SictUser.java +++ b/cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/service/SictUser.java @@ -58,7 +58,17 @@ public class SictUser extends User { * @throws IllegalArgumentException if a null value was passed either as * a parameter or as an element in the GrantedAuthority collection */ - public SictUser(Long id, String phone, String openId, String appId, String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection authorities) { + public SictUser(Long id, + String phone, + String openId, + String appId, + String username, + String password, + boolean enabled, + boolean accountNonExpired, + boolean credentialsNonExpired, + boolean accountNonLocked, + Collection authorities) { super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities); this.id = id; this.phone = phone; diff --git a/cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/service/SictUserDetailsServiceImpl.java b/cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/service/SictUserDetailsServiceImpl.java index 0b5e823..0e72e0b 100644 --- a/cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/service/SictUserDetailsServiceImpl.java +++ b/cloud-common/cloud-common-security/src/main/java/cn/sh/stc/sict/cloud/common/security/service/SictUserDetailsServiceImpl.java @@ -5,7 +5,9 @@ import cn.hutool.core.util.StrUtil; import cn.sh.stc.sict.cloud.common.core.constant.Constant; import cn.sh.stc.sict.cloud.common.core.constant.RedisCacheConstant; import cn.sh.stc.sict.cloud.common.core.constant.SecurityConstants; +import cn.sh.stc.sict.cloud.common.core.util.NumberUtil; import cn.sh.stc.sict.cloud.common.core.util.R; +import cn.sh.stc.sict.cloud.common.security.config.UserAccountProperties; import cn.sh.stc.sict.cloud.common.security.util.AuthUtils; import cn.sh.stc.sict.cloud.upms.dto.UserInfo; import cn.sh.stc.sict.cloud.upms.feign.RemoteUserService; @@ -16,6 +18,7 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.HttpHeaders; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; @@ -26,6 +29,7 @@ import org.springframework.stereotype.Service; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import javax.security.auth.login.AccountLockedException; import javax.servlet.http.HttpServletRequest; import java.util.*; @@ -42,9 +46,12 @@ public class SictUserDetailsServiceImpl implements SictUserDetailsService { private static final String BASIC_ = "Basic "; private final RemoteUserService remoteUserService; private final CacheManager cacheManager; + private final RedisTemplate redisTemplate; + private final UserAccountProperties userAccountProperties; /** * 用户密码登录 + * . * * @param username 用户名 * @return @@ -54,6 +61,11 @@ public class SictUserDetailsServiceImpl implements SictUserDetailsService { @SneakyThrows public UserDetails loadUserByUsername(String username) { String key = username; + String lockedKey = String.format("%s:%s", RedisCacheConstant.LOGIN_ERROR_TIMES, username); + Long times = NumberUtil.getLongValue(redisTemplate.opsForValue().get(lockedKey)); + if (userAccountProperties.getLimitFlag() && times >= userAccountProperties.getLimitCount()) { + throw new AccountLockedException("账号被锁定"); + } Cache cache = cacheManager.getCache(RedisCacheConstant.USER_DETAILS); if (!StrUtil.containsAny(key, StringPool.COLON)) { key = key + StringPool.COLON + getAppId(); @@ -119,8 +131,11 @@ public class SictUserDetailsServiceImpl implements SictUserDetailsService { } String userName = user.getUserName() + StringPool.COLON + info.getAppId(); - return new SictUser(user.getId(), user.getPhone(), info.getOpenId(), info.getAppId(), userName, SecurityConstants.BCRYPT + user.getPasswd(), enabled, - true, true, !Constant.BYTE_YES.equals(user.getStatus()), authorities); + String password = SecurityConstants.BCRYPT + user.getPasswd(); + // 登录失败5次锁定半小时 + boolean nonLockd = !Constant.BYTE_YES.equals(user.getStatus()); + return new SictUser(user.getId(), user.getPhone(), info.getOpenId(), info.getAppId(), userName, password, enabled, + true, true, nonLockd, authorities); } private static String getAppId() { diff --git a/cloud-common/cloud-common-security/src/main/resources/META-INF/spring.factories b/cloud-common/cloud-common-security/src/main/resources/META-INF/spring.factories index ed3c740..12c5c48 100644 --- a/cloud-common/cloud-common-security/src/main/resources/META-INF/spring.factories +++ b/cloud-common/cloud-common-security/src/main/resources/META-INF/spring.factories @@ -1,6 +1,7 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.openfeign.SictHystrixFeignTargeterConfiguration,\ cn.sh.stc.sict.cloud.common.security.feign.SictFeignConfiguration,\ + cn.sh.stc.sict.cloud.common.security.config.UserAccountProperties,\ cn.sh.stc.sict.cloud.common.security.service.SictUserDetailsServiceImpl,\ cn.sh.stc.sict.cloud.common.security.component.SictWebResponseExceptionTranslator,\ cn.sh.stc.sict.cloud.common.security.component.ResourceAuthExceptionEntryPoint,\ -- 2.22.0