问题
My project uses redis session with springboot session and spring security 5.1.10. I just migrated the old oauth2 implementation. Before, when I restarted the app I still had the access_token and refresh_token. With this implementation the user is logged in, but I loose the AuthorizedClients so loadAuthorizedClient function returns null after restarting. Also in production we have many containers with the same app. Is there any springboot stardard way to achieve this? like register some bean or something.
application.yml
...
session:
store-type: redis
redis:
namespace: spring:session:${spring.application.name}
redis:
host: ${redissession.host}
password: ${redissession.password}
port: ${redissession.port}
security:
oauth2:
client:
registration:
biocryptology:
provider: example
client-id: client
client-secret: xxx
client-authentication-method: basic
authorization-grant-type: authorization_code
redirect-uri-template: "{baseUrl}/login"
scope:
- openid
provider:
example:
issuer-uri: https://....
...
Controller.java
@Autowired
private OAuth2AuthorizedClientService clientService;
@GetMapping("/user")
public String getOidcUserPrincipal() throws InvalidSessionException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication.getPrincipal() instanceof OidcUser)) {
throw new InvalidSessionException();
}
OidcUser principal = ((OidcUser) authentication.getPrincipal());
LOG.info("oidc: {}", principal.getName());
OAuth2AuthenticationToken oauth2Token = (OAuth2AuthenticationToken) authentication;
LOG.info("authentication: {}", oauth2Token);
OAuth2AuthorizedClient client = clientService
.loadAuthorizedClient(oauth2Token.getAuthorizedClientRegistrationId(), authentication.getName());
LOG.info("client: {}", client);
return "logged";
}
The goal is getting the access_token and refresh_token across containers, any other way without OAuth2AuthorizedClientService maybe?
EDIT:
<!-- Spring -->
<spring-cloud.version>Greenwich.SR5</spring-cloud.version>
回答1:
Registering a bean did the trick, it saves it in session, but then OAuth2AuthorizedClientService
breaks down for every case and needs a workaround searching in session directly or using OAuth2AuthorizedClientRepository
autowired:
@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository() {
return new HttpSessionOAuth2AuthorizedClientRepository();
}
controller.java
@Autowired
private OAuth2AuthorizedClientRepository clientRepository;
@GetMapping("/user")
public Map<String, Object> getOidcUserPrincipal(HttpServletRequest request) throws InvalidSessionException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication.getPrincipal() instanceof OidcUser)) {
throw new InvalidSessionException();
}
OidcUser principal = ((OidcUser) authentication.getPrincipal());
OAuth2AuthorizedClient client = clientRepository
.loadAuthorizedClient(oauth2Token.getAuthorizedClientRegistrationId(), authentication, request);
LOG.info("client: {}", client);
if (Objects.nonNull(client)) {
String token = client.getAccessToken().getTokenValue();
String refreshtoken = client.getRefreshToken().getTokenValue();
LOG.info("token: {} {}", token, refreshtoken);
}
return principal.getClaims();
}
来源:https://stackoverflow.com/questions/61893795/how-to-persist-oauth2authorizedclient-in-redis-session