ServerHttpSecurity authorizeExchange PermitAll 不工作

ServerHttpSecurity authorizeExchange PermitAll Not Working

我已经使用 spring 云 API 网关配置了 auth0 身份验证,我的基本设置如下,

因此将以下安全配置与 spring 启动应用程序一起使用,

package com.app.source.configuration.security;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfiguration {
    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
                .authorizeExchange()
                //ALLOW USER REGISTRATION API WITHOUT AUTHENTICATION
                .pathMatchers("/user/api/v1/user/registration").permitAll()
                //ALL OTHER APIS ARE AUTHENTICATED
                .anyExchange().authenticated()
                .and()
                .csrf().disable()
                .oauth2Login()
                .and()
                .oauth2ResourceServer()
                .jwt();
        return http.build();
    }
}

身份验证层已应用到必要的 API 端点并且它正在按我的需要工作,但是这个注册端点发送空的 200 响应,但它没有通过 API 网关。但是当使用身份验证 header 发送它时,同样的 API 工作。我附上了 API 网关的 DEBUG 日志。

API 需要一个身份验证令牌,它可以正常工作并在未经授权的请求上发送 401。

API 配置为打开,从 API 网关发送 200,而不经过,

相同的 API 在我附加身份验证令牌时效果很好,这是不可接受的行为。

Request with valid auth token

2022-05-14 02:26:29.918 DEBUG 9999 --- [ctor-http-nio-3] o.s.w.s.adapter.HttpWebHandlerAdapter    : [1f1cee98-10, L:/0:0:0:0:0:0:0:1:8082 - R:/0:0:0:0:0:0:0:1:61057] HTTP POST "/user/api/v1/user/registration"
2022-05-14 02:26:29.934 DEBUG 9999 --- [oundedElastic-3]
o.s.w.s.s.DefaultWebSessionManager       : Created new WebSession.
2022-05-14 02:26:32.497 DEBUG 9999 --- [ctor-http-nio-3] o.s.w.s.adapter.HttpWebHandlerAdapter    : [1f1cee98-10, L:/0:0:0:0:0:0:0:1:8082 - R:/0:0:0:0:0:0:0:1:61057] Completed 200 OK


-----------

Request without token which is returning 200 in the same second without processing it.

2022-05-14 02:26:45.950 DEBUG 9999 --- [ctor-http-nio-3] o.s.w.s.adapter.HttpWebHandlerAdapter    : [1f1cee98-11, L:/0:0:0:0:0:0:0:1:8082 - R:/0:0:0:0:0:0:0:1:61057] HTTP POST "/user/api/v1/user/registration"
2022-05-14 02:26:45.960 DEBUG 9999 --- [oundedElastic-3] o.s.w.s.s.DefaultWebSessionManager       : Created new WebSession.
2022-05-14 02:26:45.977 DEBUG 9999 --- [oundedElastic-3] o.s.w.s.adapter.HttpWebHandlerAdapter    : [1f1cee98-11, L:/0:0:0:0:0:0:0:1:8082 - R:/0:0:0:0:0:0:0:1:61057] Completed 200 OK

过滤器有问题

 @Bean
public GlobalFilter customGlobalFilter() {

    return ((exchange, chain) -> exchange.getPrincipal().map(principal -> {
        String userName = "";

        if (principal instanceof JwtAuthenticationToken) {
            //Get username from Principal
            userName = principal.getName();
        }
        // adds header to proxied request
        exchange.getRequest().mutate()
                .header("X-Auth-Id", userName)
                .build();
        return exchange;
    }).flatMap(chain::filter).then(Mono.fromRunnable(() -> {

    })));
}

如果你删除了就好了

最初的问题是编写用于捕获传入请求主体用户名的自定义过滤器,添加了 defaultIfEmpty 并允许未经授权的用户请求。

package com.app.configuration;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

import java.security.Principal;

@Slf4j
@Configuration
public class GatewayConfiguration {

    private static final String HTTP_HEADER_AUTH_USER_ID = "X-Auth-Id";
    private static final String UNAUTHORIZED_USER_NAME = "SYSTEM USER";

    @Bean
    public GlobalFilter customGlobalFilter() {
        return (exchange, chain) -> exchange.getPrincipal().map(Principal::getName).defaultIfEmpty(UNAUTHORIZED_USER_NAME).map(principal -> {
            // adds header to proxied request
            exchange.getRequest().mutate()
                    .header(HTTP_HEADER_AUTH_USER_ID, principal)
                    .build();
            return exchange;
        }).flatMap(chain::filter).then(Mono.fromRunnable(() -> {

        }));
    }

}