ludc
2023-03-24 0baeb5d2b147bf29add1e5373652ae70dd749b69
Source/BladeX/blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailsServiceImpl.java
@@ -18,7 +18,8 @@
import com.alibaba.nacos.common.utils.StringUtils;
import io.jsonwebtoken.Claims;
import lombok.*;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import me.zhyd.oauth.log.Log;
import org.springblade.auth.constant.AuthConstant;
import org.springblade.auth.utils.TokenUtil;
@@ -30,17 +31,16 @@
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.*;
import org.springblade.system.cache.ParamCache;
import org.springblade.system.entity.Strategy;
import org.springblade.system.entity.Tenant;
import org.springblade.system.feign.ISysClient;
import org.springblade.system.user.entity.User;
import org.springblade.system.user.entity.UserInfo;
import org.springblade.system.user.enums.UserEnum;
import org.springblade.system.user.feign.IUserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.GrantedAuthoritiesContainer;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@@ -50,11 +50,7 @@
import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
 * 用户信息
@@ -82,6 +78,7 @@
   private final JwtProperties jwtProperties;
   /**
    * 超级管理员信息
    */
@@ -91,10 +88,12 @@
   private String userName;
   @Value("${user-info.passwrod}")
   private String password;
   @Value("#{'${user-info.ip}'.split(',')}")
   private List<String> ips;
   @Value("${user-info.id}")
   private String id;
   @Value("${ip-whitelist.ip-enable}")
   private Boolean ipEnable;
   @Value("#{'${ip-whitelist.ip}'.split(',')}")
   private List<String> ips;
   @Override
   @SneakyThrows
@@ -119,24 +118,31 @@
      // 指定租户ID
      String tenantId = StringUtils.isBlank(headerTenant) ? paramTenant : headerTenant;
      Log.debug("当前登录用户的租户Id为:"+tenantId+"当前登录用户名为:"+username);
      Strategy strategy = sysClient.getByTenantIdAndName(tenantId, username).getData();
      // 判断登录是否锁定
      int count = getFailCount(tenantId, username);
      int failCount = Func.toInt(ParamCache.getValue(FAIL_COUNT_VALUE), FAIL_COUNT);
      int failCount = Func.toInt(ParamCache.getValue(FAIL_COUNT_VALUE), Func.toInt(strategy.getLockingNum()));
      if (count >= failCount) {
         throw new UserDeniedAuthorizationException(TokenUtil.USER_HAS_TOO_MANY_FAILS);
      }
      //超级管理员配置文件配置账号密码,实现登录, 默认租户id为000000
      if(tenantId.equals(this.tenantId)){
         if (!this.userName.equals(username) && !password.equalsIgnoreCase(this.password)) {
            setFailCount(tenantId, username, count);
            setFailCount(tenantId, username, count,strategy.getLockingTime());
            throw new UsernameNotFoundException(TokenUtil.USER_NOT_FOUND);
         }
         Log.debug(getIpAddress(request));
         //如果ip比对后get抛出异常No value present就直接抛异常结束登录
         try {
            ips.stream().filter(s -> s.equals(getIpAddress(request))).findFirst().get();
         } catch (Exception e){
            throw new UserDeniedAuthorizationException(TokenUtil.IP_NOT_FOND);
         if(ipEnable){
            Log.debug("当前访问IP:"+getIpAddress(request));
            try {
               ips.stream().filter(s -> s.equals(getIpAddress(request))).findFirst().get();
            } catch (Exception e){
               throw new UserDeniedAuthorizationException(TokenUtil.IP_NOT_FOND);
            }
         }
         ArrayList<GrantedAuthority> authorities = new ArrayList<>();
@@ -181,12 +187,13 @@
            User user = userInfo.getUser();
            // 用户不存在,但提示用户名与密码错误并锁定账号
            if (user == null || user.getId() == null) {
               setFailCount(tenantId, username, count);
               setFailCount(tenantId, username, count,strategy.getLockingTime());
               throw new UsernameNotFoundException(TokenUtil.USER_NOT_FOUND);
            }
            String hex = DigestUtil.hex(password);
            // 用户存在但密码错误,超过次数则锁定账号
            if (grantType != null && !grantType.equals(TokenUtil.REFRESH_TOKEN_KEY) && !user.getPassword().equals(DigestUtil.hex(password))) {
               setFailCount(tenantId, username, count);
            if (grantType != null && !grantType.equals(TokenUtil.REFRESH_TOKEN_KEY) && !user.getPassword().equals(hex)) {
               setFailCount(tenantId, username, count,strategy.getLockingTime());
               throw new UsernameNotFoundException(TokenUtil.USER_NOT_FOUND);
            }
            // 用户角色不存在
@@ -211,7 +218,7 @@
            BladeUserDetails bladeUserDetails = new BladeUserDetails(user.getId(),
               user.getTenantId(), StringPool.EMPTY, user.getName(), user.getRealName(), user.getDeptId(), user.getPostId(), user.getRoleId(), Func.join(userInfo.getRoles()), Func.toStr(user.getAvatar(), TokenUtil.DEFAULT_AVATAR),
               username, AuthConstant.ENCRYPT + user.getPassword(), userInfo.getDetail(), true, true, true, true,
               AuthorityUtils.commaSeparatedStringToAuthorityList(Func.join(result.getData().getRoles())));
               AuthorityUtils.commaSeparatedStringToAuthorityList(Func.join(result.getData().getRoles())),user.getStrategyUpdateStatus());
            return bladeUserDetails;
         } else {
            throw new UsernameNotFoundException(result.getMsg());
@@ -229,11 +236,7 @@
      String ip = request.getHeader("x-forwarded-for");
      if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
         // 多次反向代理后会有多个ip值,第一个ip才是真实ip
         if( ip.indexOf(",")!=-1 && !ip.split(",")[0].equals("127.0.0.1")){
            ip = ip.split(",")[0];
         }else {
            ip = ip.split(",")[1];
         }
         ip = ip.split(",")[0];
      }
      if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
         ip = request.getHeader("Proxy-Client-IP");
@@ -284,8 +287,8 @@
    * @param username 账号
    * @param count    次数
    */
   private void setFailCount(String tenantId, String username, int count) {
      bladeRedis.setEx(CacheNames.tenantKey(tenantId, CacheNames.USER_FAIL_KEY, username), count + 1, Duration.ofMinutes(30));
   private void setFailCount(String tenantId, String username, int count, Long expir) {
      bladeRedis.setEx(CacheNames.tenantKey(tenantId, CacheNames.USER_FAIL_KEY, username), count + 1, Duration.ofMinutes(expir));
   }
   /**