Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 模块化Spring安全性WebFilterChain_Java_Spring_Spring Security_Spring Webflux - Fatal编程技术网

Java 模块化Spring安全性WebFilterChain

Java 模块化Spring安全性WebFilterChain,java,spring,spring-security,spring-webflux,Java,Spring,Spring Security,Spring Webflux,我们的Spring安全配置文件正在变得越来越大,我们希望将其分解为更小的部分。现在我们有以下几点: public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { http.securityMatcher(ServerWebExchangeMatchers.pathMatchers("/api/**")) .authenticationManager(this.auth

我们的Spring安全配置文件正在变得越来越大,我们希望将其分解为更小的部分。现在我们有以下几点:

public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
    http.securityMatcher(ServerWebExchangeMatchers.pathMatchers("/api/**"))
            .authenticationManager(this.authenticationManager);

    http.authorizeExchange()
            .pathMatchers(HttpMethod.GET, "/api/serviceA/**")
            .hasAuthority("PROP_A");

    http.authorizeExchange()
            .pathMatchers(HttpMethod.GET, "/api/serviceB/**")
            .hasAuthority("PROP_B");

    http.authorizeExchange().pathMatchers(HttpMethod.POST, "/api/login", "/api/logout", "/api/forgotPassword", "/api/confirmForgotPassword").permitAll();

    http.csrf()
            .disable()
            .formLogin()
            .authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED))
            .requiresAuthenticationMatcher(
                    ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, "/api/login"))
            .authenticationFailureHandler(CustomSpringSecurity::onAuthenticationFailure)
            .authenticationSuccessHandler(CustomSpringSecurity::onAuthenticationSuccess)
            .and()
            .logout()
            .logoutUrl("/api/logout")
            .logoutSuccessHandler(new CustomLogoutSuccessHandler(HttpStatus.OK));

    final SecurityWebFilterChain build = http.build();

    build
            .getWebFilters()
            .collectList()
            .subscribe(
                    webFilters -> {
                        for (WebFilter filter : webFilters) {
                            if (filter instanceof AuthenticationWebFilter) {
                                AuthenticationWebFilter awf = (AuthenticationWebFilter) filter;
                                awf.setServerAuthenticationConverter(CustomSpringSecurity::convert);
                            }
                        }
                    });

    return build;
}
我们想使用
securityMatcher
来突破
/api/seviceA/**
/api/sevice/**
来拥有
SecurityWebFilterChain@Beans

然而,我们的问题是配置中存在的额外配置数量。我们希望最终结果如下所示

    public SecurityWebFilterChain securityWebFilterChainForServiceA(ServerHttpSecurity http) {
        http.securityMatcher(ServerWebExchangeMatchers.pathMatchers("/api/serviceA/**"));

        http.authorizeExchange()
                .pathMatchers(HttpMethod.GET, "/api/serviceA/**")
                .hasAuthority("PROP_A");
        return http.build();
    }
我们希望端点的所有其他配置都是隐式的


如何在Spring Security中实现这样的模块化?

您可以指定如下接口:

    public interface HttpSecurityConfig {
        Consumer<ServerHttpSecurity> configuration();
    }

很好,它可以工作,但是您必须删除http.securityMatcher(ServerWebExchangeMatchers.pathMatchers(“/api/serviceA/**”);因为每一份上只能有一份。
    @Component
    public class ServiceASecurityConfig implements HttpSecurityConfig {
        @Override
        public Consumer<ServerHttpSecurity> configuration() {
            return (http) -> {

                http.authorizeExchange()
                        .pathMatchers(HttpMethod.GET, "/api/serviceA/**")
                        .hasAuthority("PROP_A");
            };
        }
    }

    @Component
    public class ServiceBSecurityConfig implements HttpSecurityConfig {
        @Override
        public Consumer<ServerHttpSecurity> configuration() {
            return (http) -> {

                http.authorizeExchange()
                        .pathMatchers(HttpMethod.GET, "/api/serviceB/**")
                        .hasAuthority("PROP_B");
            };
        }
    }

public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http, final List<HttpSecurityConfig> httpConfigurations) {
    http.securityMatcher(ServerWebExchangeMatchers.pathMatchers("/api/**"))
            .authenticationManager(this.authenticationManager);

    // This line replaces the individual configurations in your original question
    httpConfigurations.forEach(config -> config.configuration().accept(http));

    http.authorizeExchange().pathMatchers(HttpMethod.POST, "/api/login", "/api/logout", "/api/forgotPassword", "/api/confirmForgotPassword").permitAll();

    http.csrf()
            .disable()
            .formLogin()
            .authenticationEntryPoint(new HttpStatusServerEntryPoint(HttpStatus.UNAUTHORIZED))
            .requiresAuthenticationMatcher(
                    ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, "/api/login"))
            .authenticationFailureHandler(CustomSpringSecurity::onAuthenticationFailure)
            .authenticationSuccessHandler(CustomSpringSecurity::onAuthenticationSuccess)
            .and()
            .logout()
            .logoutUrl("/api/logout")
            .logoutSuccessHandler(new CustomLogoutSuccessHandler(HttpStatus.OK));

    final SecurityWebFilterChain build = http.build();

    build
            .getWebFilters()
            .collectList()
            .subscribe(
                    webFilters -> {
                        for (WebFilter filter : webFilters) {
                            if (filter instanceof AuthenticationWebFilter) {
                                AuthenticationWebFilter awf = (AuthenticationWebFilter) filter;
                                awf.setServerAuthenticationConverter(CustomSpringSecurity::convert);
                            }
                        }
                    });

    return build;
}