Description
OAuth 2.0 Client should support a deployment topology where application instances are replicated and distributed across a cluster. This should be supported when using HttpSecurity.oauth2Login()
and/or HttpSecurity.oauth2Client()
, as well for the reactive counterpart, ServerHttpSecurity.oauth2Login()
and/or ServerHttpSecurity.oauth2Client()
.
This can be supported today by using Spring Session and providing a minor customization for OAuth 2.0 Client. Spring Session allows replacing the HttpSession
in the application container in a neutral way. For example, instead of using the application container's HttpSession
implementation, Spring Session can store session data to either Redis, JDBC or Hazelcast. This is key to enable application clustering since application instances do not depend on the underlying container's HttpSession
and instead retrieve session data from a remote/central backing store.
In order to enable application clustering for OAuth 2.0 Client, you need to configure Spring Session and ensure the HttpSession
implementations of AuthorizationRequestRepository<OAuth2AuthorizationRequest>
and OAuth2AuthorizedClientRepository
are configured.
The default AuthorizationRequestRepository<OAuth2AuthorizationRequest>
is HttpSessionOAuth2AuthorizationRequestRepository
, so there is no need to configure this further.
The default OAuth2AuthorizedClientRepository
is AuthenticatedPrincipalOAuth2AuthorizedClientRepository
, which is backed by an InMemoryOAuth2AuthorizedClientService
that stores OAuth2AuthorizedClient
in-memory. This default configuration will not work in a clustered environment unless you have Session affinity (sticky sessions) configured. To override the default configuration and ensure OAuth2AuthorizedClient
are stored in the backing HttpSession
, provide the following configuration:
@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository() {
return new HttpSessionOAuth2AuthorizedClientRepository();
}
The reactive counterpart:
@Bean
public ServerOAuth2AuthorizedClientRepository authorizedClientRepository() {
return new WebSessionServerOAuth2AuthorizedClientRepository();
}
The default serialization used by Spring Session is standard Java Serialization. However, if your requirements are to store session data in JSON format, this will be possible in the upcoming 5.3 release via #4886. To enable session data to be stored in JSON format when using Redis, add the following configuration (in addition to above):
@Bean
public RedisSerializer<Object> springSessionRedisSerializer() {
return new GenericJackson2JsonRedisSerializer(objectMapper());
}
private ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModules(SecurityJackson2Modules.getModules(getClass().getClassLoader()));
return mapper;
}
See the Spring Session Redis-JSON sample for further details on how to configure.