This commit is contained in:
Ray.Hao
2025-03-03 15:41:03 +08:00
8 changed files with 52 additions and 22 deletions

View File

@@ -40,7 +40,7 @@ services:
image: minio/minio:latest
container_name: minio
restart: unless-stopped
command: server /data --console-address ":9090"
command: server /data --console-address ":9001"
ports:
- 9000:9000
- 9001:9001

View File

@@ -4,13 +4,13 @@
## 安装
```bash
docker-compose -f docker-compose.yml -p youlai-boot up -d
docker-compose -f ./docker-compose.yml -p youlai-boot up -d
```
- p youlai-boot 指定命名空间,避免与其他容器冲突,这里方便管理,统一管理和卸载
## 卸载
```bash
docker-compose -f docker-compose.yml -p youlai-boot down
docker-compose -f ./docker-compose.yml -p youlai-boot down
```

View File

@@ -67,7 +67,7 @@ public enum ResultCode implements IResultCode, Serializable {
REFRESH_TOKEN_INVALID("A0231", "刷新令牌无效或已过期"),
// 验证码错误
USER_VERIFICATION_CODE_ERROR("A0240", "用户验证码错误"),
USER_VERIFICATION_CODE_ERROR("A0240", "验证码错误"),
USER_VERIFICATION_CODE_ATTEMPT_LIMIT_EXCEEDED("A0241", "用户验证码尝试次数超限"),
USER_VERIFICATION_CODE_EXPIRED("A0242", "用户验证码过期"),

View File

@@ -0,0 +1,15 @@
package com.youlai.boot.core.security.exception;
import org.springframework.security.core.AuthenticationException;
/**
* 验证码校验异常
*
* @author Ray.Hao
* @since 2025/3/1
*/
public class CaptchaValidationException extends AuthenticationException {
public CaptchaValidationException(String msg) {
super(msg);
}
}

View File

@@ -2,36 +2,47 @@ package com.youlai.boot.core.security.exception;
import com.youlai.boot.common.result.ResultCode;
import com.youlai.boot.common.util.ResponseUtils;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import java.io.IOException;
/**
* 未认证异常处理器
* 统一处理 Spring Security 认证失败响应
*
* @author Ray.Hao
* @since 2.0.0
*/
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {
/**
* 认证失败处理入口方法
*
* @param request 触发异常的请求对象(可用于获取请求头、参数等)
* @param response 响应对象(用于写入错误信息)
* @param authException 认证异常对象(包含具体失败原因)
*/
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
int status = response.getStatus();
if (status == HttpServletResponse.SC_NOT_FOUND) {
// 资源不存在
ResponseUtils.writeErrMsg(response, ResultCode.USER_RESOURCE_NOT_FOUND);
if (authException instanceof BadCredentialsException) {
// 用户名或密码错误
ResponseUtils.writeErrMsg(response, ResultCode.USER_PASSWORD_ERROR);
} else if(authException instanceof InsufficientAuthenticationException){
// 请求头缺失Authorization、Token格式错误、Token过期、签名验证失败
ResponseUtils.writeErrMsg(response, ResultCode.ACCESS_TOKEN_INVALID);
} else {
if (authException instanceof BadCredentialsException) {
// 用户名或密码错误
ResponseUtils.writeErrMsg(response, ResultCode.USER_PASSWORD_ERROR, authException.getMessage());
} else {
// 登录异常
ResponseUtils.writeErrMsg(response, ResultCode.USER_LOGIN_EXCEPTION, authException.getMessage());
}
// 其他未明确处理的认证异常(如账户被锁定、账户禁用等)
ResponseUtils.writeErrMsg(response, ResultCode.USER_LOGIN_EXCEPTION, authException.getMessage());
}
}
}

View File

@@ -3,13 +3,13 @@ package com.youlai.boot.core.security.extension.sms;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.youlai.boot.common.constant.RedisConstants;
import com.youlai.boot.core.security.exception.CaptchaValidationException;
import com.youlai.boot.core.security.model.SysUserDetails;
import com.youlai.boot.system.model.dto.UserAuthInfo;
import com.youlai.boot.system.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
@@ -64,7 +64,7 @@ public class SmsAuthenticationProvider implements AuthenticationProvider {
String cachedVerifyCode = (String) redisTemplate.opsForValue().get(RedisConstants.SMS_LOGIN_CODE_PREFIX + mobile);
if (!StrUtil.equals(inputVerifyCode, cachedVerifyCode)) {
throw new BadCredentialsException("验证码错误");
throw new CaptchaValidationException("验证码错误");
} else {
// 验证成功后删除验证码
redisTemplate.delete(RedisConstants.SMS_LOGIN_CODE_PREFIX + mobile);

View File

@@ -21,7 +21,7 @@ import java.util.List;
/**
* 日志控制层
*
* @author Ray
* @author Ray.Hao
* @since 2.10.0
*/
@Tag(name = "13.日志接口")

View File

@@ -7,6 +7,7 @@ import lombok.Getter;
import lombok.Setter;
#if(${hasLocalDateTime})
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
#end
#if(${hasBigDecimal})
import java.math.BigDecimal;
@@ -46,6 +47,9 @@ public class ${entityName}Form implements Serializable {
#if($fieldConfig.maxLength)
@Size(max=$fieldConfig.maxLength, message="$fieldConfig.fieldComment长度不能超过${fieldConfig.maxLength}个字符")
#end
#if($fieldConfig.fieldType == 'LocalDateTime')
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
#end
private ${fieldConfig.fieldType} ${fieldConfig.fieldName};
#end