Java中的API Chorus Pro Oauth2身份验证

dfuffjeb  于 2023-02-28  发布在  Java
关注(0)|答案(2)|浏览(133)

我在https://developer.aife.economie.gouv.fr/网站上创建了一个帐户,我想在沙盒上尝试API。为此,已生成一个应用程序
对于这个应用程序,我获得了API密钥和OAuth2凭据。以下是我以前的API密钥。

通过阅读文档,我了解了以下身份验证入口点

我的目标是通过身份验证并获得一个auth令牌来使用这个API。

package com.oauth.app;
    
import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.URLConnectionClient;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

public class OAuthApp {
    /**
     * URL for requesting OAuth access tokens.
     */
    private static final String TOKEN_REQUEST_URL =
            "https://sandbox-oauth.aife.economie.gouv.fr/api/oauth/token";

    /**
     * Client ID of your client credential.  Change this to match whatever credential you have created.
     */
    private static final String CLIENT_ID =
            "1f80aa43-e12f-4e1c-ad42-87ec16baf060";

    /**
     * Client secret of your client credential.  Change this to match whatever credential you have created.
     */
    private static final String CLIENT_SECRET =
            "a232af0e-513e-4a64-9977-410d237dc421";

    /**
     * Account on which you want to request a resource. Change this to match the account you want to
     * retrieve resources on.
     */
    private static final String ACCOUNT_ID =
            "a232af0e-513e-4a64-9977-410d237dc421";
    
    /**
     * Request a fresh access token using the given client ID, client secret, and token request URL,
     * then request the resource at the given resource URL using that access token, and get the resource
     * content.  If an exception is thrown, print the stack trace instead.
     *
     * @param args Command line arguments are ignored.
     */
    public static void main(String[] args) {
        try {
            OAuthClient client = new OAuthClient(new URLConnectionClient());
            System.out.println("OAuthClient " + client.toString());

            OAuthClientRequest request =
                    OAuthClientRequest.tokenLocation(TOKEN_REQUEST_URL)
                            .setGrantType(GrantType.CLIENT_CREDENTIALS)
                            .setClientId(CLIENT_ID)
                            .setClientSecret(CLIENT_SECRET)
                            // .setScope() here if you want to set the token scope
                            .buildQueryMessage();
            request.addHeader("Accept", "application/json");
            // request.addHeader("Content-Type", "application/json");
            // request.addHeader("Authorization", base64EncodedBasicAuthentication());

            System.out.println("OAuthClientRequest body\n\t " + request.getBody());
            System.out.println("OAuthClientRequest headers\n\t " + request.getHeaders());
            System.out.println("OAuthClientRequest locationUri\n\t " + request.getLocationUri());

            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            }};

            // Install the all-trusting trust manager
            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            } catch (Exception e) {
                e.printStackTrace();
            }

            String token = client.accessToken(
                    request,
                    OAuth.HttpMethod.GET,
                    OAuthJSONAccessTokenResponse.class).getAccessToken();    
        } catch (OAuthSystemException | OAuthProblemException e) {
            e.printStackTrace();
        }
    }
}

我在我的控制台中获得以下信息:

OAuthClient org.apache.oltu.oauth2.client.OAuthClient@7e0ea639
OAuthClientRequest body
     null
OAuthClientRequest headers
     {Accept=application/json, Content-Type=application/json}
OAuthClientRequest locationUri
     https://sandbox-oauth.aife.economie.gouv.fr/api/oauth/token?grant_type=client_credentials&client_secret=a232af0e-513e-4a64-9977-410d237dc421&client_id=42b214ec-7eaf-4f37-aeb5-ae91057a0e27
