Java Spring Security OAuth-未为空资源配置提供程序管理器
我试图使用SpringSecruity的OAuthAPI从外部发布的API获取访问令牌 这个curl命令有效(它的内容就是我获取访问令牌所需的全部内容): 运行此curl命令后,我能够从外部服务获取访问令牌 使用Spring Security OAuth API时:Java Spring Security OAuth-未为空资源配置提供程序管理器,java,spring-mvc,curl,oauth,spring-security-oauth2,Java,Spring Mvc,Curl,Oauth,Spring Security Oauth2,我试图使用SpringSecruity的OAuthAPI从外部发布的API获取访问令牌 这个curl命令有效(它的内容就是我获取访问令牌所需的全部内容): 运行此curl命令后,我能够从外部服务获取访问令牌 使用Spring Security OAuth API时: <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>sprin
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
从本地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.
问题:
这可能是错误的,因为服务器无法识别您发布到该特定url的内容类型。 在CURL请求中,尝试使用http头为自定义conrtroller包含“content-type:application/x-www-form-urlencoded”。 此外,您还没有为resourceDetails设置用户名和密码。 resourceDetails.setUserName(“用户”); resourceDetails.setUserName(“密码”) 如果这些都不起作用,请尝试提取使用application/x-www-form-urlencoded编码的请求,并通过restemplate将其作为字符串传递,您就可以获得令牌 如果你需要额外的支持,请告诉我 请尝试下面的代码,该代码提供令牌as和字符串响应 这就是我使用的:
@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;
}
框架将设置正确的头,但用户名/密码将以base64编码作为授权头(基本身份验证)。这是用于授予客户机\u凭据的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
进行“客户端凭据”
访问令牌请求。我们无法交换ResourceOwnerPasswordResourceDetails
和ClientCredentialsResourceDetails
在ClientCredentialsResourceDetails
中,您需要设置AccessTokenUri、ClientId、ClientSecret
和grantType
。
在ResourceOwnerPasswordResourceDetails
中,您需要提供用户名和密码
以及AccessTokenUri、ClientId、ClientSecret
和GrantType
(有些authserver确实接受密码
令牌请求,但没有用户名和密码
。但我认为这是错误的)
请参阅:谢谢您的回复!既然这是OAuth2RestTemplate而不是RestTemplate,我该如何设置它?另外,如果您查看curl,没有设置用户名/密码。那么您剩下的选项是将内容类型包括为application/x-www-form-urlencodedproblem是我使用的是restemplate,您使用的是oauth2restemplate,您不能设置任何Http头,除非您将其更改为restemplate。如果你能找到一个方法来修改,我可以提供代码。JavaDoc说OAuth2RestTemplate是RestTemplate的一个子类:我已经在我的答案中添加了另一个新代码。对我来说,它是
setId(“1”)
。设置后它就开始工作了。setId(“1”)的意义是什么?从文档中:获取这些受保护资源详细信息的唯一标识符。
@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;
}
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'