提问者:小点点

与OAuth2丢失会话的Spring Security


我们有一个基于Spring Boot的网关,使用Spring Security、OAuth2登录和Zuul路由。它还使用Spring Session在Redis中存储会话。此网关在会话中存储OAuth2令牌,并将OAuth2承载令牌转发到后端服务。

我们有一个用户经常被注销的问题。似乎这大约每小时发生一次。我们甚至不太确定是什么导致了所有不同的工具到位。

我们在浏览器中的会话cookie会在更长的时间内过期。所以我怀疑要么是Spring使会话无效,要么是OAuth2令牌过期。

通过对代码的快速检查,OAuth2TokenRelayFilter似乎支持刷新令牌。这是正确的吗?

如何追查原因并解决它?

作为参考,我们使用这些版本:

  • Spring启动2.1.12
  • Spring Cloud Greenwich. SR4

以下是一些相关片段。

我们的网页安全配置。

@Configuration
@EnableWebSecurity
@EnableOAuth2Sso
@Order(SecurityProperties.BASIC_AUTH_ORDER - 2)
@Profile("!security-disabled")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
    @Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off
            http
                .authorizeRequests()
                    .antMatchers("/login", "/login/**", "/favicon.ico").permitAll()
                    .antMatchers("/signout").authenticated()
                    .anyRequest().hasAnyRole("ADMIN", "MEMBER")
                    .and()
                .csrf()
                    .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                    .and()
                .httpBasic()
                    .disable()
                .formLogin()
                    .disable()
                .logout()
                    .logoutUrl("/signout")
                    .deleteCookies("SESSION")
                    .and()
            // @formatter:on
    }

API路径的安全配置。

@Configuration
@Order(SecurityProperties.BASIC_AUTH_ORDER - 2 - 10)
@Profile("!security-disabled")
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter
{
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off
            http.requestMatchers()
                    .antMatchers("/api/**")
                    .and()
                    .authorizeRequests()
                    .antMatchers("/**").hasAnyRole("ADMIN", "MEMBER")
                        .and()
                    .csrf()
                        .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                        .and()
                    .headers()
                        .frameOptions().sameOrigin()
                        .and()
                    .httpBasic()
                        .disable()
                    .formLogin()
                        .disable()
                    .logout()
                        .disable()
                    .exceptionHandling().authenticationEntryPoint(new Http403ForbiddenEntryPoint());
            // @formatter:on
    }

}

更新

我们已经对Spring内部进行了一些调试。首先,我们发现我们缺少一个OAuth2RestTemplate。根据OAuth2引导留档,我们发现如何添加它:

@Bean
public OAuth2RestTemplate oauth2RestTemplate(
        OAuth2ClientContext oauth2ClientContext,
        OAuth2ProtectedResourceDetails details)
{
    return new OAuth2RestTemplate(details, oauth2ClientContext);
}

现在,当OAuth2TokenRelayFilter调用restTemplace. getAccessToken().getValue();时,这会引发异常。

需要重定向才能获得用户的批准

此异常是从AuthorizationCodeAccessTokenProvider引发的。


共1个答案

匿名用户

OAuth 2令牌中继过滤器

OAuth2TokenRelayFilter是一个预类型过滤器,它将上下文设置为ACCESS_TOKEN和TOKEN_TYPE,用于进一步的身份验证。它使用getAccessToken()方法验证令牌,并以401状态响应“无法获得有效的访问令牌”。

您可以检查令牌的有效性并正确配置刷新令牌grant_typerefresh_token当访问令牌过期时,客户端使用刷新令牌授予类型将刷新令牌交换为访问令牌,这允许客户端继续拥有有效的访问令牌,而无需与用户进行进一步交互。

如果您想禁用OAuth2TokenRelayFilter,您可以使用以下方法

zuul.OAuth2TokenRelayFilter.pre.disable=true