Spring boot 反应式spring云安全(带KeyClope):会话过期?

Spring boot 反应式spring云安全(带KeyClope):会话过期?,spring-boot,spring-security,keycloak,spring-webflux,spring-cloud-gateway,Spring Boot,Spring Security,Keycloak,Spring Webflux,Spring Cloud Gateway,我尝试实现以下内容:我想要一个具有一个或多个SpringCloudGateway的分布式环境,在这些网关后面有几个微服务(部分)对外公开。对于用户身份验证,我想使用OIDC(刚刚移到KeyClope) 实际上,我只是坚持使用spring security、webflux和boot的参考文档中的标准配置 具体而言,我在网关中: private final ReactiveClientRegistrationRepository clientRegistrationRepository; @Bea

我尝试实现以下内容:我想要一个具有一个或多个SpringCloudGateway的分布式环境,在这些网关后面有几个微服务(部分)对外公开。对于用户身份验证,我想使用OIDC(刚刚移到KeyClope)

实际上,我只是坚持使用spring security、webflux和boot的参考文档中的标准配置

具体而言,我在网关中:

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;
}
对于概念验证,我有一个“环境测试应用程序”,其中一个控制器只是将声明作为json返回。其配置如下:

@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
    http
            .authorizeExchange()
            .pathMatchers("/actuator/**").permitAll()
            .anyExchange().authenticated()
            .and()
            .oauth2ResourceServer()
            .jwt(Customizer.withDefaults());

    return http.build();
}
application.yml仅包含上面的领事和安全部分

基本上这是可行的。如果我尝试访问环境测试应用程序,我会被重定向到KeyClope,我必须输入凭据并被重定向回环境测试应用程序并查看声明。我可以通过“/注销”方式注销

问题是:5分钟后,keydove会话过期,我得到一个401,chrome显示“这个页面不工作”。即使我一直在重新加载(用户活动),这种情况也会发生

据我理解,本届会议应:

  • 只要有活动,就可以进行扩展(我认为这就是刷新令牌的用途,并假设spring安全性可以自动处理)
  • 当用户处于非活动状态一段时间后过期。当用户再次处于活动状态时,应将其重定向到登录,然后再返回到原始资源
  • 当点击“记住我”时,过期的会话应该在没有用户活动的情况下重新初始化(我认为,这就是KeyClope的脱机令牌的用途)
我想这一切都可以通过添加一些简单的配置行来实现,我只是不知道是哪一行。参考文档对我来说并不完全清楚,但我觉得默认情况下,这一切都是这样处理的。然而,事实并非如此

注意:我使用的是带有默认Reactor Netty的spring反应堆栈。因此,既不能使用spring安全性,也不能使用Key斗篷提供的spring引导插件。另外,我不清楚它们如何与标准配置方案交互


注意:在我和okta尝试所有这些之前(使用他们的启动器)。上述问题似乎神奇地与okta合作。但是,我遇到了不同的问题,因此现在转向开源。

TokenRelayGatewayFilterFactory添加了访问令牌,但在其过期时不会刷新它……这就是我相信您可以获得401的原因。还有一个开放的SpringCloudGateway问题,需要一个更新的解决方案。关于该问题的一条评论提供了一个实现:

当刷新令牌过滤器工作时,只有在您的spring云网关“会话”过期后,KeyClose会话才变得重要,因为如果KeyClose会话仍然良好,它允许oauth2重定向无需再次输入您的凭据即可重新建立会话

如果您希望自定义webflux应用程序的会话,有以下几种解决方案:


不确定您在前端使用的是什么,但他告诉我如何将spring security与spring cloud gateway结合使用,并做出反应:

很酷,我将看看实现。实际上,我正在考虑向我的配置中添加另一个
WebFilter
,但仅仅使用
TokenRelayGatewayFilterFactory
是一个绝妙的想法。我会看一看,然后尽快回来。顺便问一下,你知道提醒我的功能吗?@PeMa,太好了。抱歉,最近没有使用“记住我”功能。@PeMa。我不明白你为什么要用“记住我”这个词?老实说,我真的不明白这个意思。但是,从我看到的情况来看,我只能猜测“记住我”在KeyClope中创建了一个脱机会话。这可能用于恢复会话,即使在实际刷新令牌过期很久之后也是如此。非常感谢。我刚刚找到时间尝试TokenRelayWithTokenRefreshGatewayFilterFactory。它工作得非常完美。
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
    http
            .authorizeExchange()
            .pathMatchers("/actuator/**").permitAll()
            .anyExchange().authenticated()
            .and()
            .oauth2ResourceServer()
            .jwt(Customizer.withDefaults());

    return http.build();
}