diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 7cb652f9..f27b011e 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -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 diff --git a/docker/run.md b/docker/run.md index 04fb55e4..1ee1fe5e 100644 --- a/docker/run.md +++ b/docker/run.md @@ -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 ``` diff --git a/src/main/java/com/youlai/boot/common/result/ResultCode.java b/src/main/java/com/youlai/boot/common/result/ResultCode.java index 026927ef..4f046f6e 100644 --- a/src/main/java/com/youlai/boot/common/result/ResultCode.java +++ b/src/main/java/com/youlai/boot/common/result/ResultCode.java @@ -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", "用户验证码过期"), diff --git a/src/main/java/com/youlai/boot/core/security/exception/CaptchaValidationException.java b/src/main/java/com/youlai/boot/core/security/exception/CaptchaValidationException.java new file mode 100644 index 00000000..7b498a1a --- /dev/null +++ b/src/main/java/com/youlai/boot/core/security/exception/CaptchaValidationException.java @@ -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); + } +} \ No newline at end of file diff --git a/src/main/java/com/youlai/boot/core/security/exception/MyAuthenticationEntryPoint.java b/src/main/java/com/youlai/boot/core/security/exception/MyAuthenticationEntryPoint.java index a8768cdf..ff5f041e 100644 --- a/src/main/java/com/youlai/boot/core/security/exception/MyAuthenticationEntryPoint.java +++ b/src/main/java/com/youlai/boot/core/security/exception/MyAuthenticationEntryPoint.java @@ -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()); } } } + + + + diff --git a/src/main/java/com/youlai/boot/core/security/extension/sms/SmsAuthenticationProvider.java b/src/main/java/com/youlai/boot/core/security/extension/sms/SmsAuthenticationProvider.java index fc71fe37..bc048794 100644 --- a/src/main/java/com/youlai/boot/core/security/extension/sms/SmsAuthenticationProvider.java +++ b/src/main/java/com/youlai/boot/core/security/extension/sms/SmsAuthenticationProvider.java @@ -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); diff --git a/src/main/java/com/youlai/boot/system/controller/LogController.java b/src/main/java/com/youlai/boot/system/controller/LogController.java index df7890cd..606ef5db 100644 --- a/src/main/java/com/youlai/boot/system/controller/LogController.java +++ b/src/main/java/com/youlai/boot/system/controller/LogController.java @@ -21,7 +21,7 @@ import java.util.List; /** * 日志控制层 * - * @author Ray + * @author Ray.Hao * @since 2.10.0 */ @Tag(name = "13.日志接口") diff --git a/src/main/resources/templates/codegen/form.java.vm b/src/main/resources/templates/codegen/form.java.vm index e2c07377..f05ce6b8 100644 --- a/src/main/resources/templates/codegen/form.java.vm +++ b/src/main/resources/templates/codegen/form.java.vm @@ -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