更改Spring Security逻辑,使不需要验证API密钥的请求直接放行

也解决了请求一个未明确为不需要验证的路径时会错误返回“需要API密钥”的信息的问题
This commit is contained in:
TheWhiteDog9487
2025-11-04 18:42:18 +08:00
parent 56b0488c36
commit f00bab3783
3 changed files with 31 additions and 39 deletions
@@ -4,13 +4,12 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
import xyz.thewhitedog9487.WebAPI.Controller.ResponseData; import xyz.thewhitedog9487.WebAPI.Controller.ResponseData;
import xyz.thewhitedog9487.WebAPI.Data.Entity.AccessLog; import xyz.thewhitedog9487.WebAPI.Data.Entity.AccessLog;
@@ -24,29 +23,11 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
@Slf4j @Slf4j
@Component @AllArgsConstructor
public class ApiKeyAuthenticationFilter extends OncePerRequestFilter { public class ApiKeyAuthenticationFilter extends OncePerRequestFilter {
@Autowired List<String> ApiKeyList; List<String> ApiKeyList;
@Autowired AccessLogRepository AccessLogRepository; AccessLogRepository AccessLogRepository;
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
var ServletPath = request.getServletPath();
var PermitPrefix = List.of(
"/ip/",
"/v3/api-docs",
"/swagger-ui/" );
var FullyMatchList = List.of(
"/",
"/swagger-ui.html" );
for (String Prefix : PermitPrefix) {
if ( ServletPath.startsWith(Prefix) ) {
return true; } }
for (String FullyMatch : FullyMatchList) {
if ( ServletPath.equals(FullyMatch) ) {
return true; } }
return false; }
@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 {
@@ -1,36 +1,51 @@
package xyz.thewhitedog9487.WebAPI.Configuration; package xyz.thewhitedog9487.WebAPI.Configuration;
import jakarta.servlet.FilterChain;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import xyz.thewhitedog9487.WebAPI.Configuration.Security.ApiKeyAuthenticationFilter; import xyz.thewhitedog9487.WebAPI.Configuration.Security.ApiKeyAuthenticationFilter;
import xyz.thewhitedog9487.WebAPI.Data.Repository.AccessLogRepository;
import java.util.List;
@Configuration @Configuration
class SpringSecurityConfiguration { class SpringSecurityConfiguration {
@Autowired ApiKeyAuthenticationFilter ApiKeyAuthenticationFilter;
@Autowired List<String> ApiKeyList;
@Autowired AccessLogRepository AccessLogRepository;
/** /**
* @see ApiKeyAuthenticationFilter#shouldNotFilter(HttpServletRequest) * @see ApiKeyAuthenticationFilter#doFilterInternal(HttpServletRequest, HttpServletResponse, FilterChain)
*/ */
@Order(1)
@Bean @Bean
SecurityFilterChain CustomSecurityFilterChain(HttpSecurity Security) throws Exception { SecurityFilterChain RequireAPIKey(HttpSecurity Security) throws Exception {
Security
.securityMatcher("/message/**", "/accesslog/**")
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(AuthorizationManagerRequestMatcherRegistry -> {
AuthorizationManagerRequestMatcherRegistry
.anyRequest()
.authenticated(); })
.addFilterBefore(new ApiKeyAuthenticationFilter(ApiKeyList, AccessLogRepository), UsernamePasswordAuthenticationFilter.class);
return Security.build(); }
@Order(2)
@Bean
SecurityFilterChain PermitAll(HttpSecurity Security) throws Exception {
Security Security
.csrf(AbstractHttpConfigurer::disable) .csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(AuthorizationManagerRequestMatcherRegistry -> { .authorizeHttpRequests(AuthorizationManagerRequestMatcherRegistry -> {
AuthorizationManagerRequestMatcherRegistry AuthorizationManagerRequestMatcherRegistry
.requestMatchers("/ip/**")
.permitAll()
.requestMatchers("/", "/v3/api-docs/**","swagger-ui/**", "/swagger-ui.html")
.permitAll()
.requestMatchers("/message/**", "/accesslog/**")
.authenticated()
.anyRequest() .anyRequest()
.denyAll(); }) .permitAll(); });
.addFilterBefore(ApiKeyAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return Security.build(); } return Security.build(); }
} }
@@ -49,10 +49,6 @@ class GlobalSharedBean {
System.exit(-1); } System.exit(-1); }
return null; } } return null; } }
@Bean
ApiKeyAuthenticationFilter ApiKeyAuthenticationFilter(){
return new ApiKeyAuthenticationFilter(); }
@Bean @Bean
Lock SQLiteWriteLock(){ Lock SQLiteWriteLock(){
return new ReentrantLock(); } return new ReentrantLock(); }