0

我们有一个带有执行器端点的 Spring Boot 项目(2.3.0.RELEASE),我们正在使用 KeycloakWebSecurityConfigurerAdapter 将 keycloak 引入项目中,如何防止执行器端点受到 keycloak 过滤器链的保护。

我们希望通过基本身份验证保护“/actuator/**”端点。

目前我们有一个带有@Order(1) 的自定义WebSecurityConfigurerAdapter,我们将基本身份验证应用于“/actuator/**”,然后我们使用@Order(2) 对KeycloakWebSecurityConfigurerAdapter 进行了注释

因此注册了 2 个过滤器链,当我调用执行器端点时,第二个过滤器链因未授权 401 而失败

是否可以防止处理第二个过滤器链上的“/actuator/**”资源路径?

第一个执行器安全配置。

@Configuration
@Order(1)
public class ActuatorWebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final String username;
    private final String password;
    private final PasswordEncoder encoder;

    public ActuatorWebSecurityConfig(
            @Value("${spring.security.user.name}") String username,
            @Value("${spring.security.user.password}") String password,
            Optional<PasswordEncoder> encoder) {
        this.username = username;
        this.password = password;
        this.encoder = encoder.orElseGet(PasswordEncoderFactories::createDelegatingPasswordEncoder);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser(username)
                .password(encoder.encode(password))
                .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .antMatcher("/actuator/**")
                .authorizeRequests(authorize -> authorize.anyRequest().authenticated())
                .httpBasic(Customizer.withDefaults());
    }
}

第二个keycloak安全配置

@Order(2)
@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    private final String swaggerUrl;
    private final CorsFilter corsFilter;
    private final CustomSecurityConfig customSecurityConfig;

    @Autowired
    public SecurityConfig(
            @Value("${springdoc.swagger-ui.url:#{null}}") String swaggerUrl,
            CorsFilter corsFilter,
            CustomSecurityConfig customSecurityConfig) {
        this.swaggerUrl = swaggerUrl;
        this.corsFilter = corsFilter;
        this.customSecurityConfig = customSecurityConfig;
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        KeycloakAuthenticationProvider keycloakProvider = keycloakAuthenticationProvider();
        keycloakProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakProvider);
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new NullAuthenticatedSessionStrategy();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.csrf().disable()
            .requestMatcher(new NegatedRequestMatcher(new AntPathRequestMatcher("/actuator/**")));
            .headers().frameOptions().disable()
        .and()
           .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
           .antMatchers("/public/**", "/resources/**", "/resources/public/**").permitAll()
           .antMatchers(OPTIONS, "/**").permitAll();
        .authorizeRequests()
           .antMatchers("/**")
           .authenticated();
    }
}

我已经尝试过使用 keycloak 配置

.antMatchers("/actuator/**").permitAll();

http.requestMatcher(new NegatedRequestMatcher(new AntPathRequestMatcher("/actuator/**")));

但没有任何效果我收到未经授权的 401 执行器

注册的过滤器链:

2022-01-18 17:38:44,688 INFO org.springframework.security.web.DefaultSecurityFilterChain [main] Creating filter chain: Ant [pattern='/actuator/**'], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@25c6a9de, org.springframework.security.web.context.SecurityContextPersistenceFilter@56f3f9da, org.springframework.security.web.header.HeaderWriterFilter@33dcbdc2, org.springframework.security.web.csrf.CsrfFilter@522fdf0c, org.springframework.security.web.authentication.logout.LogoutFilter@365ad794, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@23df16cf, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@227cba85, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@b38dc7d, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@142422a4, org.springframework.security.web.session.SessionManagementFilter@2f0b7b6d, org.springframework.security.web.access.ExceptionTranslationFilter@74bca236, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@30587737]
2022-01-18 17:38:44,691 INFO org.springframework.security.web.DefaultSecurityFilterChain [main] Creating filter chain: NegatedRequestMatcher [requestMatcher=Ant [pattern='/actuator/**']], [com.betex.auth.filters.CorsFilter@20a9f5fb, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@10e28d97, org.springframework.security.web.context.SecurityContextPersistenceFilter@c6b08a5, org.springframework.security.web.header.HeaderWriterFilter@5f05cd7e, org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter@2a54c92e, org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter@55b62db8, org.springframework.security.web.authentication.logout.LogoutFilter@274f51ad, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@54980154, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@25874884, org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter@8cb7185, org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter@4dac40b, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@37d43b9b, org.springframework.security.web.session.SessionManagementFilter@11e8e183, org.springframework.security.web.access.ExceptionTranslationFilter@56f1db5f, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@78543f0d]
4

1 回答 1

1

扩展KeycloakWebSecurityConfigurerAdapter时,适配器注册一个 Bean 类型KeycloakAuthenticationProcessingFilter。这个过滤器注册在 Spring Security 中SecurityFilterChain,因为它是一个 Bean,所以它也是 Spring Boot 自动注册在原始链中的,因此即使 Spring Security 不应用它,它也会在后面应用到原始过滤器链中.

尝试禁止这个过滤器被 Spring Boot 注册,如下所示:

@Bean
public FilterRegistrationBean registration(KeycloakAuthenticationProcessingFilter filter) {
    FilterRegistrationBean registration = new FilterRegistrationBean(filter);
    registration.setEnabled(false);
    return registration;
}

此外,如果您使用的是 OAuth 2,您可以考虑使用spring-security-oauth2-resource-server和简化您的资源服务器的配置。看看文档。这样您就不需要扩展自定义适配器,只需依赖 Spring Security 的开箱即用配置。

于 2022-01-18T17:35:46.467 回答