如何从 OAuth2 客户端应用中的授权服务器获取访问令牌响应的其他信息



访问令牌响应

{
"access_token": "fd515395-ab03-4cc5-9ba4-03c42bdfdf189b73",
"token_type": "bearer",
"refresh_token": "176ee948-ebdc-4d51-9768-08aa1dfdd081442",
"expires_in": 10799,
"scope": "user_info",
"instance_url": "https://xxxx.xxx.com/xx-xxx-service"
}

我已经尝试过如下,但没有运气

@RequestMapping("/securedPage")
public String securedPage( Model model, OAuth2AuthenticationToken authToken ) {
OAuth2AuthorizedClient client = clientService.loadAuthorizedClient( authToken.getAuthorizedClientRegistrationId(), authToken.getName() );
OAuth2AccessToken accessToken = client.getAccessToken();
System.out.println( accessToken.getTokenValue() );
System.out.println( accessToken.getExpiresAt() );
System.out.println( client.getPrincipalName() );
System.out.println( client.getRefreshToken().getTokenValue() );
// Get "instance_url" here
return "securedPage.html";
}

我看到了 3 种可能获得结果的方法:

  1. 使用注入Principal对象。对于 Spring OAuth2,它是通过类OAuth2Authentication实现的。您可以在此对象中找到大部分信息 - 在detailsuserAuthenticationstoredRequest中。检查它,你会看到你需要什么。

  2. 通过身份验证请求直接获取所有必需的参数:

服务方式:

var resourceDetails = ((OAuth2RestTemplate) restTemplate).getResource();
var headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setBasicAuth(resourceDetails.getClientId(), resourceDetails.getClientSecret());
var form = new LinkedMultiValueMap<String, String>();
form.add("grant_type", "password");
form.add("username", "<username>");
form.add("password", "<password>");
var request = new HttpEntity<>(form, headers);
var response = restTemplate.postForObject(resourceDetails.getAccessTokenUri(), request, LinkedHashMap.class);

对象response包含访问令牌响应中的所有参数。

一件事 - 您需要使用特定的restTemplate,如下所示:

var resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setClientId("<clientId>");
resourceDetails.setClientSecret("<clientSecret>");
resourceDetails.setAccessTokenUri("<accessTokenUri>");
resourceDetails.setScope("<scopes>");
resourceDetails.setAuthenticationScheme(AuthenticationScheme.header);
resourceDetails.setGrantType("client_credentials");
var restTemplate = new OAuth2RestTemplate(resourceDetails, new DefaultOAuth2ClientContext());
var requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setConnectTimeout(10000);
requestFactory.setConnectionRequestTimeout(10000);
requestFactory.setReadTimeout(10000);
restTemplate.setRequestFactory(requestFactory);
var tokenProvider = new ClientCredentialsAccessTokenProvider();
tokenProvider.setRequestFactory(requestFactory);
restTemplate.setAccessTokenProvider(new AccessTokenProviderChain(Arrays.<AccessTokenProvider>asList(
new AuthorizationCodeAccessTokenProvider(), new ImplicitAccessTokenProvider(),
new ResourceOwnerPasswordAccessTokenProvider(), tokenProvider)));
  1. 在授权服务器上生成一个对象,并使用类似的 restTemplate 响应客户端。这是一种不可取的方法,但也可以实现。

最新更新