Spring Boot Keycloak - 每个请求验证 3 次

Posted

技术标签:

【中文标题】Spring Boot Keycloak - 每个请求验证 3 次【英文标题】:Spring Boot Keycloak - authenticates three times per request 【发布时间】:2020-02-17 19:46:33 【问题描述】:

我们正在使用带有 Undertow 的 Spring Boot 2.1.8 并使用 Keycloak 进行身份验证。每个请求都需要身份验证,但 Servlet 在 Servlet 管道或过滤器的不同点调用 Keycloak 进行 3 次身份验证。

我在日志中通过 Postman 看到了 Basic Auth 和 Bearer 令牌的这种行为。

关于为什么会发生这种情况的任何想法?这会损害我们的性能。

KeyCloak 配置

@KeycloakConfiguration
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter 

    private static final String READ_WRITE = "WRITE_USER";
    private static final String READ = "READ_USER";

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

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

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        //super.configure(http);
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .sessionAuthenticationStrategy(sessionAuthenticationStrategy())
            .and()
            .addFilterBefore(keycloakPreAuthActionsFilter(), LogoutFilter.class)
            .addFilterBefore(keycloakAuthenticationProcessingFilter(), X509AuthenticationFilter.class)
            .authorizeRequests()
            //.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
            .antMatchers(HttpMethod.GET).hasAnyRole(READ, READ_WRITE)
            .antMatchers(HttpMethod.POST).hasRole(READ_WRITE)
            .antMatchers(HttpMethod.PATCH).hasRole(READ_WRITE)
            .antMatchers(HttpMethod.PUT).hasRole(READ_WRITE)
            .antMatchers(HttpMethod.DELETE).hasRole(READ_WRITE)
            .and().csrf().disable();
    

    @Override
    public void configure(WebSecurity web) throws Exception 
         web.ignoring()
             .antMatchers(HttpMethod.OPTIONS)
             .antMatchers(
                     "/actuator/health", 
                     "/swagger-ui.html", 
                     "/webjars/springfox-swagger-ui/**", 
                     "/swagger-resources/**", 
                     "/v2/api-docs/**");
    

还有 WebConfig:

@Configuration
public class WebConfig implements WebMvcConfigurer 

    @Override
    public void addInterceptors(InterceptorRegistry registry) 
        registry.addInterceptor(new RequestIdInterceptor());
    

    @Bean
    public KeycloakSpringBootConfigResolver KeycloakConfigResolver() 
        return new KeycloakSpringBootConfigResolver();
    

编辑:这里是日志。 org.keycloak:TRACE 和 org.springframework.security:TRACE

