ADAL4j java — используйте токен обновления с именем пользователя и паролем, чтобы получить токен доступа

Я подключаюсь к API с поддержкой Azure AD, используя внутренний сервер Java. Я могу получить токен доступа, следуя коду Java.

    String tenantId = "************";
    String username = "***************";
    String password = "*************";
    String clientId = "**********";
    String resource = "***********";
    String userEmail = "**********";


    AuthenticationContext authContext = null;
    AuthenticationResult authResult = null;
    ExecutorService service = null;

    try
    {
        service = Executors.newFixedThreadPool( 1 );
        String url = "https://login.microsoftonline.com/" + tenantId + "/oauth2/authorize";
        authContext = new AuthenticationContext( url, false, service );
        Future<AuthenticationResult> future = authContext.acquireToken(
                resource,
                clientId,
                userEmail,
                password,
                null );

        authResult = future.get();

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

Обратите внимание, что поставщик API в настоящее время не поддерживает учетные данные клиента.

Для меня проблема заключается в использовании токена обновления, полученного в приведенном выше коде, для получения нового токена доступа.

Java-библиотека ADAL4j, похоже, не имеет методов, поддерживающих это. Документация по библиотеке Java

Но в библиотеке .NET есть такие методы, как

public AuthenticationResult AcquireTokenByRefreshToken(
string refreshToken,
string clientId,
string resource
)

Для обновления токена доступа без предоставления каких-либо учетных данных.

Почему эти методы не предусмотрены в библиотеке Java? Есть ли ограничения? И каковы возможные обходные пути?

Заранее спасибо.


person Tanimak    schedule 15.08.2017    source источник


Ответы (1)


Насколько я знаю, хотя библиотека Java ADAL4J не поддерживает метод

public AuthenticationResult AcquireTokenByRefreshToken(
string refreshToken,
string clientId,
string resource
)

который поддерживается в библиотеке .Net, оба типа библиотек реализованы через HTTP REST API.

Вы можете обратиться к обновлению маркеров доступа в официальном документ

// Line breaks for legibility only

POST /{tenant}/oauth2/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&refresh_token=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq...
&grant_type=refresh_token
&resource=https%3A%2F%2Fservice.contoso.com%2F
&client_secret=JqQX2PNo9bpM0uEihUPzyrh    // NOTE: Only required for web apps

Я использую Postman для проверки запроса на получение accessToken с помощью refreshToken без учетных данных для вашей справки:

введите здесь описание изображения

В ответ я реализовал запрос со следующим кодом Java:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import com.microsoft.aad.adal4j.AuthenticationContext;
import com.microsoft.aad.adal4j.AuthenticationResult;

public class AcquireTokenByRefreshToken {

    static String tenantId = "***";
    static String username = "***";
    static String password = "***";
    static String clientId = "***";
    static String resource = "https://graph.windows.net";
    static String userEmail = "***";

    public static void main(String[] args) throws MalformedURLException, IOException {
        AuthenticationContext authContext = null;
        AuthenticationResult authResult = null;
        ExecutorService service = null;

        try {
            service = Executors.newFixedThreadPool(1);
            String url = "https://login.microsoftonline.com/" + tenantId + "/oauth2/authorize";
            authContext = new AuthenticationContext(url, false, service);
            Future<AuthenticationResult> future = authContext.acquireToken(resource, clientId, userEmail, password,
                    null);

            authResult = future.get();
            System.out.println("get access token: \n" + authResult.getAccessToken());
            System.out.println("get refresh token: \n" + authResult.getRefreshToken());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        // get access token by refresh token
        getToken(authResult.getRefreshToken());
    }

    public static void getToken(String refreshToken) throws IOException {

        String encoding = "UTF-8";
        String params = "client_id=" + clientId + "&refresh_token=" + refreshToken
                + "&grant_type=refresh_token&resource=https%3A%2F%2Fgraph.windows.net";
        String path = "https://login.microsoftonline.com/" + tenantId + "/oauth2/token";
        byte[] data = params.getBytes(encoding);
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        conn.setRequestProperty("Content-Length", String.valueOf(data.length));
        conn.setConnectTimeout(5 * 1000);
        OutputStream outStream = conn.getOutputStream();
        outStream.write(data);
        outStream.flush();
        outStream.close();
        System.out.println(conn.getResponseCode());
        System.out.println(conn.getResponseMessage());

        BufferedReader br = null;
        if (conn.getResponseCode() != 200) {
            br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
        } else {
            br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
        }
        System.out.println("Response body : " + br.readLine());
    }

}

Результат напечатан в консоли, как показано ниже:

введите здесь описание изображения

Надеюсь, это поможет вам.

person Jay Gong    schedule 17.08.2017
comment
Спасибо. Я считаю альтернативу, которую вы предоставили, очень полезной. - person Tanimak; 18.08.2017
comment
Но знаете ли вы, почему библиотека Java не поддерживает эту функциональность. За этим должна быть причина. - person Tanimak; 18.08.2017