Oauth 2.0 org.springframework.web.client.RestTemplate-对的POST请求导致400(错误请求);调用错误处理程序
我希望开发一个Spring OAuth2RestTemplate代码,并从中获取参考 这里给出了两个建议,第一个建议使用ApacheOLTU对我来说非常好。现在,我希望开发第二个选项,即使用SpringOAuth2RestTemplate 我得到的错误是:-Oauth 2.0 org.springframework.web.client.RestTemplate-对的POST请求导致400(错误请求);调用错误处理程序,oauth-2.0,facebook-oauth,spring-security-oauth2,oauth2client,Oauth 2.0,Facebook Oauth,Spring Security Oauth2,Oauth2client,我希望开发一个Spring OAuth2RestTemplate代码,并从中获取参考 这里给出了两个建议,第一个建议使用ApacheOLTU对我来说非常好。现在,我希望开发第二个选项,即使用SpringOAuth2RestTemplate 我得到的错误是:- WARN : org.springframework.web.client.RestTemplate - POST request for "https://graph.facebook.com/oauth/access_token" re
WARN : org.springframework.web.client.RestTemplate - POST request for "https://graph.facebook.com/oauth/access_token" resulted in 400 (Bad Request); invoking error handler
Exception in thread "main" error="access_denied", error_description="Error requesting access token."
at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport.retrieveToken(OAuth2AccessTokenSupport.java:145)
at org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider.obtainAccessToken(ClientCredentialsAccessTokenProvider.java:44)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:142)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:118)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:105)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:564)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:529)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:329)
at com.apache.oltu.RestFacebookController.authenticate(RestFacebookController.java:46)
at com.apache.oltu.RestFacebookController.main(RestFacebookController.java:52)
Caused by: org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport$AccessTokenErrorHandler.handleError(OAuth2AccessTokenSupport.java:244)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:615)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:573)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:537)
at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport.retrieveToken(OAuth2AccessTokenSupport.java:137)
... 12 more
我试着调试这个应用程序好几个星期了,最后决定把它发布在stackoverflow.com上。下面是我开发的代码
import java.util.Arrays;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/restfacebook")
public class RestFacebookController {
private static final Logger logger = LoggerFactory.getLogger(RestFacebookController.class);
private String CLIENT_SECRET = "33b17e044ee6a4fa383f46ec6e28ea1d";
private String CLIENT_ID = "233668646673605";
@RequestMapping(value = "/auth", method = RequestMethod.GET)
public void authenticate() {
logger.debug("In a Authenticate() method");
ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setClientSecret(CLIENT_SECRET);
resourceDetails.setClientId(CLIENT_ID);
resourceDetails.setAccessTokenUri("https://graph.facebook.com/oauth/access_token");
resourceDetails.setScope(Arrays.asList("email,offline_access,user_about_me,user_birthday,read_friendlists"));
resourceDetails.setTokenName("code");
JSONObject request = new JSONObject();
request.put("resourceDetails", resourceDetails);
OAuth2RestTemplate oAuthRestTemplate = new OAuth2RestTemplate(resourceDetails);
HttpHeaders headers = new HttpHeaders();
headers.setContentType( MediaType.APPLICATION_JSON );
// Sample POST Method
HttpEntity<String> reqEntity = new HttpEntity<String>(resourceDetails.toString(), headers);
String postUri = "https://www.facebook.com/dialog/oauth";
String postResult = oAuthRestTemplate.postForObject(postUri, reqEntity, String.class);
System.out.println(postResult);
}
}
}
pom.xml:
<properties>
<org.springframework-version>4.1.5.RELEASE</org.springframework-version>
<org.aspectj-version>1.8.5</org.aspectj-version>
</properties>
<dependencies>
<!-- Spring Context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Web MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Module for providing OAuth2 support to Spring Security -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.7.RELEASE</version>
</dependency>
<!-- Apache Log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
</dependencies>
您可能需要为您的客户端设置身份验证方案Facebook可能仍然不接受规范建议的标头身份验证。例如
重定向RequiredException通常由筛选器处理。如果您有一个OAuth2ClientContextFilter,您永远不会看到它。这个示例和文档应该很容易理解。Dave-我不太确定是否需要修复重定向才能获得用户的批准。根据我的代码,目前我没有在代码中使用OAuth2ClientContextFilter,只是通过已经工作的RestTemplate执行简单的POST。您认为呢?我将按照您的建议尝试使用OAuth2ClientContextFilter。除非您的系统只有一个用户,否则您需要一个过滤器,假设它是一个webapp。我相信在文档和tonr样本中都是明确的。我不理解这个问题。您正在使用Spring MVC,因此您可能正在使用一个基于servlet的常规Web应用程序,对吗?您可能希望查看以下帖子:
Exception in thread "main" org.springframework.security.oauth2.client.resource.UserRedirectRequiredException: A redirect is required to get the users approval
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.getRedirectForAuthorization(AuthorizationCodeAccessTokenProvider.java:347)
at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:194)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:142)
at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:118)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.createRequest(OAuth2RestTemplate.java:105)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:564)
at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:529)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:329)
at com.apache.oltu.RestFacebookController.authenticate(RestFacebookController.java:48)
at com.apache.oltu.RestFacebookController.main(RestFacebookController.java:54)
<properties>
<org.springframework-version>4.1.5.RELEASE</org.springframework-version>
<org.aspectj-version>1.8.5</org.aspectj-version>
</properties>
<dependencies>
<!-- Spring Context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Web MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Module for providing OAuth2 support to Spring Security -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.0.7.RELEASE</version>
</dependency>
<!-- Apache Log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
</dependencies>
resourceDetails.setAuthenticationScheme(AuthenticationScheme.query);