diff --git a/pom.xml b/pom.xml index bc881e88..c45f36ae 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.youlai youlai-boot - 2.18.1 + 2.19.0 基于 Java 17 + SpringBoot 3 + Spring Security 构建的权限管理系统。 diff --git a/src/main/java/com/youlai/boot/common/annotation/AnonymousAccess.java b/src/main/java/com/youlai/boot/common/annotation/AnonymousAccess.java deleted file mode 100644 index 8acb03be..00000000 --- a/src/main/java/com/youlai/boot/common/annotation/AnonymousAccess.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.youlai.boot.common.annotation; - -import java.lang.annotation.*; - -/// 标记匿名访问 -@Inherited -@Documented -@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -public @interface AnonymousAccess { -} diff --git a/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousDeleteMapping.java b/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousDeleteMapping.java deleted file mode 100644 index b83c764f..00000000 --- a/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousDeleteMapping.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.youlai.boot.common.annotation.methods; - -import com.youlai.boot.common.annotation.AnonymousAccess; -import org.springframework.core.annotation.AliasFor; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import java.lang.annotation.*; - -/** - * Annotation for mapping HTTP {@code DELETE} requests onto specific handler - * methods. - *

- * 支持匿名访问 DeleteMapping - * - * @see RequestMapping - */ -@AnonymousAccess -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@RequestMapping(method = RequestMethod.DELETE) -public @interface AnonymousDeleteMapping { - - /** - * Alias for {@link RequestMapping#name}. - */ - @AliasFor(annotation = RequestMapping.class) - String name() default ""; - - /** - * Alias for {@link RequestMapping#value}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] value() default {}; - - /** - * Alias for {@link RequestMapping#path}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] path() default {}; - - /** - * Alias for {@link RequestMapping#params}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] params() default {}; - - /** - * Alias for {@link RequestMapping#headers}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] headers() default {}; - - /** - * Alias for {@link RequestMapping#consumes}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] consumes() default {}; - - /** - * Alias for {@link RequestMapping#produces}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] produces() default {}; - -} diff --git a/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousGetMapping.java b/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousGetMapping.java deleted file mode 100644 index 923e2e70..00000000 --- a/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousGetMapping.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.youlai.boot.common.annotation.methods; - -import com.youlai.boot.common.annotation.AnonymousAccess; -import org.springframework.core.annotation.AliasFor; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import java.lang.annotation.*; - -/** - * Annotation for mapping HTTP {@code GET} requests onto specific handler - * methods. - *

- * 支持匿名访问 GetMapping - * - * @see RequestMapping - */ -@AnonymousAccess -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@RequestMapping(method = RequestMethod.GET) -public @interface AnonymousGetMapping { - - /** - * Alias for {@link RequestMapping#name}. - */ - @AliasFor(annotation = RequestMapping.class) - String name() default ""; - - /** - * Alias for {@link RequestMapping#value}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] value() default {}; - - /** - * Alias for {@link RequestMapping#path}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] path() default {}; - - /** - * Alias for {@link RequestMapping#params}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] params() default {}; - - /** - * Alias for {@link RequestMapping#headers}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] headers() default {}; - - /** - * Alias for {@link RequestMapping#consumes}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] consumes() default {}; - - /** - * Alias for {@link RequestMapping#produces}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] produces() default {}; - -} diff --git a/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousPatchMapping.java b/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousPatchMapping.java deleted file mode 100644 index 4795725c..00000000 --- a/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousPatchMapping.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.youlai.boot.common.annotation.methods; - -import com.youlai.boot.common.annotation.AnonymousAccess; -import org.springframework.core.annotation.AliasFor; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import java.lang.annotation.*; - -/** - * Annotation for mapping HTTP {@code PATCH} requests onto specific handler - * methods. - *

- * 支持匿名访问 PatchMapping - * - * @see RequestMapping - */ -@AnonymousAccess -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@RequestMapping(method = RequestMethod.PATCH) -public @interface AnonymousPatchMapping { - - /** - * Alias for {@link RequestMapping#name}. - */ - @AliasFor(annotation = RequestMapping.class) - String name() default ""; - - /** - * Alias for {@link RequestMapping#value}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] value() default {}; - - /** - * Alias for {@link RequestMapping#path}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] path() default {}; - - /** - * Alias for {@link RequestMapping#params}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] params() default {}; - - /** - * Alias for {@link RequestMapping#headers}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] headers() default {}; - - /** - * Alias for {@link RequestMapping#consumes}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] consumes() default {}; - - /** - * Alias for {@link RequestMapping#produces}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] produces() default {}; - -} diff --git a/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousPostMapping.java b/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousPostMapping.java deleted file mode 100644 index 810e2e38..00000000 --- a/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousPostMapping.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.youlai.boot.common.annotation.methods; - -import com.youlai.boot.common.annotation.AnonymousAccess; -import org.springframework.core.annotation.AliasFor; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import java.lang.annotation.*; - -/** - * Annotation for mapping HTTP {@code POST} requests onto specific handler - * methods. - *

- * 支持匿名访问 PostMapping - * - * @see RequestMapping - */ -@AnonymousAccess -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@RequestMapping(method = RequestMethod.POST) -public @interface AnonymousPostMapping { - - /** - * Alias for {@link RequestMapping#name}. - */ - @AliasFor(annotation = RequestMapping.class) - String name() default ""; - - /** - * Alias for {@link RequestMapping#value}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] value() default {}; - - /** - * Alias for {@link RequestMapping#path}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] path() default {}; - - /** - * Alias for {@link RequestMapping#params}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] params() default {}; - - /** - * Alias for {@link RequestMapping#headers}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] headers() default {}; - - /** - * Alias for {@link RequestMapping#consumes}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] consumes() default {}; - - /** - * Alias for {@link RequestMapping#produces}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] produces() default {}; - -} diff --git a/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousPutMapping.java b/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousPutMapping.java deleted file mode 100644 index 68df92f8..00000000 --- a/src/main/java/com/youlai/boot/common/annotation/methods/AnonymousPutMapping.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.youlai.boot.common.annotation.methods; - -import com.youlai.boot.common.annotation.AnonymousAccess; -import org.springframework.core.annotation.AliasFor; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -import java.lang.annotation.*; - -/** - * Annotation for mapping HTTP {@code PUT} requests onto specific handler - * methods. - *

- * 支持匿名访问 PutMapping - * - * @see RequestMapping - */ -@AnonymousAccess -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@RequestMapping(method = RequestMethod.PUT) -public @interface AnonymousPutMapping { - - /** - * Alias for {@link RequestMapping#name}. - */ - @AliasFor(annotation = RequestMapping.class) - String name() default ""; - - /** - * Alias for {@link RequestMapping#value}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] value() default {}; - - /** - * Alias for {@link RequestMapping#path}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] path() default {}; - - /** - * Alias for {@link RequestMapping#params}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] params() default {}; - - /** - * Alias for {@link RequestMapping#headers}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] headers() default {}; - - /** - * Alias for {@link RequestMapping#consumes}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] consumes() default {}; - - /** - * Alias for {@link RequestMapping#produces}. - */ - @AliasFor(annotation = RequestMapping.class) - String[] produces() default {}; - -} diff --git a/src/main/java/com/youlai/boot/common/util/AnonymousUtils.java b/src/main/java/com/youlai/boot/common/util/AnonymousUtils.java deleted file mode 100644 index 1ffe013c..00000000 --- a/src/main/java/com/youlai/boot/common/util/AnonymousUtils.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.youlai.boot.common.util; - -import com.youlai.boot.common.annotation.AnonymousAccess; -import com.youlai.boot.common.enums.RequestMethodEnum; -import org.springframework.context.ApplicationContext; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.method.HandlerMethod; -import org.springframework.web.servlet.mvc.method.RequestMappingInfo; -import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; - -import java.util.*; -import java.util.stream.Collectors; - -public class AnonymousUtils { - /** - * 获取所有匿名标记URL,不区分请求方式 - */ - public static Set getAnonymousUrls(ApplicationContext applicationContext) { - return getAllAnonymousUrls(applicationContext).values().stream().flatMap(Collection::stream).collect(Collectors.toSet()); - } - - /** - * 获取所有被标记的匿名类集合 - * - * @return / - */ - public static Map> getAllAnonymousUrls(ApplicationContext applicationContext) { - // 搜索匿名标记 - RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping"); - Map handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods(); - - // 获取所以被标记的匿名类集合 - return getAnonymousUrl(handlerMethodMap); - } - - /** - * 获取所有被标记的匿名类集合 - * - * @param handlerMethodMap 请求映射信息集合 - * @return / - */ - public static Map> getAnonymousUrl(Map handlerMethodMap) { - Set get = new HashSet<>(); - Set post = new HashSet<>(); - Set put = new HashSet<>(); - Set patch = new HashSet<>(); - Set delete = new HashSet<>(); - Set all = new HashSet<>(); - - handlerMethodMap.forEach((key, value) -> { - AnonymousAccess anonymousAccess = value.getMethodAnnotation(AnonymousAccess.class); - if (anonymousAccess != null) { - ArrayList requestMethods = new ArrayList<>(key.getMethodsCondition().getMethods()); - RequestMethodEnum request = RequestMethodEnum.find(requestMethods.isEmpty() ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name()); - switch (Objects.requireNonNull(request)) { - case GET: - get.addAll(key.getDirectPaths()); - break; - case POST: - post.addAll(key.getDirectPaths()); - break; - case PUT: - put.addAll(key.getDirectPaths()); - break; - case PATCH: - patch.addAll(key.getDirectPaths()); - break; - case DELETE: - delete.addAll(key.getDirectPaths()); - break; - default: - all.addAll(key.getDirectPaths()); - } - } - }); - - return Map.ofEntries( - entry(RequestMethodEnum.GET.getType(), get), - entry(RequestMethodEnum.POST.getType(), post), - entry(RequestMethodEnum.PUT.getType(), put), - entry(RequestMethodEnum.PATCH.getType(), patch), - entry(RequestMethodEnum.DELETE.getType(), delete), - entry(RequestMethodEnum.ALL.getType(), all) - ); - } - - public static Map.Entry> entry(String key, Collection collection) { - return Map.entry(key, collection.stream().filter(it -> !it.isEmpty()).collect(Collectors.toUnmodifiableSet())); - } - -} diff --git a/src/main/java/com/youlai/boot/config/SecurityConfig.java b/src/main/java/com/youlai/boot/config/SecurityConfig.java index 7b3c8a0d..6b32835e 100644 --- a/src/main/java/com/youlai/boot/config/SecurityConfig.java +++ b/src/main/java/com/youlai/boot/config/SecurityConfig.java @@ -2,9 +2,7 @@ package com.youlai.boot.config; import cn.binarywang.wx.miniapp.api.WxMaService; import cn.hutool.captcha.generator.CodeGenerator; -import cn.hutool.core.collection.CollectionUtil; -import com.youlai.boot.common.enums.RequestMethodEnum; -import com.youlai.boot.common.util.AnonymousUtils; +import cn.hutool.core.util.ArrayUtil; import com.youlai.boot.config.property.SecurityProperties; import com.youlai.boot.core.filter.RateLimiterFilter; import com.youlai.boot.core.security.exception.MyAccessDeniedHandler; @@ -17,11 +15,9 @@ import com.youlai.boot.shared.auth.service.impl.JwtTokenService; import com.youlai.boot.system.service.ConfigService; import com.youlai.boot.system.service.UserService; import lombok.RequiredArgsConstructor; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; @@ -36,9 +32,6 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import java.util.Map; -import java.util.Set; - /** * Spring Security 安全配置 * @@ -60,64 +53,61 @@ public class SecurityConfig { private final SysUserDetailsService userDetailsService; private final CodeGenerator codeGenerator; - private final SecurityProperties securityProperties; private final ConfigService configService; + private final SecurityProperties securityProperties; - private final MyAuthenticationEntryPoint authenticationEntryPoint; // 项目内安全类 - private final MyAccessDeniedHandler accessDeniedHandler; - - private final ApplicationContext applicationContext; - + /** + * 配置安全过滤链 SecurityFilterChain + */ @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - // 获取所有匿名访问路径 - Map> anonymousUrls = AnonymousUtils.getAllAnonymousUrls(applicationContext); - - http - - .authorizeHttpRequests(requestMatcherRegistry -> - requestMatcherRegistry - // GET - .requestMatchers(HttpMethod.GET, anonymousUrls.get(RequestMethodEnum.GET.getType()).toArray(new String[0])).permitAll() - // POST - .requestMatchers(HttpMethod.POST, anonymousUrls.get(RequestMethodEnum.POST.getType()).toArray(new String[0])).permitAll() - // PUT - .requestMatchers(HttpMethod.PUT, anonymousUrls.get(RequestMethodEnum.PUT.getType()).toArray(new String[0])).permitAll() - // PATCH - .requestMatchers(HttpMethod.PATCH, anonymousUrls.get(RequestMethodEnum.PATCH.getType()).toArray(new String[0])).permitAll() - // DELETE - .requestMatchers(HttpMethod.DELETE, anonymousUrls.get(RequestMethodEnum.DELETE.getType()).toArray(new String[0])).permitAll() - // 所有类型的接口都放行 - .requestMatchers(anonymousUrls.get(RequestMethodEnum.ALL.getType()).toArray(new String[0])).permitAll() - .anyRequest().authenticated() + return http + .authorizeHttpRequests(requestMatcherRegistry -> { + // 忽略认证的 URI 地址 + String[] ignoreUrls = securityProperties.getIgnoreUrls(); + if (ArrayUtil.isNotEmpty(ignoreUrls)) { + requestMatcherRegistry.requestMatchers(ignoreUrls).permitAll(); + } + // 其他请求都需要认证 + requestMatcherRegistry.anyRequest().authenticated(); + } ) - .exceptionHandling(httpSecurityExceptionHandlingConfigurer -> - httpSecurityExceptionHandlingConfigurer - .authenticationEntryPoint(authenticationEntryPoint) - .accessDeniedHandler(accessDeniedHandler) + .exceptionHandling(configurer -> + configurer + .authenticationEntryPoint(new MyAuthenticationEntryPoint()) // 未认证异常处理器 + .accessDeniedHandler(new MyAccessDeniedHandler()) // 无权限访问异常处理器 ) - .sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) - .csrf(AbstractHttpConfigurer::disable) + + // 禁用默认的 Spring Security 特性,适用于前后端分离架构 + .sessionManagement(configurer -> + configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 无状态认证,不使用 Session + ) + .csrf(AbstractHttpConfigurer::disable) // 禁用 CSRF 防护,前后端分离无需此防护机制 + .formLogin(AbstractHttpConfigurer::disable) // 禁用默认的表单登录功能,前后端分离采用 Token 认证方式 + .httpBasic(AbstractHttpConfigurer::disable) // 禁用 HTTP Basic 认证,避免弹窗式登录 + // 禁用 X-Frame-Options 响应头,允许页面被嵌套到 iframe 中 .headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) // 限流过滤器 .addFilterBefore(new RateLimiterFilter(redisTemplate, configService), UsernamePasswordAuthenticationFilter.class) // 验证码校验过滤器 .addFilterBefore(new CaptchaValidationFilter(redisTemplate, codeGenerator), UsernamePasswordAuthenticationFilter.class) // JWT 验证和解析过滤器 - .addFilterBefore(new JwtAuthenticationFilter(jwtTokenService), UsernamePasswordAuthenticationFilter.class); - - return http.build(); + .addFilterBefore(new JwtAuthenticationFilter(jwtTokenService), UsernamePasswordAuthenticationFilter.class) + .build(); } /** - * 不走过滤器链的放行配置 + * 配置Web安全自定义器,以忽略特定请求路径的安全性检查。 + *

+ * 该配置用于指定哪些请求路径不经过Spring Security过滤器链。通常用于静态资源文件。 */ @Bean public WebSecurityCustomizer webSecurityCustomizer() { return (web) -> { - if (CollectionUtil.isNotEmpty(securityProperties.getIgnoreUrls())) { - web.ignoring().requestMatchers(securityProperties.getIgnoreUrls().toArray(new String[0])); + String[] unsecuredUrls = securityProperties.getUnsecuredUrls(); + if (ArrayUtil.isNotEmpty(unsecuredUrls)) { + web.ignoring().requestMatchers(unsecuredUrls); } }; } @@ -130,7 +120,6 @@ public class SecurityConfig { DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); daoAuthenticationProvider.setPasswordEncoder(passwordEncoder); daoAuthenticationProvider.setUserDetailsService(userDetailsService); - daoAuthenticationProvider.setHideUserNotFoundExceptions(false); return daoAuthenticationProvider; } diff --git a/src/main/java/com/youlai/boot/config/property/SecurityProperties.java b/src/main/java/com/youlai/boot/config/property/SecurityProperties.java index ce8b3822..969098a5 100644 --- a/src/main/java/com/youlai/boot/config/property/SecurityProperties.java +++ b/src/main/java/com/youlai/boot/config/property/SecurityProperties.java @@ -28,7 +28,9 @@ public class SecurityProperties { /** * 白名单 URL 集合 */ - private List ignoreUrls; + private String[] ignoreUrls; + + private String[] unsecuredUrls; /** * 会话属性 diff --git a/src/main/java/com/youlai/boot/core/aspect/LogAspect.java b/src/main/java/com/youlai/boot/core/aspect/LogAspect.java index 4e89c810..bff5f107 100644 --- a/src/main/java/com/youlai/boot/core/aspect/LogAspect.java +++ b/src/main/java/com/youlai/boot/core/aspect/LogAspect.java @@ -8,7 +8,6 @@ import cn.hutool.http.useragent.UserAgentUtil; import cn.hutool.json.JSONUtil; import com.aliyun.oss.HttpMethod; import com.youlai.boot.common.enums.LogModuleEnum; -import com.youlai.boot.common.util.AnonymousUtils; import com.youlai.boot.common.util.IPUtils; import com.youlai.boot.core.security.util.SecurityUtils; import com.youlai.boot.system.model.entity.Log; @@ -22,7 +21,6 @@ import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; -import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; @@ -31,12 +29,11 @@ import org.springframework.web.servlet.HandlerMapping; import java.util.Collection; import java.util.Map; -import java.util.Set; /** * 日志切面 * - * @author Ray + * @author Ray.Hao * @since 2024/6/25 */ @Aspect @@ -46,7 +43,6 @@ import java.util.Set; public class LogAspect { private final LogService logService; private final HttpServletRequest request; - private final ApplicationContext applicationContext; @Pointcut("@annotation(com.youlai.boot.common.annotation.Log)") public void logPointcut() { @@ -80,16 +76,6 @@ public class LogAspect { private void saveLog(final JoinPoint joinPoint, final Exception e, Object jsonResult, com.youlai.boot.common.annotation.Log logAnnotation) { String requestURI = request.getRequestURI(); - Long userId = null; - - // 获取所有匿名标记 - Set anonymousUrls = AnonymousUtils.getAnonymousUrls(applicationContext); - - // 非登录请求获取用户ID,登录请求在登录成功后(joinPoint.proceed())获取用户ID - if (!anonymousUrls.contains(requestURI)) { - userId = SecurityUtils.getUserId(); - } - TimeInterval timer = DateUtil.timer(); // 执行方法 long executionTime = timer.interval(); @@ -113,12 +99,8 @@ public class LogAspect { log.setResponseContent(JSONUtil.toJsonStr(jsonResult)); } } - log.setRequestUri(requestURI); - // 登录方法需要在登录成功后获取用户ID - if (userId == null) { - userId = SecurityUtils.getUserId(); - } + Long userId = SecurityUtils.getUserId(); log.setCreateBy(userId); String ipAddr = IPUtils.getIpAddr(request); if (StrUtil.isNotBlank(ipAddr)) { diff --git a/src/main/java/com/youlai/boot/shared/auth/controller/AuthController.java b/src/main/java/com/youlai/boot/shared/auth/controller/AuthController.java index 23b532ec..a6758aea 100644 --- a/src/main/java/com/youlai/boot/shared/auth/controller/AuthController.java +++ b/src/main/java/com/youlai/boot/shared/auth/controller/AuthController.java @@ -1,6 +1,5 @@ package com.youlai.boot.shared.auth.controller; -import com.youlai.boot.common.annotation.methods.AnonymousPostMapping; import com.youlai.boot.common.enums.LogModuleEnum; import com.youlai.boot.common.result.Result; import com.youlai.boot.shared.auth.model.RefreshTokenRequest; @@ -31,7 +30,7 @@ public class AuthController { private final AuthService authService; @Operation(summary = "登录") - @AnonymousPostMapping("/login") + @PostMapping("/login") @Log(value = "登录", module = LogModuleEnum.LOGIN) public Result login( @Parameter(description = "用户名", example = "admin") @RequestParam String username, @@ -59,12 +58,12 @@ public class AuthController { @Operation(summary = "刷新token") @PostMapping("/refresh-token") public Result refreshToken(@RequestBody RefreshTokenRequest request) { - AuthTokenResponse authTokenResponse = authService.refreshToken(request); + AuthTokenResponse authTokenResponse = authService.refreshToken(request); return Result.success(authTokenResponse); } @Operation(summary = "微信登录") - @AnonymousPostMapping("/wechat-login") + @PostMapping("/wechat-login") @Log(value = "微信登录", module = LogModuleEnum.LOGIN) public Result wechatLogin( @Parameter(description = "微信授权码", example = "code") @RequestParam String code diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index cb6c707e..c5a8295f 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -62,7 +62,7 @@ mybatis-plus: # 主键ID类型 id-type: none # 逻辑删除全局属性名(驼峰和下划线都支持) - logic-delete-field: isDeleted + logic-delete-field: is_deleted # 逻辑删除-删除值 logic-delete-value: 1 # 逻辑删除-未删除值 @@ -85,17 +85,20 @@ security: access-token-time-to-live: 3600 # 刷新令牌有效期(单位:秒),默认 7 天 refresh-token-time-to-live: 604800 - # 白名单列表 + # 无需认证的请求路径 ignore-urls: - - /v3/api-docs/** - - /doc.html + - /api/v1/auth/login # 用户登录接口 + - /api/v1/auth/wechat-login # 微信登录接口 + - /api/v1/auth/captcha # 验证码获取接口 + - /api/v1/auth/refresh-token # 刷新令牌接口 + - /ws/** # WebSocket接口 + # 不走 Spring Security 过滤器链的请求路径(一般是静态资源) + unsecured-urls: - ${springdoc.swagger-ui.path} - - /swagger-resources/** + - /doc.html + - /v3/api-docs/** - /webjars/** - - /swagger-ui/** - - /api/v1/auth/captcha - - /api/v1/auth/refresh-token - - /ws/** + # 文件存储配置 oss: diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 78a48ba4..616b4324 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -84,17 +84,19 @@ security: access-token-time-to-live: 3600 # 刷新令牌有效期(单位:秒),默认 7 天 refresh-token-time-to-live: 604800 - # 白名单列表 + # 无需认证的请求路径 ignore-urls: - - /v3/api-docs/** - - /doc.html + - /api/v1/auth/login # 用户登录接口 + - /api/v1/auth/wechat-login # 微信登录接口 + - /api/v1/auth/captcha # 验证码获取接口 + - /api/v1/auth/refresh-token # 刷新令牌接口 + - /ws/** # WebSocket接口 + # 不走 Spring Security 过滤器链的请求路径(一般是静态资源) + unsecured-urls: - ${springdoc.swagger-ui.path} - - /swagger-resources/** + - /doc.html + - /v3/api-docs/** - /webjars/** - - /swagger-ui/** - - /api/v1/auth/captcha - - /api/v1/auth/refresh-token - - /ws/** # 文件存储配置 oss: