我们有一个使用Spring Security,OAuth2登录和Zuul路由的基于Spring Boot的网关。它还使用Spring Session将会话存储在Redis中。该网关将OAuth2令牌存储在会话中,并将OAuth2承载令牌转发给后端服务。
我们遇到一个问题,即用户经常退出。看来这大约每小时发生一次。我们甚至还不确定在使用所有不同工具时是什么原因造成的。
我们在浏览器中的会话cookie会在更长的时间内过期。因此,我怀疑是Spring使会话无效,还是OAuth2令牌到期。
通过快速检查代码,可以发现OAuth2TokenRelayFilter
支持刷新令牌。这是正确的吗?
如何找到原因并加以解决?
作为参考,我们正在使用以下版本:
以下是一些相关的摘要。
我们用于网页的网络安全配置。
@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 Boot documentation,我们发现了如何添加:
@Bean
public OAuth2RestTemplate oauth2RestTemplate(
OAuth2ClientContext oauth2ClientContext,
OAuth2ProtectedResourceDetails details)
{
return new OAuth2RestTemplate(details, oauth2ClientContext);
}
当OAuth2TokenRelayFilter
调用restTemplate.getAccessToken().getValue();
时,这将引发异常。
需要重定向才能获得用户的认可
此异常是从AuthorizationCodeAccessTokenProvider引发的。
答案 0 :(得分:1)
OAuth2TokenRelayFilter
OAuth2TokenRelayFilter
是一个 pre 类型过滤器,它使用 ACCESS_TOKEN 和 TOKEN_TYPE 设置上下文,这将用于进一步的身份验证。它使用getAccessToken()
方法验证令牌,并以401状态的“无法获得有效的访问令牌” 进行响应。
您可以检查令牌的有效性,并使用 grant_type 将刷新令牌正确配置为 refresh_token ,因为客户端使用“刷新令牌”授予类型来交换刷新令牌。访问令牌过期后的访问令牌,允许客户端继续拥有有效的访问令牌,而无需与用户进行进一步的交互。
如果要禁用 OAuth2TokenRelayFilter ,则可以使用以下
zuul.OAuth2TokenRelayFilter.pre.disable=true