了解 Keycloak Adapter(Spring-Security 和 Spring Boot)会话要求

Posted

技术标签:

【中文标题】了解 Keycloak Adapter(Spring-Security 和 Spring Boot)会话要求【英文标题】:Understanding Keycloak Adapter (Spring-Security & Spring Boot) session requirement 【发布时间】:2019-11-20 23:39:57 【问题描述】:

对于正在积极开发的软件,我们使用 Spring Boot(带有 Spring Security)和 Keycloak Adapter。

目标是:

要求对所有端点进行有效的身份验证,但用@Public 注释的端点除外(请参见代码 sn-p)(可行) 身份验证必须通过 OAuth - 客户端直接从 Keycloak 获取令牌,Spring Security + Keycloak 适配器确保它有效 可选地,还支持基本身份验证(Keycloak 适配器可以配置为执行登录并使其在其余代码中看起来像常规令牌身份验证)(这也适用)

目前一切正常,但我在理解一些细节时遇到了一些问题:

KeycloakWebSecurityConfigurerAdapter 启用CSRF 保护。我认为这样做只是为了让它可以注册自己的 Matcher 以允许来自 Keycloak 的请求 它启用会话管理并需要一些相应的 bean 即使使用令牌身份验证发出请求,也会返回 JSESSIONID cookie

据我了解:

由于使用了无状态令牌身份验证,因此不需要会话(那么为什么KeycloakWebSecurityConfigurerAdapter 启用它)。这仅适用于BASIC Auth 部分吗? 由于启用了会话,确实需要CSRF 保护 - 但我不希望首先使用会话,然后 API 就不需要CSRF 保护,对吧? 即使我在super.configure(http) 调用之后设置了http.sessionManagement().disable()JSESSIONID cookie 也已设置(那么这是从哪里来的?)

正如代码 sn-p 中所述,SessionAuthenticationStrategy 不会设置为 null 一次,因为我们使用 Keycloak 的 Authorization 部分并且应用程序是 Service Account Manager(因此管理这些资源记录)。

如果有人能把事情弄清楚就好了。提前致谢!

@KeycloakConfiguration
public class WebSecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter 

    @Inject private RequestMappingHandlerMapping requestMappingHandlerMapping;

    @Override
    protected void configure(final HttpSecurity http) throws Exception 
        super.configure(http);
        http
            .authorizeRequests()
                .requestMatchers(new PublicHandlerMethodMatcher(requestMappingHandlerMapping))
                    .permitAll()
                .anyRequest()
                    .authenticated();
    

    // ~~~~~~~~~~ Keycloak ~~~~~~~~~~

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

    /**
     * @link NullAuthenticatedSessionStrategy is not used since we initiate logins
     * from our application and this would not be possible with @code bearer-only
     * clients (for which the null strategy is recommended). 
     */
    @Override
    @Bean protected SessionAuthenticationStrategy sessionAuthenticationStrategy() 
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    

    /**
     * HTTP session @link ApplicationEvent publisher needed for the
     * @link SessionRegistryImpl of @link #sessionAuthenticationStrategy()
     * to work properly.
     */
    @Bean public HttpSessionEventPublisher httpSessionEventPublisher() 
        return new HttpSessionEventPublisher();
    

    @Override
    @Bean public KeycloakAuthenticationProvider keycloakAuthenticationProvider() 
        return super.keycloakAuthenticationProvider();
    


【问题讨论】:

【参考方案1】:

您可能会过度使用 JWT 令牌。看看这篇文章,例如https://blog.logrocket.com/jwt-authentication-best-practices/。尤其是在文章末尾关于 JWT 作为会话令牌的参考资料。

对于您的 Web 应用程序 UI,您在大多数情况下都使用会话。用于身份验证的令牌类型无关紧要。 Keycloak 做的一切都是正确的——它返回 httpOnly 安全 cookie 用于会话管理并在后端跟踪用户状态。为了更好地理解它的工作原理,您可以查看此处的示例代码:examples

为了更好地分离无状态后端(微)服务和用户 UI 会话 keycloak documentation 建议使用 2 种不同的身份验证策略:RegisterSessionAuthenticationStrategy 用于会话,NullAuthenticatedSessionStrategy 用于仅承载服务

【讨论】:

以上是关于了解 Keycloak Adapter(Spring-Security 和 Spring Boot)会话要求的主要内容,如果未能解决你的问题,请参考以下文章

HttpSecurity 配置不适用于 Spring 上的 Keycloak Adapter

Spring Keycloak Adapter 为每个请求加载 Open-ID 配置

Keycloak Java Adapter 属性“public-client”是啥意思?

JBoss 没有重定向到 Keycloak

Keycloak 注销不会结束会话

Keycloak 和 Spring Security