对于正在进行活跃开发的软件,我们使用Spring Boot(带有Spring Security)和Keycloak适配器。
目标是:
- 对所有除了那些用@Public注释的端点以外的端点都需要有效身份验证(代码段中已实现)。 - 身份验证必须通过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(那么这是从哪里来的呢?)
如代码段中所述,SessionAuthenticationStrategy没有设置为null,因为我们使用Keycloak的Authorization部分,应用程序是Service Account Manager(因此管理这些资源记录)。
如果有人能澄清一下这些问题就太好了。提前谢谢!
目标是:
- 对所有除了那些用@Public注释的端点以外的端点都需要有效身份验证(代码段中已实现)。 - 身份验证必须通过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(那么这是从哪里来的呢?)
如代码段中所述,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();
}
}