java - 如何从 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 种可能的方法来获得结果:
使用注入
Principal
对象。对于 Spring OAuth2,它是用 class 实现的OAuth2Authentication
。您可以在此对象中找到大部分信息 - 在details
,userAuthentication
, 中storedRequest
。检查它,你会看到你需要什么。使用身份验证请求直接获取所有必需的参数:
服务方式:
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)));
- 在授权服务器上生成一个对象,并用一个类似的 restTemplate 响应它给客户端。这是一种不受欢迎的方法,但也可以实施。
推荐阅读
- php - 解析符号字符串对以构建 sql 的 WHERE 子句的条件表达式
- jenkins - 我正在尝试在 jenkins 上运行 selenium 脚本,但出现以下错误(我还附上了我要运行的脚本)
- python - 如何将抓取的数据添加到我的列表中,我无法打印“ranking_list”并且它不能为空
- mapbox - MapBox中的集群标记,如何“累积”不同的属性?
- java - 导入 com.google.android.gms.security.ProviderInstaller
- javascript - 如何在useEffect()中刷新signalR的连接ID?
- bash - 从执行 ssh 两级的 shell 脚本获取输出
- google-cloud-platform - GCP 负载均衡器 URL 映射将所有请求路由到默认后端服务,配置根据文档显示正确
- macos - 如何使用 AppleScript 及其脚本标签替换 Pages 中的单个占位符文本?
- reactjs - 仅在 React 中使用 ContextAPI 加载查找值一次