|
10 | 10 | package org.eclipse.hawkbit.ui.simple.security;
|
11 | 11 |
|
12 | 12 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
| 13 | +import org.springframework.security.core.context.SecurityContext; |
| 14 | +import org.springframework.security.core.context.SecurityContextHolder; |
13 | 15 | import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
|
14 | 16 | import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
|
15 | 17 | import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
|
16 | 18 | import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
|
17 | 19 | import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
18 |
| -import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient; |
19 |
| -import org.springframework.security.oauth2.client.endpoint.OAuth2RefreshTokenGrantRequest; |
20 |
| -import org.springframework.security.oauth2.client.endpoint.RestClientRefreshTokenTokenResponseClient; |
21 |
| -import org.springframework.security.oauth2.client.registration.ClientRegistration; |
22 |
| -import org.springframework.security.oauth2.core.OAuth2AccessToken; |
23 |
| -import org.springframework.security.oauth2.core.OAuth2RefreshToken; |
24 |
| -import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; |
25 | 20 | import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
|
26 | 21 | import org.springframework.stereotype.Component;
|
27 | 22 |
|
28 |
| -import java.util.Optional; |
29 |
| - |
30 | 23 | @Component
|
31 | 24 | @ConditionalOnProperty(prefix = "hawkbit.server.security.oauth2.client", name = "enabled")
|
32 | 25 | public class OAuth2TokenManager {
|
33 | 26 |
|
34 | 27 | private final OAuth2AuthorizedClientService clientService;
|
35 | 28 | private final OAuth2AuthorizedClientManager clientManager;
|
36 |
| - private final OAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> tokenResponseClient; |
37 | 29 |
|
38 | 30 | OAuth2TokenManager(
|
39 | 31 | final OAuth2AuthorizedClientService clientService,
|
40 | 32 | final OAuth2AuthorizedClientManager clientManager
|
41 | 33 | ) {
|
42 | 34 | this.clientService = clientService;
|
43 | 35 | this.clientManager = clientManager;
|
44 |
| - this.tokenResponseClient = new RestClientRefreshTokenTokenResponseClient(); |
45 | 36 | }
|
46 | 37 |
|
47 | 38 | public String getToken(final OAuth2AuthenticationToken authentication) {
|
48 |
| - return Optional.ofNullable(authorizedToken(authentication)).orElse( |
49 |
| - ((DefaultOidcUser) authentication.getPrincipal()).getIdToken().getTokenValue() |
50 |
| - ); |
51 |
| - } |
52 |
| - |
53 |
| - /** |
54 |
| - * Tries to refresh the id token if it is expired and adds it to the request. |
55 |
| - */ |
56 |
| - private String authorizedToken(final OAuth2AuthenticationToken authentication) { |
| 39 | + final String currentToken = ((DefaultOidcUser) authentication.getPrincipal()).getIdToken().getTokenValue(); |
57 | 40 | String registrationId = authentication.getAuthorizedClientRegistrationId();
|
58 |
| - OAuth2AuthorizeRequest request = OAuth2AuthorizeRequest.withClientRegistrationId(registrationId).principal(authentication).build(); |
59 | 41 |
|
60 | 42 | // This ensures that there is a client already, otherwise we won't be able to call the manager for authorization
|
61 | 43 | OAuth2AuthorizedClient authorizedClient = clientService.loadAuthorizedClient(registrationId, authentication.getName());
|
62 |
| - if (authorizedClient == null) return null; |
| 44 | + if (authorizedClient == null) return currentToken; |
63 | 45 |
|
64 | 46 | // Will ensure that the token is refreshed if needed; do not rely on it being not null as it won't be available
|
65 | 47 | // during the first calls made to get the rights and generate the authorities
|
66 |
| - OAuth2AuthorizedClient refreshClient = clientManager.authorize(request); |
67 |
| - if (refreshClient == null) return null; |
68 |
| - |
69 |
| - // A small trick to refresh the token if it is expired; the current spring version does not refresh the ID Token when the Access Token is refreshed |
70 |
| - // This won't be necessary after Spring Security 6.5; cf. https://github.com/spring-projects/spring-security/pull/16589 |
71 |
| - OAuth2AccessToken accessToken = refreshClient.getAccessToken(); |
72 |
| - OAuth2RefreshToken refreshToken = refreshClient.getRefreshToken(); |
73 |
| - ClientRegistration clientRegistration = refreshClient.getClientRegistration(); |
74 |
| - // if this is null, please request it via the scopes |
75 |
| - if (refreshToken == null) return null; |
| 48 | + OAuth2AuthorizeRequest request = OAuth2AuthorizeRequest.withClientRegistrationId(registrationId).principal(authentication).build(); |
| 49 | + // since Spring Security 6.5 this will trigger a refresh of the id token |
| 50 | + authorizedClient = clientManager.authorize(request); |
| 51 | + if (authorizedClient == null) return currentToken; |
76 | 52 |
|
77 |
| - OAuth2RefreshTokenGrantRequest refreshTokenGrantRequest = new OAuth2RefreshTokenGrantRequest( |
78 |
| - clientRegistration, accessToken, refreshToken); |
79 |
| - OAuth2AccessTokenResponse response = tokenResponseClient.getTokenResponse(refreshTokenGrantRequest); |
80 |
| - return (String) response.getAdditionalParameters().get("id_token"); |
| 53 | + // we need to fetch the newly created context containing the matching token |
| 54 | + SecurityContext securityContext = SecurityContextHolder.getContext(); |
| 55 | + return ((DefaultOidcUser) securityContext.getAuthentication().getPrincipal()).getIdToken().getTokenValue(); |
81 | 56 | }
|
82 | 57 | }
|
0 commit comments