2019-10-21 18:29:01.648 -DEBUG 98529 --- o.k.adapters.PreAuthActionsHandler       adminRequest http://localhost:8084/service/api/111
2019-10-21 18:29:01.651 -DEBUG 98529 --- o.k.adapters.PreAuthActionsHandler       adminRequest http://localhost:8084/service/api/111
2019-10-21 18:29:01.652 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        --> authenticate()
2019-10-21 18:29:01.652 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        try bearer
2019-10-21 18:29:01.653 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        try query paramter auth
2019-10-21 18:29:01.653 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        try basic auth
2019-10-21 18:29:01.824 -DEBUG 98529 --- o.k.a.BearerTokenRequestAuthenticator    Verifying access_token
2019-10-21 18:29:01.825 -TRACE 98529 --- o.k.a.BearerTokenRequestAuthenticator      access_token: INSERT BEARER TOKEN HERE.signature
2019-10-21 18:29:01.827 -DEBUG 98529 --- o.k.a.BearerTokenRequestAuthenticator    successful authorized
2019-10-21 18:29:01.827 -DEBUG 98529 --- o.k.adapters.RequestAuthenticator        BasicAuth AUTHENTICATED
2019-10-21 18:29:01.827 -TRACE 98529 --- o.k.a.RefreshableKeycloakSecurityContext checking whether to refresh.
2019-10-21 18:29:01.827 -TRACE 98529 --- org.keycloak.adapters.AdapterUtils       useResourceRoleMappings
2019-10-21 18:29:01.827 -TRACE 98529 --- org.keycloak.adapters.AdapterUtils       Setting roles: 
2019-10-21 18:29:01.827 -TRACE 98529 --- org.keycloak.adapters.AdapterUtils          role: SCAN_USER
2019-10-21 18:29:01.827 -DEBUG 98529 --- o.k.adapters.RequestAuthenticator        User 'scantest' invoking 'http://localhost:8084/service/api/111' on client 'clientname'
2019-10-21 18:29:01.827 -DEBUG 98529 --- o.k.a.AuthenticatedActionsHandler        AuthenticatedActionsValve.invoke http://localhost:8084/service/api/111
2019-10-21 18:29:01.827 -DEBUG 98529 --- o.k.a.AuthenticatedActionsHandler        Policy enforcement is disabled.
2019-10-21 18:29:01.827 -DEBUG 98529 --- o.k.a.AuthenticatedActionsHandler        AuthenticatedActionsValve.invoke http://localhost:8084/service/api/111
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.k.a.AuthenticatedActionsHandler        Policy enforcement is disabled.
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Request 'GET /api/111' doesn't match 'OPTIONS /**'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Checking match of request : '/api/111'; against '/actuator/health'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Checking match of request : '/api/111'; against '/swagger-ui.html'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Checking match of request : '/api/111'; against '/webjars/springfox-swagger-ui/**'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Checking match of request : '/api/111'; against '/swagger-resources/**'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Checking match of request : '/api/111'; against '/v2/api-docs/**'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 4 of 12 in additional filter chain; firing Filter: 'KeycloakPreAuthActionsFilter'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.k.adapters.PreAuthActionsHandler       adminRequest http://localhost:8084/service/api/111
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.web.util.matcher.OrRequestMatcher  Trying to match using Ant [pattern='/logout', GET]
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Checking match of request : '/api/111'; against '/logout'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.web.util.matcher.OrRequestMatcher  Trying to match using Ant [pattern='/logout', POST]
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Request 'GET /api/111' doesn't match 'POST /logout'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.web.util.matcher.OrRequestMatcher  Trying to match using Ant [pattern='/logout', PUT]
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Request 'GET /api/111' doesn't match 'PUT /logout'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.web.util.matcher.OrRequestMatcher  Trying to match using Ant [pattern='/logout', DELETE]
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Request 'GET /api/111' doesn't match 'DELETE /logout'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.web.util.matcher.OrRequestMatcher  No matches found
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 6 of 12 in additional filter chain; firing Filter: 'KeycloakAuthenticationProcessingFilter'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.web.util.matcher.OrRequestMatcher  Trying to match using Ant [pattern='/sso/login']
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Checking match of request : '/api/111'; against '/sso/login'
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.web.util.matcher.OrRequestMatcher  Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=Authorization, expectedHeaderValue=null]
2019-10-21 18:29:01.828 -DEBUG 98529 --- o.s.s.web.util.matcher.OrRequestMatcher  matched
2019-10-21 18:29:01.828 -DEBUG 98529 --- f.KeycloakAuthenticationProcessingFilter Request is to process authentication
2019-10-21 18:29:01.828 -DEBUG 98529 --- f.KeycloakAuthenticationProcessingFilter Attempting Keycloak authentication
2019-10-21 18:29:01.828 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        --> authenticate()
2019-10-21 18:29:01.829 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        try bearer
2019-10-21 18:29:01.829 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        try query paramter auth
2019-10-21 18:29:01.829 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        try basic auth
2019-10-21 18:29:01.970 -DEBUG 98529 --- o.k.a.BearerTokenRequestAuthenticator    Verifying access_token
2019-10-21 18:29:01.970 -TRACE 98529 --- o.k.a.BearerTokenRequestAuthenticator      access_token:  INSERT BEARER TOKEN HERE.signature
2019-10-21 18:29:01.971 -DEBUG 98529 --- o.k.a.BearerTokenRequestAuthenticator    successful authorized
2019-10-21 18:29:01.971 -DEBUG 98529 --- o.k.adapters.RequestAuthenticator        BasicAuth AUTHENTICATED
2019-10-21 18:29:01.971 -TRACE 98529 --- o.k.a.RefreshableKeycloakSecurityContext checking whether to refresh.
2019-10-21 18:29:01.971 -TRACE 98529 --- org.keycloak.adapters.AdapterUtils       useResourceRoleMappings
2019-10-21 18:29:01.971 -TRACE 98529 --- org.keycloak.adapters.AdapterUtils       Setting roles: 
2019-10-21 18:29:01.971 -TRACE 98529 --- org.keycloak.adapters.AdapterUtils          role: SCAN_USER
2019-10-21 18:29:01.971 -DEBUG 98529 --- a.s.a.SpringSecurityRequestAuthenticator Completing bearer authentication. Bearer roles: [SCAN_USER] 
2019-10-21 18:29:01.971 -DEBUG 98529 --- o.k.adapters.RequestAuthenticator        User 'scantest' invoking 'http://localhost:8084/service/api/111' on client 'clientname'
2019-10-21 18:29:01.971 -DEBUG 98529 --- f.KeycloakAuthenticationProcessingFilter Auth outcome: AUTHENTICATED
2019-10-21 18:29:01.971 -DEBUG 98529 --- o.s.s.authentication.ProviderManager     Authentication attempt using org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Registering session MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L, for principal scantest
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Removing session MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L from set of registered sessions
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Removing session MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L from principal's set of registered sessions
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Removing principal scantest from registry
2019-10-21 18:29:01.972 -TRACE 98529 --- o.s.s.core.session.SessionRegistryImpl   Sessions used by 'scantest' : []
2019-10-21 18:29:01.972 -TRACE 98529 --- o.s.s.core.session.SessionRegistryImpl   Sessions used by 'scantest' : [MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L]
2019-10-21 18:29:01.972 -DEBUG 98529 --- f.KeycloakAuthenticationProcessingFilter Authentication success using bearer token/basic authentication. Updating SecurityContextHolder to contain: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@2f5132da: Principal: scantest; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@592730ab; Granted Authorities: ROLE_SCAN_USER
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.w.a.AnonymousAuthenticationFilter  SecurityContextHolder not populated with anonymous token, as it already contained: 'org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@2f5132da: Principal: scantest; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@592730ab; Granted Authorities: ROLE_SCAN_USER'
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2019-10-21 18:29:01.972 -DEBUG 98529 --- s.CompositeSessionAuthenticationStrategy Delegating to org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy@556aed22
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Registering session MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L, for principal scantest
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Removing session MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L from set of registered sessions
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Removing session MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L from principal's set of registered sessions
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Removing principal scantest from registry
2019-10-21 18:29:01.972 -TRACE 98529 --- o.s.s.core.session.SessionRegistryImpl   Sessions used by 'scantest' : []
2019-10-21 18:29:01.972 -TRACE 98529 --- o.s.s.core.session.SessionRegistryImpl   Sessions used by 'scantest' : [MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L]
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Request '/api/111' matched by universal pattern '/**'
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.w.a.i.FilterSecurityInterceptor    Secure object: FilterInvocation: URL: /api/111; Attributes: [hasAnyAuthority('ROLE_SCAN_USER','ROLE_WRITE_USER')]
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.w.a.i.FilterSecurityInterceptor    Previously Authenticated: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@2f5132da: Principal: scantest; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@592730ab; Granted Authorities: ROLE_SCAN_USER
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.access.vote.AffirmativeBased       Voter: org.springframework.security.web.access.expression.WebExpressionVoter@1bc888f1, returned: 1
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.w.a.i.FilterSecurityInterceptor    Authorization successful
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.s.w.a.i.FilterSecurityInterceptor    RunAsManager did not change Authentication object
2019-10-21 18:29:01.972 -DEBUG 98529 --- o.s.security.web.FilterChainProxy        /api/111 reached end of additional filter chain; proceeding with original chain
2019-10-21 18:29:01.973 -DEBUG 98529 --- o.s.s.web.util.matcher.OrRequestMatcher  Trying to match using Ant [pattern='/sso/login']
2019-10-21 18:29:01.973 -DEBUG 98529 --- o.s.s.w.u.matcher.AntPathRequestMatcher  Checking match of request : '/api/111'; against '/sso/login'
2019-10-21 18:29:01.973 -DEBUG 98529 --- o.s.s.web.util.matcher.OrRequestMatcher  Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=Authorization, expectedHeaderValue=null]
2019-10-21 18:29:01.973 -DEBUG 98529 --- o.s.s.web.util.matcher.OrRequestMatcher  matched
2019-10-21 18:29:01.973 -DEBUG 98529 --- f.KeycloakAuthenticationProcessingFilter Request is to process authentication
2019-10-21 18:29:01.973 -DEBUG 98529 --- f.KeycloakAuthenticationProcessingFilter Attempting Keycloak authentication
2019-10-21 18:29:01.973 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        --> authenticate()
2019-10-21 18:29:01.973 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        try bearer
2019-10-21 18:29:01.973 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        try query paramter auth
2019-10-21 18:29:01.973 -TRACE 98529 --- o.k.adapters.RequestAuthenticator        try basic auth
2019-10-21 18:29:02.114 -DEBUG 98529 --- o.k.a.BearerTokenRequestAuthenticator    Verifying access_token
2019-10-21 18:29:02.114 -TRACE 98529 --- o.k.a.BearerTokenRequestAuthenticator      access_token:  INSERT BEARER TOKEN HERE.signature
2019-10-21 18:29:02.116 -DEBUG 98529 --- o.k.a.BearerTokenRequestAuthenticator    successful authorized
2019-10-21 18:29:02.116 -DEBUG 98529 --- o.k.adapters.RequestAuthenticator        BasicAuth AUTHENTICATED
2019-10-21 18:29:02.116 -TRACE 98529 --- o.k.a.RefreshableKeycloakSecurityContext checking whether to refresh.
2019-10-21 18:29:02.116 -TRACE 98529 --- org.keycloak.adapters.AdapterUtils       useResourceRoleMappings
2019-10-21 18:29:02.116 -TRACE 98529 --- org.keycloak.adapters.AdapterUtils       Setting roles: 
2019-10-21 18:29:02.116 -TRACE 98529 --- org.keycloak.adapters.AdapterUtils          role: SCAN_USER
2019-10-21 18:29:02.116 -DEBUG 98529 --- a.s.a.SpringSecurityRequestAuthenticator Completing bearer authentication. Bearer roles: [SCAN_USER] 
2019-10-21 18:29:02.116 -DEBUG 98529 --- o.k.adapters.RequestAuthenticator        User 'scantest' invoking 'http://localhost:8084/service/api/111' on client 'clientname'
2019-10-21 18:29:02.116 -DEBUG 98529 --- f.KeycloakAuthenticationProcessingFilter Auth outcome: AUTHENTICATED
2019-10-21 18:29:02.116 -DEBUG 98529 --- o.s.s.authentication.ProviderManager     Authentication attempt using org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticationProvider
2019-10-21 18:29:02.117 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Registering session MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L, for principal scantest
2019-10-21 18:29:02.117 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Removing session MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L from set of registered sessions
2019-10-21 18:29:02.117 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Removing session MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L from principal's set of registered sessions
2019-10-21 18:29:02.117 -DEBUG 98529 --- o.s.s.core.session.SessionRegistryImpl   Removing principal scantest from registry
2019-10-21 18:29:02.117 -TRACE 98529 --- o.s.s.core.session.SessionRegistryImpl   Sessions used by 'scantest' : []
2019-10-21 18:29:02.117 -TRACE 98529 --- o.s.s.core.session.SessionRegistryImpl   Sessions used by 'scantest' : [MYs36v2qRDjsrESJs7dMO4CdBuQjrO0kDF0ZUy7L]
2019-10-21 18:29:02.117 -DEBUG 98529 --- f.KeycloakAuthenticationProcessingFilter Authentication success using bearer token/basic authentication. Updating SecurityContextHolder to contain: org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken@156b8e00: Principal: scantest; Credentials: [PROTECTED]; Authenticated: true; Details: org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount@42235f32; Granted Authorities: ROLE_SCAN_USER
2019-10-21 18:29:02.117 -DEBUG 98529 --- o.k.adapters.PreAuthActionsHandler       adminRequest http://localhost:8084/service/api/111
2019-10-21 18:29:02.117 -DEBUG 98529 --- o.k.a.AuthenticatedActionsHandler        AuthenticatedActionsValve.invoke http://localhost:8084/service/api/111
2019-10-21 18:29:02.117 -DEBUG 98529 --- o.k.a.AuthenticatedActionsHandler        Policy enforcement is disabled.

【问题讨论】:

你的日志是什么样的? 日志现已发布;) 【参考方案1】:

这不是最佳解决方案,因为它没有解决根本原因。但这个修复/破解对我们有用。

public class OurKeycloakAuthenticationProcessingFilter extends KeycloakAuthenticationProcessingFilter 

    public OurKeycloakAuthenticationProcessingFilter(AuthenticationManager authenticationManager) 
        super(authenticationManager);
    

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException 

        LOG.info("OurKeycloakAuthenticationProcessingFilter...");
        if (SecurityContextHolder.getContext().getAuthentication() != null && SecurityContextHolder.getContext().getAuthentication().isAuthenticated()) 
            LOG.info("OurKeycloakAuthenticationProcessingFilter. We are already authenticated");
            return SecurityContextHolder.getContext().getAuthentication();
        
        return super.attemptAuthentication(request, response);
    


然后将这个添加到 KeycloakSecurityConfig 类中:

    @Bean
    @Primary
    @Override
    protected KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter() throws Exception 
        KeycloakAuthenticationProcessingFilter filter = new OurKeycloakAuthenticationProcessingFilter(authenticationManagerBean());
        filter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy());
        return filter;
    

【讨论】:

【参考方案2】:

我在阅读 Keycloak 的文档时遇到了这个问题:

https://github.com/keycloak/keycloak-documentation/blob/master/securing_apps/topics/oidc/java/spring-security-adapter.adoc#avoid-double-bean-registration.

您可以尝试遵循文档中的建议,看看是否对您的问题有帮助。

Spring Boot 尝试将过滤器 bean 急切地注册到 Web 应用程序上下文中。因此,在 Spring Boot 环境中运行 Keycloak Spring Security 适配器时,可能需要将 FilterRegistrationBeans 添加到您的安全配置中,以防止 Keycloak 过滤器被注册两次。

Spring Boot 2.1 默认也禁用 spring.main.allow-bean-definition-overriding。这可能意味着如果扩展 KeycloakWebSecurityConfigurerAdapter 的配置类注册了一个已被 @ComponentScan 检测到的 bean,则会遇到 BeanDefinitionOverrideException。这可以通过覆盖注册以使用特定于引导的@ConditionalOnMissingBean 注释来避免,就像下面的 HttpSessionManager 一样。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter

    ...

    @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 的注册是否会导致安全隐患 httpSessionManager() bean 在这里覆盖的目的是什么? 它只是为了显示 bean 覆盖问题的克服还是同时处理多个过滤器注册问题?

以上是关于Spring Boot Keycloak - 每个请求验证 3 次的主要内容,如果未能解决你的问题,请参考以下文章

Spring-boot 和 Keycloak 集成

Spring Boot - KeyCloak 指向 403 禁止

在 Spring Boot 中扩展 Keycloak 令牌

403 spring-boot-2-keycloak-适配器

Keycloak,如何保护不提供网页的 Spring Boot 后端?

Angular - Spring Boot - Keycloak - 401错误