反应性 spring 云安全(使用 Keycloak):Session 过期?
Reactive spring cloud security (with Keycloak): Session expiration?
我尝试实现以下内容:我想要一个具有一个或多个 spring 云网关的分布式环境,这些网关背后是几个(部分)暴露于外部的微服务。对于用户身份验证,我想使用 OIDC(刚刚移至 Keycloak)。
实际上我只是坚持使用 spring 安全、webflux 和引导参考文档中的标准配置。
详细的,我在网关里有:
private final ReactiveClientRegistrationRepository clientRegistrationRepository;
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.csrf().disable()
.authorizeExchange()
.pathMatchers("/login").permitAll()
.pathMatchers("/actuator/**").permitAll()
.anyExchange().authenticated()
.and()
.oauth2Login()
.and()
.logout(logout -> logout.logoutSuccessHandler(oidcLogoutSuccessHandler()));
return http.build();
}
private ServerLogoutSuccessHandler oidcLogoutSuccessHandler() {
OidcClientInitiatedServerLogoutSuccessHandler oidcLogoutSuccessHandler =
new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository);
oidcLogoutSuccessHandler.setPostLogoutRedirectUri(URI.create("https://<host>/login?logout"));
return oidcLogoutSuccessHandler;
}
with application.yml(仅必要部分):
spring:
cloud:
gateway:
default-filters:
- TokenRelay=
- RemoveRequestHeader=Cookie
discovery:
locator:
enabled: true
consul:
host: 127.0.0.1
port: 8500
loadbalancer:
ribbon:
enabled: false
security:
oauth2:
client:
provider:
keycloak:
issuer-uri: ${KEYCLOAK_ISSUER_URI}
registration:
keycloak:
client-id: ${KEYCLOAK_CLIENT_ID}
client-secret: ${KEYCLOAK_CLIENT_SECRET}
resourceserver:
jwt:
jwk-set-uri: ${KEYCLOAK_ISSUER_URI}/protocol/openid-connect/certs
server:
forward-headers-strategy: framework
为了概念验证,我有一个“environment-test-application”,控制器只是将声明作为 json 返回。它的配置如下:
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.pathMatchers("/actuator/**").permitAll()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt(Customizer.withDefaults());
return http.build();
}
application.yml只包含上面的领事和安全部分。
基本上这行得通。如果我尝试访问 environment-test-application,我将被重定向到 Keycloak,我必须输入我的凭据并被重定向回 environment-test-application 并查看声明。我可以通过“/logout”注销。
问题:密钥斗篷 session 5 分钟后过期,我收到 401 并且 chrome 说“此页面无法正常工作”。即使我一直在重新加载,也会发生这种情况(用户 activity)。
据我了解 session 应该:
- 只要有 activity 就可以扩展(我认为这就是刷新令牌的用途,并假设 spring 安全性可以自动处理)
- 当用户不活动一段时间后过期。当用户再次处于活动状态时,he/she 应该被重定向到登录,然后返回到原始资源。
- 当点击“记住我”时,过期的 session 应该在没有用户的情况下重新启动 activity (我认为,这就是 Keycloak 的离线令牌的用途)。
我想这一切都可以通过添加一些简单的配置行来实现,但我不知道是哪一行。参考文档对我来说并不完全清楚,但我感觉这一切都是默认情况下处理的。然而,事实并非如此。
注意:我正在使用 spring 反应堆和默认的 Reactor Netty。因此,既不能使用 spring 安全性,也不能使用 Keycloak 提供的 spring 启动插件。另外,我不清楚它们如何与标准配置方案交互。
注意:在我用 okta 尝试所有这些之前(使用他们的启动器)。上面描述的问题似乎神奇地与 okta 一起工作。但是,我遇到了不同的问题,因此现在转向开源。
TokenRelayGatewayFilterFactory 添加访问令牌但在它过期时不刷新它...我相信这就是您得到 401 的原因。有一个未解决的 spring 云网关问题,要求同时刷新的解决方案。关于该问题的评论之一提供了一个实现:https://github.com/spring-cloud/spring-cloud-security/issues/175#issuecomment-557135243.
当刷新令牌过滤器工作时,keycloak 会话仅在您的 spring 云网关“会话”过期后才变得重要,因为如果 keycloak 会话仍然有效,它允许 oauth2 重定向重新-无缝建立会话(即无需再次输入您的凭据)。
如果您希望自定义 webflux 应用程序的会话,有一些解决方案,包括这个:
不确定您的前端使用的是什么,但他是我使用 spring 安全性和 spring 云网关并做出反应的方式:https://sdoxsee.github.io/blog/2019/12/17/merry-microservices-part2-ui-gateway
我尝试实现以下内容:我想要一个具有一个或多个 spring 云网关的分布式环境,这些网关背后是几个(部分)暴露于外部的微服务。对于用户身份验证,我想使用 OIDC(刚刚移至 Keycloak)。
实际上我只是坚持使用 spring 安全、webflux 和引导参考文档中的标准配置。
详细的,我在网关里有:
private final ReactiveClientRegistrationRepository clientRegistrationRepository;
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.csrf().disable()
.authorizeExchange()
.pathMatchers("/login").permitAll()
.pathMatchers("/actuator/**").permitAll()
.anyExchange().authenticated()
.and()
.oauth2Login()
.and()
.logout(logout -> logout.logoutSuccessHandler(oidcLogoutSuccessHandler()));
return http.build();
}
private ServerLogoutSuccessHandler oidcLogoutSuccessHandler() {
OidcClientInitiatedServerLogoutSuccessHandler oidcLogoutSuccessHandler =
new OidcClientInitiatedServerLogoutSuccessHandler(clientRegistrationRepository);
oidcLogoutSuccessHandler.setPostLogoutRedirectUri(URI.create("https://<host>/login?logout"));
return oidcLogoutSuccessHandler;
}
with application.yml(仅必要部分):
spring:
cloud:
gateway:
default-filters:
- TokenRelay=
- RemoveRequestHeader=Cookie
discovery:
locator:
enabled: true
consul:
host: 127.0.0.1
port: 8500
loadbalancer:
ribbon:
enabled: false
security:
oauth2:
client:
provider:
keycloak:
issuer-uri: ${KEYCLOAK_ISSUER_URI}
registration:
keycloak:
client-id: ${KEYCLOAK_CLIENT_ID}
client-secret: ${KEYCLOAK_CLIENT_SECRET}
resourceserver:
jwt:
jwk-set-uri: ${KEYCLOAK_ISSUER_URI}/protocol/openid-connect/certs
server:
forward-headers-strategy: framework
为了概念验证,我有一个“environment-test-application”,控制器只是将声明作为 json 返回。它的配置如下:
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.pathMatchers("/actuator/**").permitAll()
.anyExchange().authenticated()
.and()
.oauth2ResourceServer()
.jwt(Customizer.withDefaults());
return http.build();
}
application.yml只包含上面的领事和安全部分。
基本上这行得通。如果我尝试访问 environment-test-application,我将被重定向到 Keycloak,我必须输入我的凭据并被重定向回 environment-test-application 并查看声明。我可以通过“/logout”注销。
问题:密钥斗篷 session 5 分钟后过期,我收到 401 并且 chrome 说“此页面无法正常工作”。即使我一直在重新加载,也会发生这种情况(用户 activity)。
据我了解 session 应该:
- 只要有 activity 就可以扩展(我认为这就是刷新令牌的用途,并假设 spring 安全性可以自动处理)
- 当用户不活动一段时间后过期。当用户再次处于活动状态时,he/she 应该被重定向到登录,然后返回到原始资源。
- 当点击“记住我”时,过期的 session 应该在没有用户的情况下重新启动 activity (我认为,这就是 Keycloak 的离线令牌的用途)。
我想这一切都可以通过添加一些简单的配置行来实现,但我不知道是哪一行。参考文档对我来说并不完全清楚,但我感觉这一切都是默认情况下处理的。然而,事实并非如此。
注意:我正在使用 spring 反应堆和默认的 Reactor Netty。因此,既不能使用 spring 安全性,也不能使用 Keycloak 提供的 spring 启动插件。另外,我不清楚它们如何与标准配置方案交互。
注意:在我用 okta 尝试所有这些之前(使用他们的启动器)。上面描述的问题似乎神奇地与 okta 一起工作。但是,我遇到了不同的问题,因此现在转向开源。
TokenRelayGatewayFilterFactory 添加访问令牌但在它过期时不刷新它...我相信这就是您得到 401 的原因。有一个未解决的 spring 云网关问题,要求同时刷新的解决方案。关于该问题的评论之一提供了一个实现:https://github.com/spring-cloud/spring-cloud-security/issues/175#issuecomment-557135243.
当刷新令牌过滤器工作时,keycloak 会话仅在您的 spring 云网关“会话”过期后才变得重要,因为如果 keycloak 会话仍然有效,它允许 oauth2 重定向重新-无缝建立会话(即无需再次输入您的凭据)。
如果您希望自定义 webflux 应用程序的会话,有一些解决方案,包括这个:
不确定您的前端使用的是什么,但他是我使用 spring 安全性和 spring 云网关并做出反应的方式:https://sdoxsee.github.io/blog/2019/12/17/merry-microservices-part2-ui-gateway