Hey all, I am using Spring Cloud Gateway as well as the Okta starter to manage the user’s session for single page app.
It seems that the access token is not refreshed after expiry. This was called out as an issue on GitHub, and should have been resolved, but for some reason we’re still seeing expired tokens getting passed to downstream services. The only way we can get a new token is forcing the user to logout and then log in again.
Versions
Spring Boot: 2.4.9
Cloud: 2020.0.3
Okta Boot Starter: 2.0.1
okta:
oauth2:
scopes:
- openid
- profile
- email
- offline_access # thought this would fix it up
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
@Slf4j
class WebSecurityConfiguration {
@Autowired
CsrfHeaderFilter csrfHeaderFilter
@Autowired
CustomAuthenticationSuccessHandler successHandler
@Bean
WebFilter addCsrfToken() {
return { exchange, next ->
exchange
.<Mono<CsrfToken>> getAttribute(CsrfToken.class.getName())
// do nothing, just subscribe :/
// https://github.com/spring-projects/spring-security/issues/5766#issuecomment-564636167
.doOnSuccess({ token -> })
.then(next.filter(exchange))
}
}
@Bean
SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.addFilterBefore(csrfHeaderFilter, SecurityWebFiltersOrder.CSRF)
.httpBasic().disable()
.formLogin().disable()
.oauth2Login({
it.authenticationSuccessHandler(successHandler)
})
.csrf(this.&configureCsrf)
.authorizeExchange()
.pathMatchers("/actuator/health").permitAll()
.pathMatchers("/**").authenticated()
.and().build()
}
ServerHttpSecurity.CsrfSpec configureCsrf(ServerHttpSecurity.CsrfSpec csrfSpec) {
def csrfTokenRepository = new CookieServerCsrfTokenRepository()
csrfTokenRepository.cookieHttpOnly = true
csrfSpec.csrfTokenRepository(csrfTokenRepository)
csrfSpec
}
}
Our OIDC client is configured in Okta to allow both authorization code and refresh token flows.