OAuthProblemException{error='unsupported_response_type', description='Invalid response! Response body is not application/json encoded', uri='null', state='null', scope='null', redirectUri='null', responseStatus=0, parameters={}}
    at org.apache.oltu.oauth2.common.exception.OAuthProblemException.error(OAuthProblemException.java:63)
    at org.apache.oltu.oauth2.client.response.OAuthJSONAccessTokenResponse.setBody(OAuthJSONAccessTokenResponse.java:76)
    at org.apache.oltu.oauth2.client.response.OAuthClientResponse.init(OAuthClientResponse.java:92)
    at org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse.init(OAuthAccessTokenResponse.java:65)
    at org.apache.oltu.oauth2.client.response.OAuthClientResponse.init(OAuthClientResponse.java:101)
    at org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse.init(OAuthAccessTokenResponse.java:60)
    at org.apache.oltu.oauth2.client.response.OAuthClientResponse.init(OAuthClientResponse.java:120)
    at org.apache.oltu.oauth2.client.response.OAuthClientResponseFactory.createCustomResponse(OAuthClientResponseFactory.java:82)
    at org.apache.oltu.oauth2.client.URLConnectionClient.execute(URLConnectionClient.java:111)
    at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:65)
    at com.oauth.app.OAuthApp.main(OAuthApp.java:101)

