如何使用 Spring Boot + Spring Security + KeyCloak 验证每个请求?

How to verify each request with Spring Boot + Spring Security + KeyCloak?

我正在使用 KeycloakWebSecurityConfigurerAdapter。每次我尝试访问我的 spring 启动应用程序时,它只会验证持有者令牌一次。一旦验证了令牌,我就可以在没有令牌的情况下访问(相同的)应用程序,甚至可以使用已从 keycloak 注销的用户的令牌访问(从管理控制台我注销用户会话并注销 Rest API KeyCloak)。

我想在每次向 spring 引导应用程序发出请求时验证令牌。

Keycloak Client Config

安全配置

@KeycloakConfiguration
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        KeycloakAuthenticationProvider keycloakAuthenticationProvider
                = keycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(
                new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }
    @Bean
    public FilterRegistrationBean keycloakAuthenticationProcessingFilterRegistrationBean(
            KeycloakAuthenticationProcessingFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean keycloakPreAuthActionsFilterRegistrationBean(
            KeycloakPreAuthActionsFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean keycloakAuthenticatedActionsFilterBean(
            KeycloakAuthenticatedActionsFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    public FilterRegistrationBean keycloakSecurityContextRequestFilterBean(
            KeycloakSecurityContextRequestFilter filter) {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setEnabled(false);
        return registrationBean;
    }

    @Bean
    @Override
    @ConditionalOnMissingBean(HttpSessionManager.class)
    protected HttpSessionManager httpSessionManager() {
        return new HttpSessionManager();
    }

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

   
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.csrf().disable().cors().and()
                .authorizeRequests()
                .antMatchers("/admin/*").hasAnyRole("Admin")
                .anyRequest().permitAll();
    }
}

应用程序属性:

keycloak.realm=xyz
keycloak.resource=abc
keycloak.auth-server-url=...
keycloak.ssl-required=none
keycloak.use-resource-role-mappings= false
keycloak.bearer-only=true

通过为 HttpSecurity 将会话创建策略设置为无状态解决了这个问题。

protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http
                .csrf().disable()
                .cors().and()
               .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                 .authorizeRequests()
                .antMatchers("/admin/*").hasAnyRole("Admin")
                .anyRequest().permitAll();
    }