使用java从Oauth2 rest api获取访问令牌。

问题描述 投票:0回答:1

我需要调用Oauth2 ResT API服务从JSON文件中获取访问令牌和expire_in值。

以下是我需要用JAVA调用的CURL示例,我是JAVA初学者,所以不知道怎么做,但是我可以用shell脚本来做。

curl -u 'ClientId:Clientaccesskey' https://oauth2.url/oauth/token -X POST -d 'response_type=token&client_id=ClientId&username=user&password=userpassword&scope=process&grant_type=password'

上面的curl命令得到的JSON样本 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

{"access_token":"accessTokentobefetched","token_type":"bearer","refresh_token":"refreshToken","expires_in":7199,"scope":"process","jti":"somehexadecimalvaliu"}

在shell脚本中,我们可以使用AWK命令和其他命令来获取访问令牌和其他字段的值,所以我需要在JAVA中调用这个CURL命令,从JSON文件中获取访问令牌和其他键的值。

所以我需要在JAVA中调用这个CURL命令,从JSON文件中获取访问令牌和其他键值。

由于我是一个新的JAVA学习者,欢迎任何能帮助我开始这项工作的帮助。

java spring-boot maven
1个回答
0
投票

你没有明确说明这个标记将在什么情况下使用,但我假设你正在创建一个需要访问资源服务器的客户端应用程序。

似乎你需要访问授权服务器返回的值。

你可能会发现像这样的库很有意义。oauth2-essentials. 以下是他们的例子。

初始化客户机

// Create HttpRequestExecutor to execute HTTP requests
// Any other HttpRequestExecutor implementaion will do
HttpRequestExecutor executor = new HttpUrlConnectionExecutor();

// Create OAuth2 provider
OAuth2AuthorizationProvider provider = new BasicOAuth2AuthorizationProvider(
    URI.create("http://example.com/auth"),
    URI.create("http://example.com/token"),
    new Duration(1,0,3600) /* default expiration time in case the server doesn't return any */);

// Create OAuth2 client credentials
OAuth2ClientCredentials credentials = new BasicOAuth2ClientCredentials(
    "client-id", "client-password");

// Create OAuth2 client
OAuth2Client client = new BasicOAuth2Client(
    provider,
    credentials,
    new LazyUri(new Precoded("http://localhost")) /* Redirect URL */);

授权代码 拨款

// Start an interactive Authorization Code Grant
OAuth2InteractiveGrant grant = new AuthorizationCodeGrant(
    client, new BasicScope("scope"));

// Get the authorization URL and open it in a WebView
URI authorizationUrl = grant.authorizationUrl();

// Open the URL in a WebView and wait for the redirect to the redirect URL
// After the redirect, feed the URL to the grant to retrieve the access token
OAuth2AccessToken token = grant.withRedirect(redirectUrl).accessToken(executor);

来自 [OAuth2AccessToken](https://github.com/dmfs/oauth2-essentials/blob/master/src/main/java/org/dmfs/oauth2/client/OAuth2AccessToken.java)然后你可以使用以下方法来访问token的内容。

  • public CharSequence token.accessToken()
  • public CharSequence tokenType()
  • public boolean hasRefreshToken()
  • public CharSequence refreshToken()
  • public DateTime expirationDate()
  • public OAuth2Scope scope()

访问此链接查看如何将此依赖关系添加到你的mavengradle项目中。

OAuth2 Essentials " 0.18 - 最新的版本是从2019年9月开始的,在写这篇文章的时候是0.18版本。

然而,如果你发现自己在Spring应用中,有很好的支持。而且,你将永远不会真正需要处理令牌本身。考虑一下Spring是否适合你的应用--看看这个。Spring安全OAuth. 注意 SPring安全OAuth 包最近已经被去掉了 -- 网上有很多文档现在已经和它一起被去掉了,请查看迁移指南了解更多信息。

你可能还想看看其他可用的库来帮助你使用oauth2,包括服务器端和客户端,这里有一个很好的列表。

Java的OAuth库


0
投票

有相当多的库可以用来帮助你从Java中发出一个常规的HTTP POST请求,但由于你似乎需要发送普通的 text/plain 体含量--我建议你用 okhttp3. 这是一个相当轻量级且易于使用的HTTP客户端。

您将需要在您的pom.xml中添加以下依赖关系,这些依赖关系是从 https:/mvnrepository.comartifactcom.squareup.okhttp3okhttp4.7.2。:

        <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.7.2</version>
        </dependency>

如果你使用的是gradle,只要访问前面提到的URL,就可以得到gradle对应的依赖声明。

这里是一个完整的类,说明如何使用okhttp3客户端来执行POST请求,并提取返回值。这个例子希望你使用的是 spring-boot-starter-web 依赖关系 (这将包括本例中使用的 jackson 和 tomcat 库)。

package com.example.demo;

import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Component
public class TokenRequester {

    public String getAccessToken() throws IOException {
        // Create a new HTTP client
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        // Create the request body
        MediaType mediaType = MediaType.parse("text/plain");
        RequestBody body = RequestBody.create("response_type=token&client_id=ClientId&username=user&password=userpassword&scope=process&grant_type=password", mediaType);
        // Build the request object, with method, headers
        Request request = new Request.Builder()
                .url("https://oauth2.url/oauth/token")
                .method("POST", body)
                .addHeader("Authorization", createAuthHeaderString("ClientId", "Clientaccesskey"))
                .addHeader("Content-Type", "text/plain")
                .build();
        // Perform the request, this potentially throws an IOException
        Response response = client.newCall(request).execute();
        // Read the body of the response into a hashmap
        Map<String,Object> responseMap = new ObjectMapper().
                readValue(response.body().byteStream(), HashMap.class);
        // Read the value of the "access_token" key from the hashmap 
        String accessToken = (String)responseMap.get("access_token");
        // Return the access_token value
        return accessToken;
    }

    // Just a helper metod to create the basic auth header
    private String createAuthHeaderString(String username, String password) {
        String auth = username + ":" + password;
        byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.US_ASCII));
        String authHeader = "Basic " + new String(encodedAuth);
        return authHeader;
    }
}

