This commit is contained in:
2023-06-13 09:41:20 +08:00
parent 95bae3f9b3
commit 42781d03c8
6 changed files with 29 additions and 19 deletions

View File

@ -1,6 +1,5 @@
package com.qiaoba.auth.filters; package com.qiaoba.auth.filters;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.api.auth.service.AuthConfigApiService; import com.qiaoba.api.auth.service.AuthConfigApiService;
import com.qiaoba.auth.constants.SecurityConstant; import com.qiaoba.auth.constants.SecurityConstant;
import com.qiaoba.auth.entity.dto.OnlineUserDto; import com.qiaoba.auth.entity.dto.OnlineUserDto;
@ -48,7 +47,7 @@ public class AuthenticationCoreFilter extends OncePerRequestFilter {
protected void doFilterInternal(HttpServletRequest request, protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, HttpServletResponse response,
FilterChain chain) throws ServletException, IOException { FilterChain chain) throws ServletException, IOException {
log.debug(StrUtil.format("Start run AuthenticationCoreFilter, Uri: {}", request.getRequestURI())); log.debug("Start run AuthenticationCoreFilter, Uri: {}", request.getRequestURI());
// 白名单 放行 // 白名单 放行
for (String uri : authConfigProperties.getWhitelist()) { for (String uri : authConfigProperties.getWhitelist()) {
if (UriUtil.match(uri, request.getRequestURI())) { if (UriUtil.match(uri, request.getRequestURI())) {

View File

@ -46,13 +46,15 @@ public class AuthConfigServiceImpl implements AuthConfigApiService {
@Override @Override
public Long getBlacklistExpireTime() { public Long getBlacklistExpireTime() {
return redisService.getObject(ConfigConstant.BLACKLIST_EXPIRE_TIME_KEY, Long.class); Object expireTime = redisService.get(ConfigConstant.BLACKLIST_EXPIRE_TIME_KEY);
return Objects.isNull(expireTime) ? ConfigConstant.DEFAULT_MAX_BLACKLIST_EXPIRE_TIME : Long.parseLong(expireTime.toString());
} }
@Override @Override
public Integer getAllowMaxErrorCount() { public Integer getAllowMaxErrorCount() {
Integer count = redisService.getObject(ConfigConstant.LOGIN_ERROR_MAX_COUNT_KEY, Integer.class); Object count = redisService.get(ConfigConstant.LOGIN_ERROR_MAX_COUNT_KEY);
return Objects.isNull(count) ? ConfigConstant.DEFAULT_LOGIN_ERROR_MAX_COUNT : count; return Objects.isNull(count) ? ConfigConstant.DEFAULT_LOGIN_ERROR_MAX_COUNT : Integer.parseInt(count.toString());
} }
@Override @Override

View File

@ -63,4 +63,9 @@ public class ConfigConstant {
* 默认最大允许错误次数 * 默认最大允许错误次数
*/ */
public static final Integer DEFAULT_LOGIN_ERROR_MAX_COUNT = 5; public static final Integer DEFAULT_LOGIN_ERROR_MAX_COUNT = 5;
/**
* 默认最大黑名单过期时间(单位分钟)
*/
public static final Long DEFAULT_MAX_BLACKLIST_EXPIRE_TIME = 30L;
} }

View File

@ -1,7 +1,6 @@
package com.qiaoba.common.redis.service.impl; package com.qiaoba.common.redis.service.impl;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.common.base.constants.BaseConstant; import com.qiaoba.common.base.constants.BaseConstant;
import com.qiaoba.common.base.constants.TenantConstant; import com.qiaoba.common.base.constants.TenantConstant;
import com.qiaoba.common.base.context.BaseContext; import com.qiaoba.common.base.context.BaseContext;
@ -258,7 +257,7 @@ public class RedisServiceImpl implements RedisService {
public String addTenantPrefix(String key) { public String addTenantPrefix(String key) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(TenantConstant.TENANT_KEY_PREFIX).append(BaseContext.getTenantId()).append(BaseConstant.COLON_JOIN_STR).append(key); sb.append(TenantConstant.TENANT_KEY_PREFIX).append(BaseContext.getTenantId()).append(BaseConstant.COLON_JOIN_STR).append(key);
log.debug(StrUtil.format("拼接后的RedisKey: {}", sb.toString())); log.debug("拼接后的RedisKey: {}", sb.toString());
return sb.toString(); return sb.toString();
} }
@ -266,7 +265,7 @@ public class RedisServiceImpl implements RedisService {
public String removeTenantPrefix(String key) { public String removeTenantPrefix(String key) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(TenantConstant.TENANT_KEY_PREFIX).append(BaseContext.getTenantId()).append(BaseConstant.COLON_JOIN_STR); sb.append(TenantConstant.TENANT_KEY_PREFIX).append(BaseContext.getTenantId()).append(BaseConstant.COLON_JOIN_STR);
log.debug(StrUtil.format("去除拼接后的RedisKey: {}", key.replace(sb.toString(), ""))); log.debug("去除拼接后的RedisKey: {}", key.replace(sb.toString(), ""));
return key.replace(sb.toString(), ""); return key.replace(sb.toString(), "");
} }
} }

View File

@ -3,7 +3,6 @@ package com.qiaoba.module.system.service.impl;
import cn.hutool.captcha.CaptchaUtil; import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha; import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.lang.UUID; import cn.hutool.core.lang.UUID;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgent;
@ -31,6 +30,7 @@ import javax.servlet.http.HttpServletRequest;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* 登录 服务层实现 * 登录 服务层实现
@ -120,20 +120,26 @@ public class SysLoginServiceImpl implements SysLoginService {
// 开启->继续 // 开启->继续
// 错误次数是否到达允许最大错误次数 // 错误次数是否到达允许最大错误次数
Integer maxAllowCount = authConfigApiService.getAllowMaxErrorCount(); Integer maxAllowCount = authConfigApiService.getAllowMaxErrorCount();
Integer ipErrorCount = redisService.getObject(SecurityConstant.LOGIN_ERROR_COUNT + ip, Integer.class); Integer ipErrorCount = getIpErrorCount(ip);
if (ipErrorCount >= maxAllowCount) { if (ipErrorCount >= maxAllowCount) {
// 是-> 进入黑名单库 && 返回"IP已被拉黑" // 是-> 进入黑名单库 && 返回"IP已被拉黑"
redisService.set(SecurityConstant.BLACKLIST_KEY + ip, username, authConfigApiService.getBlacklistExpireTime()); redisService.set(SecurityConstant.BLACKLIST_KEY + ip, username, 60 * authConfigApiService.getBlacklistExpireTime());
redisService.del(SecurityConstant.LOGIN_ERROR_COUNT + ip);
return SecurityConstant.HAS_BEEN_PULLED_BLACK; return SecurityConstant.HAS_BEEN_PULLED_BLACK;
} else { } else {
// 否-> 错误次数+1 && 返回"你还剩xx次错误机会" // 否-> 错误次数+1 && 返回"你还剩xx次错误机会"
ipErrorCount++; ipErrorCount++;
redisService.set(SecurityConstant.LOGIN_ERROR_COUNT + ip, ipErrorCount); redisService.set(SecurityConstant.LOGIN_ERROR_COUNT + ip, ipErrorCount, 600);
return StrUtil.format("密码错误, 还有[{}]次错误机会", ipErrorCount); return StrUtil.format("密码错误, 还有[{}]次错误机会", (maxAllowCount - ipErrorCount));
} }
} }
private Integer getIpErrorCount(String ip) {
Object ipErrorCount = redisService.get(SecurityConstant.LOGIN_ERROR_COUNT + ip);
return Objects.isNull(ipErrorCount) ? 0 : Integer.parseInt(ipErrorCount.toString());
}
private void validateUser(String username, SysUser user) { private void validateUser(String username, SysUser user) {
if (ObjectUtil.isNull(user)) { if (ObjectUtil.isNull(user)) {
throw new ServiceException(StrUtil.format("登录用户:{} 不存在", username)); throw new ServiceException(StrUtil.format("登录用户:{} 不存在", username));

View File

@ -1,7 +1,6 @@
package com.qiaoba.module.tenant.filters; package com.qiaoba.module.tenant.filters;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.qiaoba.common.base.code.TenantErrorCode; import com.qiaoba.common.base.code.TenantErrorCode;
import com.qiaoba.common.base.constants.TenantConstant; import com.qiaoba.common.base.constants.TenantConstant;
import com.qiaoba.common.base.context.BaseContext; import com.qiaoba.common.base.context.BaseContext;
@ -45,7 +44,7 @@ public class DynamicDataSourceFilter extends OncePerRequestFilter {
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
log.debug(StrUtil.format("Start run DynamicDataSourceFilter, Uri: {}", request.getRequestURI())); log.debug("Start run DynamicDataSourceFilter, Uri: {}", request.getRequestURI());
String tenantId = request.getHeader(TenantConstant.HEADER_KEY_TENANT); String tenantId = request.getHeader(TenantConstant.HEADER_KEY_TENANT);
// 主系统 or 登录入口获取租户列表 // 主系统 or 登录入口获取租户列表
if (TenantConstant.DEFAULT_TENANT_ID.equals(tenantId) || TenantConstant.LOGIN_TENANT_LIST_URI.equals(request.getRequestURI())) { if (TenantConstant.DEFAULT_TENANT_ID.equals(tenantId) || TenantConstant.LOGIN_TENANT_LIST_URI.equals(request.getRequestURI())) {
@ -68,7 +67,7 @@ public class DynamicDataSourceFilter extends OncePerRequestFilter {
} }
private void before(SysTenant sysTenant) { private void before(SysTenant sysTenant) {
log.debug(StrUtil.format("设置租户信息, 租户ID: {},租户模式: {}", sysTenant.getTenantId(), sysTenant.getMode())); log.debug("设置租户信息, 租户ID: {},租户模式: {}", sysTenant.getTenantId(), sysTenant.getMode());
BaseContext.setTenantId(sysTenant.getTenantId()); BaseContext.setTenantId(sysTenant.getTenantId());
BaseContext.setSchema(sysTenant.getMode().equals(SysTenant.SCHEMA_MODE)); BaseContext.setSchema(sysTenant.getMode().equals(SysTenant.SCHEMA_MODE));
// 数据源模式-设置第三方数据源 // 数据源模式-设置第三方数据源
@ -105,20 +104,20 @@ public class DynamicDataSourceFilter extends OncePerRequestFilter {
if (TenantStatusEnum.DISABLE.getStatus().equals(sysTenant.getStatus())) { if (TenantStatusEnum.DISABLE.getStatus().equals(sysTenant.getStatus())) {
// 封禁状态 // 封禁状态
log.debug(StrUtil.format("租户已封禁, 租户ID: {}", sysTenant.getTenantId())); log.debug("租户已封禁, 租户ID: {}", sysTenant.getTenantId());
ResponseUtil.errorAuth(response, TenantErrorCode.DISABLE.getCode(), TenantErrorCode.DISABLE.getMsg()); ResponseUtil.errorAuth(response, TenantErrorCode.DISABLE.getCode(), TenantErrorCode.DISABLE.getMsg());
return true; return true;
} }
if (TenantStatusEnum.EXPIRE.getStatus().equals(sysTenant.getStatus())) { if (TenantStatusEnum.EXPIRE.getStatus().equals(sysTenant.getStatus())) {
// 已过期 // 已过期
log.debug(StrUtil.format("租户已过期, 租户ID: {}", sysTenant.getTenantId())); log.debug("租户已过期, 租户ID: {}", sysTenant.getTenantId());
ResponseUtil.errorAuth(response, TenantErrorCode.EXPIRE.getCode(), TenantErrorCode.EXPIRE.getMsg()); ResponseUtil.errorAuth(response, TenantErrorCode.EXPIRE.getCode(), TenantErrorCode.EXPIRE.getMsg());
return true; return true;
} }
if (DateUtil.compare(sysTenant.getExpireTime(), new Date()) < 0) { if (DateUtil.compare(sysTenant.getExpireTime(), new Date()) < 0) {
// 已过期 // 已过期
log.debug(StrUtil.format("租户已过期, 租户ID: {}", sysTenant.getTenantId())); log.debug("租户已过期, 租户ID: {}", sysTenant.getTenantId());
ResponseUtil.errorAuth(response, TenantErrorCode.EXPIRE.getCode(), TenantErrorCode.EXPIRE.getMsg()); ResponseUtil.errorAuth(response, TenantErrorCode.EXPIRE.getCode(), TenantErrorCode.EXPIRE.getMsg());
// 更新租户状态为已过期 // 更新租户状态为已过期
dynamicDataSourceConfig.setDefaultSetting(); dynamicDataSourceConfig.setDefaultSetting();