使用2脚Oauth 2.0和Apache OauthClient访问令牌

时间:2014-05-06 04:52:12

标签: apache oauth-2.0

我正在努力让2腿的Oauth 2工作。我正在尝试模仿此CURL调用以获取访问令牌:

curl -u CLIENT_ID:CLIENT_SECRET https://mydomain.com/token -d "grant_type=client_credentials"

我正在尝试使用Apache Oltu在Java中执行相同的操作:

<dependency>
    <groupId>org.apache.oltu.oauth2</groupId>
    <artifactId>org.apache.oltu.oauth2.client</artifactId>
    <version>1.0.0</version>
</dependency>

这是我正在使用的Java代码:

OAuthClientRequest request = OAuthClientRequest
            .tokenLocation("https://mydomain.com/token")
            .setGrantType(GrantType.CLIENT_CREDENTIALS)
            .setClientId(CLIENT_ID)
            .setClientSecret(CLIENT_SECRET)
            .buildBodyMessage();


//create OAuth client that uses custom http client under the hood
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());

OAuthJSONAccessTokenResponse oAuthResponse = oAuthClient.accessToken(request, OAuthJSONAccessTokenResponse.class);

CURL命令工作正常,但Java代码会出现此错误:

OAuthProblemException{error='invalid_request', description='Must include a basic access authentication header.', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}

我尝试使用标题邮件构建:

.buildHeaderMessage();

相反,但它给出了:

OAuthProblemException{error='invalid_request', description='Must specify grant_type field.', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}

任何建议都表示赞赏。我希望这很简单。

2 个答案:

答案 0 :(得分:1)

我放弃了Apache Oltu Oauth并提出了两种替代解决方案。后者是首选。

解决方案1:低级别HTTP呼叫

在我第一次尝试时,我回到了基础并使用了HttpClient库。

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.3.3</version>
</dependency>

我可以使用以下代码获取Oauth访问令牌:

HttpPost request = new HttpPost("https://mydomain.com/token");
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
urlParameters.add(new BasicNameValuePair("grant_type", "client_credentials"));
request.setEntity(new UrlEncodedFormEntity(urlParameters)); 

String auth = CLIENT_ID + ":" + CLIENT_SECRET;
byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII")));
String authHeader = "Basic " + new String(encodedAuth);
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);

HttpClient client = HttpClientBuilder.create().build();
HttpResponse response = client.execute(request);
System.out.println("Oauth Access Token" + EntityUtils.toString(response.getEntity()));

解决方案2:Spring Oauth2 RestTemplate

我怀疑必须有更好的方法来做Two Legged Oauth 2.0并很高兴找到Spring Oauth2框架

<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    <version>1.0.5.RELEASE</version>
</dependency>

这会产生更简单的代码,并为后续的REST调用提供框架。这段代码可以使用杰克逊来清理,但我决定保持简单。

String CLIENT_SECRET = "xxxx";
String CLIENT_ID = "yyyy";

ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setClientSecret(CLIENT_SECRET);
resourceDetails.setClientId(CLIENT_ID);
resourceDetails.setAccessTokenUri("https://mydomain.com/token");

OAuth2RestTemplate oAuthRestTemplate = new OAuth2RestTemplate(resourceDetails);

HttpHeaders headers = new HttpHeaders();
headers.setContentType( MediaType.APPLICATION_JSON );

// Sample POST Method
String postJson = "{\"phone\":\"15554443333\", \"ip\":\"67.666.666.666\"}";
HttpEntity<String> reqEntity = new HttpEntity<String>(postJson, headers);
String postUri = "https://mydomain.com/v1.0/phone.json";
String postResult = oAuthRestTemplate.postForObject(postUri, reqEntity, String.class);
System.out.println(postResult);

// Sample GET method
String getUri = "https://mydomain.com/v1.0/phone.json?phone=15554443333";
String result = oAuthRestTemplate.getForObject( getUri, String.class);
System.out.println(result);

答案 1 :(得分:0)

最近,我试图找到一个OAuth2 java库来获取“client_credential”类型的accesstoken。以下是我所拥有的,似乎它确实有效。

@Test
public void getAccessTokenViaApacheOltuOAuthClient() {
    try{

        OAuthClient client = new OAuthClient(new URLConnectionClient());

        OAuthClientRequest request =
                OAuthClientRequest.tokenLocation(TOKEN_REQUEST_URL)
                        .setGrantType(GrantType.CLIENT_CREDENTIALS)
                        .setClientId(CLIENT_ID)
                        .setClientSecret(CLIENT_SECRET)
                        .setScope(StringUtils.join(TEST_SCOPES, " ")) //if you have scope
                        .buildBodyMessage();

        String token =
                client.accessToken(request, "POST", OAuthJSONAccessTokenResponse.class)
                        .getAccessToken();

        System.out.println(token);
        assertTrue( token != null);

    } catch (Exception e) {
        e.printStackTrace();
    }
}