2017-01-23 117 views
0

我試圖使用Azure AD oAuth 2身份驗證訪問Dynamics CRM Online REST API。爲了做到這一點我按照這些步驟:將訪問令牌傳遞給CRM API引發未經授權的(401)錯誤

  • 我已經登記在Azure中的Web應用程序和/或web API
  • 配置的權限動態CRM具有委託權限「訪問CRM在線爲組織用戶「
  • 然後創建一個具有1年到期時間的密鑰並保留生成的客戶端ID。

我的代碼:

package com.JasonLattimer.crm.auth; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
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 javax.naming.ServiceUnavailableException; 

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

import net.minidev.json.JSONObject; 
import net.minidev.json.JSONValue; 

public class App { 


    // CRM URL 
    private final static String RESOURCE = "xxxxxx.crm8.dynamics.com"; 
    private final static String CLIENT_ID = "xxxxxxx-xxxxx-xxxxxxx-xxxxxxxxx"; 
    private final static String CLIENT_SECRET_KEY = "xxxxxxxxxxxxxxxxxxxxxx"; 
    private final static String TENANTID = "xxxxxxxxxxx-xxxx-xxxxx-xxxxxxx"; 
    private final static String AUTHORITY = "login.microsoftonline.com" + TENANTID + "/oauth2/authorize"; 

    public static void main(String args[]) throws Exception { 
     AuthenticationResult result = getAccessTokenFromUserCredentials(); 
     System.out.println("Access Token - " + result.getAccessToken()); 
     System.out.println("Token expires on - " + result.getExpiresOn()); 

     //String userId = WhoAmI(result.getAccessToken()); 
     //System.out.println("UserId - " + userId); 

     String fullname = FindFullname(result.getAccessToken(), "2b8fc8ca-86cd-e611-8109-c4346bdc0e01"); 
     System.out.println("Fullname: " + fullname); 
    } 

    private static AuthenticationResult getAccessTokenFromUserCredentials() throws Exception { 

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

     try { 
      service = Executors.newFixedThreadPool(1); 
      authContext = new AuthenticationContext(AUTHORITY, false, service); 

      ClientCredential clientCred = new ClientCredential(CLIENT_ID, CLIENT_SECRET_KEY); 
      Future<AuthenticationResult> future = authContext.acquireToken(RESOURCE, clientCred, null); 
      authResult = future.get(); 
     } catch (Exception ex) { 
      System.out.println(ex); 
     } finally { 
      service.shutdown(); 
     } 

     if (authResult == null) { 
      throw new ServiceUnavailableException("authentication result was null"); 
     } 
     return authResult; 
    } 

    private static String FindFullname(String token, String userId) throws MalformedURLException, IOException { 
     System.out.println("AAAAAAAAAAAAAAAAAA"); 
     HttpURLConnection connection = null; 
     //The URL will change in 2016 to include the API version - /api/data/v8.0/systemusers 
     URL url = new URL(RESOURCE + "/api/data/systemusers(" + userId + ")?$select=fullname"); 
     connection = (HttpURLConnection) url.openConnection(); 
     connection.setRequestMethod("GET"); 
     connection.setRequestProperty("OData-MaxVersion", "4.0"); 
     connection.setRequestProperty("OData-Version", "4.0"); 
     connection.setRequestProperty("Accept", "application/json"); 
     connection.addRequestProperty("Authorization", "Bearer " + token); 

     int responseCode = connection.getResponseCode(); 

     BufferedReader in = new BufferedReader(
       new InputStreamReader(connection.getInputStream())); 
     String inputLine; 
     StringBuffer response = new StringBuffer(); 

     while ((inputLine = in.readLine()) != null) { 
      response.append(inputLine); 
     } 
     in.close(); 

     Object jResponse; 
     jResponse = JSONValue.parse(response.toString()); 
     JSONObject jObject = (JSONObject) jResponse; 
     String fullname = jObject.get("fullname").toString(); 
     System.out.println("FULL NAME" + fullname); 
     return fullname; 
    } 

    private static String WhoAmI(String token) throws MalformedURLException, IOException { 
     HttpURLConnection connection = null; 
     //The URL will change in 2016 to include the API version - /api/data/v8.0/WhoAmI 
     URL url = new URL(RESOURCE + "/api/data/WhoAmI"); 
     connection = (HttpURLConnection) url.openConnection(); 
     connection.setRequestMethod("GET"); 
     connection.setRequestProperty("OData-MaxVersion", "4.0"); 
     connection.setRequestProperty("OData-Version", "4.0"); 
     connection.setRequestProperty("Accept", "application/json"); 
     connection.addRequestProperty("Authorization", "Bearer " + token); 

     int responseCode = connection.getResponseCode(); 

     BufferedReader in = new BufferedReader(
       new InputStreamReader(connection.getInputStream())); 
     String inputLine; 
     StringBuffer response = new StringBuffer(); 

     while ((inputLine = in.readLine()) != null) { 
      response.append(inputLine); 
     } 
     in.close(); 

     Object jResponse; 
     jResponse = JSONValue.parse(response.toString()); 
     JSONObject jObject = (JSONObject) jResponse; 
     String userId = jObject.get("UserId").toString(); 
     return userId; 
    } 
} 

我檢索一個訪問令牌成功,但是當我嘗試做一個HTTPRequest,以CRM我總是得到一個401 - Unauthorized狀態碼。我錯過了什麼?

回答

0

你有2種選擇:

  1. ,你在CRM中的「普通」用戶身份驗證舊的方式(你需要他們的密碼,但能避免彈出流量)。 C#示例here
  2. 新的方法是「服務器到服務器身份驗證」,它要求您創建一個Application User。注意這個例子也是C#,但是Java中的ADAL代碼應該非常相似。