在Sping Boot 云网关中忽略SecurityFilterChain

ep6jt1vc  于 2023-08-05  发布在  Spring
关注(0)|答案(1)|浏览(98)

我正在尝试为我的API网关(Sping Boot Cloud Gateway)设置安全性。在添加Spring Security 之前,请求工作正常,但在添加spring-boot-starter-security并设置SecurityFilterChain之后,每个GET请求都会得到401响应,每个POST请求都会得到403 -无法找到预期的CSRF令牌。我正在禁用CSRF并允许所有内容进行如下测试:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;

/**
 * Security configuration for the service.
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    SecurityFilterChain filterChain(final HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable())
            .httpBasic(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(authz ->
                authz
                    .anyRequest().permitAll()
                    );
        return http.build();
    }
}

字符串
这是我的POM,供参考:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.arkdia.condominium.apigateway</groupId>
    <artifactId>condominium-apigateway-2</artifactId>
    <version>1.0.0</version>
    <name>condominium-apigateway-2</name>
    <description>Apigateway for Condominium</description>
    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2022.0.3</spring-cloud.version>
        <log4j2.version>2.20.0</log4j2.version>
        <jjwt.version>0.11.5</jjwt.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


这是我的应用程序。yml:

server:
  port: 6081
eureka:
  instance:
    hostname: localhost
    port: 6761
  client:
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${eureka.instance.port}/eureka
logging:
  level:
    org.springframework.security: DEBUG
spring:
  application:
    name: condominium-api-gateway
  main:
    allow-bean-definition-overriding: true
  cloud:
    gateway:
      discovery:
        locator:
          lower-case-service-id: true
          enabled: true
      routes:
        -
          id: condominium-authentication
          uri: lb://condominium-authentication
          predicates:
            - Path=/api/condominium/authentication/login
            - Method=POST
          filters:
            - RemoveRequestHeader=Cookie
        -
          id: condominium-authentication
          uri: lb://condominium-authentication
          predicates:
            - Path=/api/condominium/authentication/version
            - Method=GET
          filters:
            - RemoveRequestHeader=Cookie


我还启用了org.springframework.security日志来查看发生了什么,但只是GET请求获得如下日志:

2023-07-06 13:45:42.882  [32;1mDEBUG [m  [35m26180 [m [nio-6081-exec-3]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/login', method=POST}
2023-07-06 13:45:42.883  [32;1mDEBUG [m  [35m26180 [m [nio-6081-exec-3]  [36mathPatternParserServerWebExchangeMatcher [m : Request 'GET /api/condominium/authentication/version' doesn't match 'POST /login'
2023-07-06 13:45:42.884  [32;1mDEBUG [m  [35m26180 [m [nio-6081-exec-3]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : No matches found
2023-07-06 13:45:42.884  [32;1mDEBUG [m  [35m26180 [m [nio-6081-exec-3]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/login', method=GET}
2023-07-06 13:45:42.885  [32;1mDEBUG [m  [35m26180 [m [nio-6081-exec-3]  [36mathPatternParserServerWebExchangeMatcher [m : Request 'GET /api/condominium/authentication/version' doesn't match 'GET /login'
2023-07-06 13:45:42.886  [32;1mDEBUG [m  [35m26180 [m [nio-6081-exec-3]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : No matches found
2023-07-06 13:45:42.886  [32;1mDEBUG [m  [35m26180 [m [nio-6081-exec-3]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/logout', method=GET}
2023-07-06 13:45:42.887  [32;1mDEBUG [m  [35m26180 [m [nio-6081-exec-3]  [36mathPatternParserServerWebExchangeMatcher [m : Request 'GET /api/condominium/authentication/version' doesn't match 'GET /logout'
2023-07-06 13:45:42.887  [32;1mDEBUG [m  [35m26180 [m [nio-6081-exec-3]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : No matches found
2023-07-06 13:45:42.888  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/logout', method=POST}
2023-07-06 13:45:42.889  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mathPatternParserServerWebExchangeMatcher [m : Request 'GET /api/condominium/authentication/version' doesn't match 'POST /logout'
2023-07-06 13:45:42.889  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : No matches found
2023-07-06 13:45:42.889  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : Trying to match using EndpointRequestMatcher includes=[health], excludes=[], includeLinks=false
2023-07-06 13:45:42.896  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : Trying to match using PathMatcherServerWebExchangeMatcher{pattern='/actuator/health/**', method=null}
2023-07-06 13:45:42.897  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mathPatternParserServerWebExchangeMatcher [m : Request 'GET /api/condominium/authentication/version' doesn't match 'null /actuator/health/**'
2023-07-06 13:45:42.898  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : No matches found
2023-07-06 13:45:42.898  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : No matches found
2023-07-06 13:45:42.898  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36ma.DelegatingReactiveAuthorizationManager [m : Checking authorization on '/api/condominium/authentication/version' using org.springframework.security.authorization.AuthenticatedReactiveAuthorizationManager@7ebda86b
2023-07-06 13:45:42.900  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mebSessionServerSecurityContextRepository [m : No SecurityContext found in WebSession: 'org.springframework.web.server.session.InMemoryWebSessionStore$InMemoryWebSession@24122132'
2023-07-06 13:45:42.901  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mo.s.s.w.s.a.AuthorizationWebFilter       [m : Authorization failed: Access Denied
2023-07-06 13:45:42.902  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mebSessionServerSecurityContextRepository [m : No SecurityContext found in WebSession: 'org.springframework.web.server.session.InMemoryWebSessionStore$InMemoryWebSession@24122132'
2023-07-06 13:45:42.902  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mDelegatingServerAuthenticationEntryPoint [m : Trying to match using MediaTypeRequestMatcher [matchingMediaTypes=[text/html], useEquals=false, ignoredMediaTypes=[*/*]]
2023-07-06 13:45:42.902  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36m.s.u.m.MediaTypeServerWebExchangeMatcher [m : httpRequestMediaTypes=[*/*]
2023-07-06 13:45:42.902  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36m.s.u.m.MediaTypeServerWebExchangeMatcher [m : Processing */*
2023-07-06 13:45:42.903  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36m.s.u.m.MediaTypeServerWebExchangeMatcher [m : Ignoring
2023-07-06 13:45:42.903  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36m.s.u.m.MediaTypeServerWebExchangeMatcher [m : Did not match any media types
2023-07-06 13:45:42.903  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mDelegatingServerAuthenticationEntryPoint [m : Trying to match using OrServerWebExchangeMatcher{matchers=[org.springframework.security.config.web.server.ServerHttpSecurity$HttpBasicSpec$$Lambda$1062/0x0000000801275d70@60534b79, AndServerWebExchangeMatcher{matchers=[NegatedServerWebExchangeMatcher{matcher=MediaTypeRequestMatcher [matchingMediaTypes=[text/html], useEquals=false, ignoredMediaTypes=[]]}, MediaTypeRequestMatcher [matchingMediaTypes=[application/atom+xml, application/x-www-form-urlencoded, application/json, application/octet-stream, application/xml, multipart/form-data, text/xml], useEquals=false, ignoredMediaTypes=[*/*]]]}]}
2023-07-06 13:45:42.903  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : Trying to match using org.springframework.security.config.web.server.ServerHttpSecurity$HttpBasicSpec$$Lambda$1062/0x0000000801275d70@60534b79
2023-07-06 13:45:42.903  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : Trying to match using AndServerWebExchangeMatcher{matchers=[NegatedServerWebExchangeMatcher{matcher=MediaTypeRequestMatcher [matchingMediaTypes=[text/html], useEquals=false, ignoredMediaTypes=[]]}, MediaTypeRequestMatcher [matchingMediaTypes=[application/atom+xml, application/x-www-form-urlencoded, application/json, application/octet-stream, application/xml, multipart/form-data, text/xml], useEquals=false, ignoredMediaTypes=[*/*]]]}
2023-07-06 13:45:42.903  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36m.s.s.w.s.u.m.AndServerWebExchangeMatcher [m : Trying to match using NegatedServerWebExchangeMatcher{matcher=MediaTypeRequestMatcher [matchingMediaTypes=[text/html], useEquals=false, ignoredMediaTypes=[]]}
2023-07-06 13:45:42.903  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36m.s.u.m.MediaTypeServerWebExchangeMatcher [m : httpRequestMediaTypes=[*/*]
2023-07-06 13:45:42.904  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36m.s.u.m.MediaTypeServerWebExchangeMatcher [m : Processing */*
2023-07-06 13:45:42.904  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36m.s.u.m.MediaTypeServerWebExchangeMatcher [m : text/html .isCompatibleWith */* = true
2023-07-06 13:45:42.904  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36m.w.s.u.m.NegatedServerWebExchangeMatcher [m : matches = false
2023-07-06 13:45:42.904  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36m.s.s.w.s.u.m.AndServerWebExchangeMatcher [m : Did not match
2023-07-06 13:45:42.904  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mo.s.s.w.s.u.m.OrServerWebExchangeMatcher [m : No matches found
2023-07-06 13:45:42.904  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mDelegatingServerAuthenticationEntryPoint [m : No match found. Using default entry point org.springframework.security.web.server.DelegatingServerAuthenticationEntryPoint@46e5207c
2023-07-06 13:45:42.904  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mDelegatingServerAuthenticationEntryPoint [m : Trying to match using org.springframework.security.config.web.server.ServerHttpSecurity$HttpBasicSpec$$Lambda$1062/0x0000000801275d70@60534b79
2023-07-06 13:45:42.905  [32;1mDEBUG [m  [35m26180 [m [     parallel-2]  [36mDelegatingServerAuthenticationEntryPoint [m : No match found. Using default entry point org.springframework.security.web.server.authentication.HttpBasicServerAuthenticationEntryPoint@5588263b


根据日志判断,我怀疑我的安全过滤器链被忽略了,但我找不到修复方法

iaqfqrcu

iaqfqrcu1#

如果你使用的是spring Boot 3,可以参考以下代码:

@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
public class SecurityConfig {

    private final UserDetailServiceImpl userDetailsService;

    private final BCryptPasswordEncoder encoder;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

       http.csrf(csrf -> csrf.disable())
            .authorizeRequests().
            requestMatchers("/category/add")
            .authenticated()
            .requestMatchers("/authenticate","/register").permitAll()
            .anyRequest()
            .authenticated()
            .and().exceptionHandling(ex -> ex.authenticationEntryPoint(point))
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
    http.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);
    return http.build();

    }

    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return new CustomAuthenticationManager();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(encoder);
        return authenticationProvider;
    }
}

字符串
CustomAuthenticationManager:

public class CustomAuthenticationManager implements AuthenticationManager {

    @Autowired
    private DaoAuthenticationProvider authenticationProvider;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        return authenticationProvider.authenticate(authentication);
    }
}

相关问题