代码之家  ›  专栏  ›  技术社区  ›  mradul

使用java从OAuth2RESTAPI获取访问令牌

  •  0
  • mradul  · 技术社区  · 4 年前

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

    下面是一个示例CURL,我需要使用JAVA调用它。我是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文件中获取access token和其他键的值。

    0 回复  |  直到 4 年前
        1
  •  1
  •   Andreas Lorenzen    4 年前

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

    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等价的依赖关系声明。

    下面是一个完整的类,它演示了如何使用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命令的详细输出,以确保编码的正确性—但是请尝试一下,看看您得到了什么?

        2
  •  1
  •   Andreas Lorenzen    4 年前

    这里有一个只涉及Spring的解决方案,使用rest模板处理POST请求。

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

    此解决方案使用您指定的头和主体设置restemplate,并在与您描述的对象等效的对象中捕获响应。

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

    雷斯特mplateTokenRequester.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;
        }
    }
    

    令牌响应.java

    这只是jackson映射器使用的POJO,用于捕获对象中的响应,您可以轻松地从中读取结果。

    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;
    }
    

        3
  •  0
  •   Ali Dahaghin    4 年前

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