我试图使用Spring Secruity的OAuth API从外部发布的API获取访问令牌。
这个curl命令有效(它的内容就是我获取访问令牌所需的全部内容):
curl -X POST \
https://api.app.com/v1/oauth/token \
-H 'content-type: application/x-www-form-urlencoded' \
-d'grant_type=client_credentials&client_id=bcfrtew123&client_secret=Y67493012'
运行此curl命令后,能够从外部服务获取访问令牌。
使用Spring Security OAuth API时:
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
像这样设置我的Spring MVC Controller方法:
@RequestMapping(value = "/getAccessToken", method = RequestMethod.POST, consumes="application/x-www-form-urlencoded")
public OAuth2AccessToken getAccessToken(@RequestParam(value="client_id", required=true) String clientId, @RequestParam(value="client_secret", required=true) String clientSecret) throws Exception {
String tokenUri = "https://api.app.com/v1/oauth/token";
ResourceOwnerPasswordResourceDetails resourceDetails = new ResourceOwnerPasswordResourceDetails();
resourceDetails.setAccessTokenUri(tokenUri);
resourceDetails.setClientId(clientId);
resourceDetails.setClientSecret(clientSecret);
resourceDetails.setGrantType("client_credentials");
resourceDetails.setScope(Arrays.asList("read", "write"));
DefaultOAuth2ClientContext clientContext = new DefaultOAuth2ClientContext();
oauth2RestTemplate = new OAuth2RestTemplate(resourceDetails, clientContext);
OAuth2AccessToken token = oauth2RestTemplate.getAccessToken();
return token;
}
当我从本地tomcat实例调用getAccessToken调用时:
access_denied
error_description=Unable to obtain a new access token for resource 'null'.
The provider manager is not configured to support it.
问题(S):
(请注意,内容类型必须是“application / x-www-form-urlencoded”......)
这是我用的:
@Bean
public RestTemplate oAuthRestTemplate() {
ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setId("1");
resourceDetails.setClientId(oAuth2ClientId);
resourceDetails.setClientSecret(oAuth2ClientSecret);
resourceDetails.setAccessTokenUri(accessTokenUri);
OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, oauth2ClientContext);
return restTemplate;
}
正确的标题将设置为bij框架,但用户名/密码将是base64编码为授权标头(基本认证)。这是client_credentials授权的OAuth2规范。
检查api是否支持规范:
curl -X POST \
'https://api.app.com/v1/oauth/token' \
-i -u 'client:secret' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials'
如果您需要将用户名和密码作为数据而不是授权标题发送,您可以添加resourceDetails.setAuthenticationScheme(AuthenticationScheme.form);
这应该将de username&password设置为数据
真正的原因是,您使用ResourceOwnerPasswordResourceDetails
进行"client_credentials"
访问令牌请求。我们不能互换ResourceOwnerPasswordResourceDetails
和ClientCredentialsResourceDetails
。
在ClientCredentialsResourceDetails
你需要设置AccessTokenUri, ClientId, ClientSecret
和grantType
。在ResourceOwnerPasswordResourceDetails
,你需要提供Username and Password
以及AccessTokenUri, ClientId, ClientSecret
和GrantType
。
(有些authserver会接受没有password
的username and password
令牌请求..但我会说这是错误的)
这可能是因为服务器无法识别您发布到该特定网址的内容类型。在您的CURL请求中,尝试使用http标头为自定义控制器包含'content-type:application / x-www-form-urlencoded'。
您还没有为resourceDetails设置用户名和密码。 resourceDetails.setUserName( “用户”); resourceDetails.setUserName( “密码”);
如果那些不起作用尝试提取编码与application / x-www-form-urlencoded的请求并通过RestTemplate将其作为字符串传递,您可以获取令牌。
如果您需要其他支持,请告诉我。
尝试下面给出令牌和字符串响应的代码。