2017-08-15 259 views
0

我正在使用java后端服务器连接到启用Azure AD的API。我可以通过以下java代码获得访问令牌。ADAL4j 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提供者目前不支持客户端凭证。

问题是,使用上面代码中接收到的刷新令牌来获取新的访问令牌。

ADAL4j java库似乎没有任何支持此方法的方法。 A Documentation for java library

但在.NET库也有类似的方法,

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

对于刷新访问令牌不提供任何凭证。

为什么这些方法没有在Java库中提供?有任何限制吗? 什么是可能的解决方法?

在此先感谢。

回答

1

据我所知,尽管Java ADAL4J库不支持的方法

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

这是在NET库的支持,无论是两种类型的库都是通过HTTP REST API实现

你可以参考刷新访问令牌在官方document

// 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 

我用邮差测试获取的accessToken通过refreshToken无凭据,供您参考的请求:

enter image description here

对应,我实现了以下请求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()); 
    } 

} 

在控制台打印如下结果:

enter image description here

希望它可以帮助你。

+0

谢谢。我发现你提供的选择非常有用。 – Tanimak

+0

但是你有什么想法为什么java库不支持这个功能。背后应该有一个原因。 – Tanimak

相关问题