我收到此错误消息:
OAuthProblemException{错误=“不支持的响应类型”,描述=“无效响应!响应正文不是应用程序/json编码的”
我还尝试使用curl调用API:

curl –k –H "content-type :application/x-www-form-urlencoded" –d "grant_type=client_credentials&client_id=42b214ec-7eaf-4f37-aeb5-ae91057a0e27&client_secret=a232af0e-513e-4a64-9977-410d237dc421&scope=openid" –X POST https://sandbox-oauth.aife.finances.rie.gouv.fr/api/oauth/token

curl: (6) Could not resolve host: -k
curl: (6) Could not resolve host: -H
curl: (3) Port number ended with 'a'
curl: (6) Could not resolve host: -d
curl: (6) Could not resolve host: grant_type=client_credentials&client_id=42b214ec-7eaf-4f37-aeb5-ae91057a0e27&client_secret=a232af0e-513e-4a64-9977-410d237dc421&scope=openid
curl: (6) Could not resolve host: -X
curl: (6) Could not resolve host: POST
curl: (6) Could not resolve host: sandbox-oauth.aife.finances.rie.gouv.fr
tzdcorbm

tzdcorbm1#

好了,我终于解决了我自己的问题。没有必要使用OAuth的东西。它分为2个类。这段代码只是为了测试的目的。

public class OAuthApp {
    private static final String TOKEN_REQUEST_URL = "https://sandbox-oauth.aife.economie.gouv.fr/api/oauth/token";
    private static final String CLIENT_ID = "xxxxxx";
    private static final String CLIENT_SECRET = "xxxxxx";
    private static final String GRANT_TYPE = "client_credentials";
    private static final String SCOPE = "openid";

    public static void main(String[] args) throws IOException {
        try {
            Map<String, String> headers = new HashMap<>();
            HttpsPostForm httpsPostForm = new HttpsPostForm(TOKEN_REQUEST_URL, "utf-8", headers);
            httpsPostForm.addFormField("grant_type", GRANT_TYPE);
            httpsPostForm.addFormField("client_id", CLIENT_ID);
            httpsPostForm.addFormField("client_secret", CLIENT_SECRET);
            httpsPostForm.addFormField("scope", SCOPE);
            // Result
            String response = httpsPostForm.finish();
            System.out.println(response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我的第二个类只是构建HTTPS请求并设置头元素。空的信任管理器有助于避免错误消息。

public class HttpsPostForm {

    private HttpsURLConnection conn;
    private Map<String, Object> queryParams;
    private String charset;

    public HttpsPostForm(String requestURL, String charset, Map<String, String> headers, Map<String, Object> queryParams) throws IOException {
        this.charset = charset;
        if (queryParams == null) {
            this.queryParams = new HashMap<>();
        } else {
            this.queryParams = queryParams;
        }
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                    return null;
            }
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        }};

        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }

        URL url = new URL(requestURL);
        conn = (HttpsURLConnection) url.openConnection();
        conn.setUseCaches(false);
        conn.setDoOutput(true);    // indicates POST method
        conn.setDoInput(true);
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        if (headers != null && headers.size() > 0) {
            Iterator<String> it = headers.keySet().iterator();
            while (it.hasNext()) {
                String key = it.next();
                String value = headers.get(key);
                conn.setRequestProperty(key, value);
            }
        }
    }

    public HttpsPostForm(String requestURL, String charset, Map<String, String> headers) throws IOException {
        this(requestURL, charset, headers, null);
    }

    public HttpsPostForm(String requestURL, String charset) throws IOException {
        this(requestURL, charset, null, null);
    }
    public void addFormField(String name, Object value) {
        queryParams.put(name, value);
    }

    public void addHeader(String key, String value) {
        conn.setRequestProperty(key, value);
    }

    private byte[] getParamsByte(Map<String, Object> params) {
        byte[] result = null;
        StringBuilder postData = new StringBuilder();
        for (Map.Entry<String, Object> param : params.entrySet()) {
            if (postData.length() != 0) {
                postData.append('&');
            }
            postData.append(this.encodeParam(param.getKey()));
            postData.append('=');
            postData.append(this.encodeParam(String.valueOf(param.getValue())));
        }
        try {
            result = postData.toString().getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    private String encodeParam(String data) {
        String result = "";
        result = URLEncoder.encode(data, StandardCharsets.UTF_8);
        return result;
    }

    public String finish() throws IOException {
        String response = "";
        byte[] postDataBytes = this.getParamsByte(queryParams);
        conn.getOutputStream().write(postDataBytes);
        // Check the http status
        int status = conn.getResponseCode();
        if (status == HttpsURLConnection.HTTP_OK) {
            ByteArrayOutputStream result = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = conn.getInputStream().read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }
            response = result.toString(this.charset);
            conn.disconnect();
        } else {
            throw new IOException("Server returned non-OK status: " + status);
        }
        return response;
    }
}

最后我可以打印我的Json字符串:

{
    "access_token":"Js1NYJvtQREj0I0Dz5b0qrMh8gjJBlltJAit2Yx6BGJDloixPv2JwB",
    "token_type":"Bearer",
    "expires_in":3600,
    "scope":"openid resource.READ"
}
brtdzjyr

brtdzjyr2#

我在使用Chorus API时也遇到了一些困难,但我使用相同的方法获得了tokenKey,但最后使用了buildBodyMessage()。

// Création requête pour obtenir le token Oauth2 API CHORUS
            request = OAuthClientRequest
                    .tokenLocation(urlToken)
                    .setGrantType(GrantType.CLIENT_CREDENTIALS)
                    .setClientId(clientid)
                    .setClientSecret(clientsecret)
                    .setScope(OidcScopes.OPENID)
                    .buildBodyMessage();

            // Ajout du Cpro-account
            request.addHeader("cpro-account", cproAccount);

            tokenChorus = client.accessToken(request, OAuth.HttpMethod.POST, OAuthJSONAccessTokenResponse.class)
                    .getAccessToken();

它创建了String格式标记。然后,您必须使用此标记创建HttpUrlConnection,其标头如下

HttpURLConnection connexion = null;

        try {
            URL url = new URL(currentUrl);
            connexion = (HttpURLConnection) url.openConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }
        connexion.setRequestProperty("Content-type", "application/json");
        connexion.setRequestProperty("Authorization", "Bearer " + tokenChorus);
        connexion.setRequestProperty("cpro-account", cproAccount);
        try {
            connexion.setRequestMethod("POST");
        } catch (ProtocolException e) {
            e.printStackTrace();
        }

        connexion.setDoInput(true);
        connexion.setDoOutput(true);
        return connexion;

相关问题