5

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

目标是:

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

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

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

根据我的理解:

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

如代码片段中所述,由于我们使用Keycloak 的一部分并且应用程序是一个(因此管理这些资源记录) ,SessionAuthenticationStrategy因此不会将其设置为 null 一次。AuthorizationService 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();
    }

}
4

1 回答 1

6

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

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

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

于 2020-01-15T10:04:08.660 回答