你可能需要调整一些东西。我可以要求你提供curl命令的详细输出,以便确定编码--但试试这个,看看你能得到什么?


0
投票

下面是一个只涉及Spring的解决方案,在POST请求中使用RestTemplate。

我发现,当你使用 curl -X POST -d 'key=data',curl将添加头 content-type: application/x-www-form-urlencoded所以这里的解决方案也会做同样的事情。

这个解决方案用你指定的头部和主体设置了RestTemplate,并在一个相当于你描述的对象中捕获响应。

下面的解决方案由两个文件组成,您可以尝试将其引入到您的解决方案中。

RestTemplateTokenRequester.java。

package com.example.demo;

import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;

@Component
public class RestTemplateTokenRequester {

    public TokenResponse requestAccessToken() {
        // Create a RestTemplate to describe the request
        RestTemplate restTemplate = new RestTemplate();

        // Specify the http headers that we want to attach to the request
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("Authorization", createAuthHeaderString("ClientId", "Clientaccesskey"));

        // Create a map of the key/value pairs that we want to supply in the body of the request
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("response_type","token");
        map.add("client_id","ClientId");
        map.add("username","user");
        map.add("password","userpassword");
        map.add("scope","process");
        map.add("grant_type","password");

        // Create an HttpEntity object, wrapping the body and headers of the request
        HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(map, headers);

        // Execute the request, as a POSt, and expecting a TokenResponse object in return
        ResponseEntity<TokenResponse> response =
                restTemplate.exchange("https://oauth2.url/oauth/token",
                        HttpMethod.POST,
                        entity,
                        TokenResponse.class);

        return response.getBody();
    }

    // Just a helper metod to create the basic auth header
    private String createAuthHeaderString(String username, String password) {
        String auth = username + ":" + password;
        byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.US_ASCII));
        String authHeader = "Basic " + new String(encodedAuth);
        return authHeader;
    }
}

TokenResponse.java

这是一个简单的POJO,被jackson mapper使用,用来捕捉响应的对象,你可以很容易的读取结果。

package com.example.demo;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonIgnoreProperties(ignoreUnknown = true)
public class TokenResponse {
    @JsonProperty("access_token")
    private String accessToken;
    @JsonProperty("token_type")
    private String tokenType;
    @JsonProperty("refresh_token")
    private String refreshToken;
    @JsonProperty("expires_in")
    private Integer expiresIn;
    @JsonProperty("scope")
    private String scope;
    @JsonProperty("jti")
    private String jti;
}

我希望这个解决方案能帮到你--比起我用okhttp3建议的其他解决方案,我更喜欢它。


0
投票

curl是一个HTTP客户端.更好的解决方案是使用HTTP客户端API的java来调用端点.RestTemplate是常见的HTTP客户端与spring一起,它是你最好的选择。

© www.soinside.com 2019 - 2024. All rights reserved.