繁体   English   中英

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

[英]Get access token from Oauth2 rest api using java

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

Below is a sample CURL which i need to call using JAVA i am beginner in JAVA so not able to figure out how to do it however i can do it using shell script.

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 和学习的新手。

您可以使用很多库来帮助您从 Java 发出常规的 HTTP POST 请求,但由于您似乎需要发送纯text/plain正文内容 - 我建议您使用okhttp3 这是一个相当轻量级且易于使用 HTTP 客户端。

您需要将以下依赖项添加到您的 pom.xml,从https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp/4.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 等效依赖项声明。

这是一个完整的 class 说明如何使用 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 命令中向我提供详细的 output ,以便确定编码 - 但是试试这个,看看你得到了什么?

这是一个仅涉及 Spring 的解决方案,对 POST 请求使用 RestTemplate。

我发现当你使用curl -X POST -d 'key=data'时,curl 会添加 header content-type: application/x-www-form-urlencoded

此解决方案使用您指定的标头和正文设置 RestTemplate,并在与您描述的等效的 object 中捕获响应。

以下解决方案包含两个文件,您可以尝试将它们引入您的解决方案:

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 映射器使用它来捕获 object 中的响应,您可以轻松地从中读取结果。

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 建议的其他解决方案。

curl 是 HTTP 客户端。 更好的解决方案是使用 java 的 HTTP 客户端 API 来调用端点。 RestTemplate 是常见的 HTTP 客户端附带 spring 是您的最佳选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM