diff --git a/eladmin-common/src/main/java/me/zhengjie/config/SwaggerConfig.java b/eladmin-common/src/main/java/me/zhengjie/config/SwaggerConfig.java index 1edbcc49..b1a868c4 100644 --- a/eladmin-common/src/main/java/me/zhengjie/config/SwaggerConfig.java +++ b/eladmin-common/src/main/java/me/zhengjie/config/SwaggerConfig.java @@ -20,7 +20,10 @@ import com.fasterxml.classmate.TypeResolver; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import lombok.RequiredArgsConstructor; +import me.zhengjie.utils.AnonTagUtils; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -41,6 +44,9 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + import static springfox.documentation.schema.AlternateTypeRules.newRule; /** @@ -50,6 +56,7 @@ import static springfox.documentation.schema.AlternateTypeRules.newRule; */ @Configuration @EnableSwagger2 +@RequiredArgsConstructor public class SwaggerConfig { @Value("${jwt.header}") @@ -58,6 +65,11 @@ public class SwaggerConfig { @Value("${swagger.enabled}") private Boolean enabled; + @Value("${server.servlet.context-path:}") + private String apiPath; + + private final ApplicationContext applicationContext; + @Bean @SuppressWarnings("all") public Docket createRestApi() { @@ -98,10 +110,14 @@ public class SwaggerConfig { } private SecurityContext getContextByPath() { + Set urls = AnonTagUtils.getAllAnonymousUrl(applicationContext); + urls = urls.stream().filter(url -> !url.equals("/")).collect(Collectors.toSet()); + String regExp = "^(?!" + apiPath + String.join("|" + apiPath, urls) + ").*$"; return SecurityContext.builder() .securityReferences(defaultAuth()) - // 表示 /auth/code、/auth/login 接口不需要使用securitySchemes即不需要带token - .operationSelector(o->o.requestMappingPattern().matches("^(?!/auth/code|/auth/login).*$")) + .operationSelector(o->o.requestMappingPattern() + // 排除不需要认证的接口 + .matches(regExp)) .build(); } diff --git a/eladmin-common/src/main/java/me/zhengjie/utils/AnonTagUtils.java b/eladmin-common/src/main/java/me/zhengjie/utils/AnonTagUtils.java new file mode 100644 index 00000000..d57ebf28 --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/utils/AnonTagUtils.java @@ -0,0 +1,103 @@ +/* + * Copyright 2019-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package me.zhengjie.utils; + +import me.zhengjie.annotation.AnonymousAccess; +import me.zhengjie.utils.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.*; + +/** + * @author Zheng Jie + * @description 匿名标记工具 + * @date 2025-01-13 + **/ +public class AnonTagUtils { + + /** + * 获取匿名标记的URL + * @param applicationContext / + * @return / + */ + public static Map> getAnonymousUrl(ApplicationContext applicationContext){ + RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping"); + Map handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods(); + Map> anonymousUrls = new HashMap<>(8); + // 获取匿名标记 + Set get = new HashSet<>(); + Set post = new HashSet<>(); + Set put = new HashSet<>(); + Set patch = new HashSet<>(); + Set delete = new HashSet<>(); + Set all = new HashSet<>(); + for (Map.Entry infoEntry : handlerMethodMap.entrySet()) { + HandlerMethod handlerMethod = infoEntry.getValue(); + AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class); + if (null != anonymousAccess) { + List requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods()); + RequestMethodEnum request = RequestMethodEnum.find(requestMethods.isEmpty() ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name()); + if (infoEntry.getKey().getPatternsCondition()!=null) { + switch (Objects.requireNonNull(request)) { + case GET: + get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case POST: + post.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case PUT: + put.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case PATCH: + patch.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + case DELETE: + delete.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + default: + all.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); + break; + } + } + } + } + anonymousUrls.put(RequestMethodEnum.GET.getType(), get); + anonymousUrls.put(RequestMethodEnum.POST.getType(), post); + anonymousUrls.put(RequestMethodEnum.PUT.getType(), put); + anonymousUrls.put(RequestMethodEnum.PATCH.getType(), patch); + anonymousUrls.put(RequestMethodEnum.DELETE.getType(), delete); + anonymousUrls.put(RequestMethodEnum.ALL.getType(), all); + return anonymousUrls; + } + + /** + * 获取所有匿名标记的URL + * @param applicationContext / + * @return / + */ + public static Set getAllAnonymousUrl(ApplicationContext applicationContext){ + Set allUrl = new HashSet<>(); + Map> anonymousUrls = getAnonymousUrl(applicationContext); + for (String key : anonymousUrls.keySet()) { + allUrl.addAll(anonymousUrls.get(key)); + } + return allUrl; + } +} diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SpringSecurityConfig.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SpringSecurityConfig.java index ad886f31..0a776292 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SpringSecurityConfig.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SpringSecurityConfig.java @@ -16,11 +16,11 @@ package me.zhengjie.modules.security.config; import lombok.RequiredArgsConstructor; -import me.zhengjie.annotation.AnonymousAccess; import me.zhengjie.modules.security.config.bean.SecurityProperties; import me.zhengjie.modules.security.security.*; import me.zhengjie.modules.security.service.OnlineUserService; import me.zhengjie.modules.security.service.UserCacheManager; +import me.zhengjie.utils.AnonTagUtils; import me.zhengjie.utils.enums.RequestMethodEnum; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -35,11 +35,7 @@ import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.filter.CorsFilter; -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.*; /** @@ -74,11 +70,8 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception { - // 搜寻匿名标记 url: @AnonymousAccess - RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping"); - Map handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods(); // 获取匿名标记 - Map> anonymousUrls = getAnonymousUrl(handlerMethodMap); + Map> anonymousUrls = AnonTagUtils.getAnonymousUrl(applicationContext); httpSecurity // 禁用 CSRF .csrf().disable() @@ -140,49 +133,4 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { private TokenConfigurer securityConfigurerAdapter() { return new TokenConfigurer(tokenProvider, properties, onlineUserService, userCacheManager); } - - private Map> getAnonymousUrl(Map handlerMethodMap) { - Map> anonymousUrls = new HashMap<>(8); - Set get = new HashSet<>(); - Set post = new HashSet<>(); - Set put = new HashSet<>(); - Set patch = new HashSet<>(); - Set delete = new HashSet<>(); - Set all = new HashSet<>(); - for (Map.Entry infoEntry : handlerMethodMap.entrySet()) { - HandlerMethod handlerMethod = infoEntry.getValue(); - AnonymousAccess anonymousAccess = handlerMethod.getMethodAnnotation(AnonymousAccess.class); - if (null != anonymousAccess) { - List requestMethods = new ArrayList<>(infoEntry.getKey().getMethodsCondition().getMethods()); - RequestMethodEnum request = RequestMethodEnum.find(requestMethods.size() == 0 ? RequestMethodEnum.ALL.getType() : requestMethods.get(0).name()); - switch (Objects.requireNonNull(request)) { - case GET: - get.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); - break; - case POST: - post.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); - break; - case PUT: - put.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); - break; - case PATCH: - patch.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); - break; - case DELETE: - delete.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); - break; - default: - all.addAll(infoEntry.getKey().getPatternsCondition().getPatterns()); - break; - } - } - } - anonymousUrls.put(RequestMethodEnum.GET.getType(), get); - anonymousUrls.put(RequestMethodEnum.POST.getType(), post); - anonymousUrls.put(RequestMethodEnum.PUT.getType(), put); - anonymousUrls.put(RequestMethodEnum.PATCH.getType(), patch); - anonymousUrls.put(RequestMethodEnum.DELETE.getType(), delete); - anonymousUrls.put(RequestMethodEnum.ALL.getType(), all); - return anonymousUrls; - } }