2016-06-24 13 views
6

Chúng tôi đang viết một dịch vụ WCF có tích hợp với Dynamics CRM 2016 Online. Tôi đang cố gắng để xác thực bằng cách sử dụng ADAL, sử dụng phương pháp AcquireTokenAsync(). Vấn đề là, nó sẽ hiển thị một hộp bật lên, nhắc người dùng về thông tin đăng nhập. Đương nhiên, ứng dụng của chúng tôi là một dịch vụ, đây không phải là những gì chúng tôi muốn. Chúng tôi đã tìm kiếm một cách để xác thực mà không có hộp bật lên này.C# ADAL AcquireTokenAsync() không có hộp bật lên

Có một lớp được gọi là AuthenticationContextIntegratedAuthExtensions, được cho là hỗ trợ "lưu lượng người dùng/mật khẩu". Nó có phương thức duy nhất AcquireTokenAsync, ngăn chặn hộp bật lên, nhưng chúng tôi không tìm thấy bất kỳ cách nào để chuyển mật khẩu cho nó. Khi chạy chỉ với tên người dùng, nó làm tăng ngoại lệ về cơ bản là "không có mật khẩu nào được cung cấp".

Có ai có ý tưởng nào về cách giải quyết vấn đề này không? Thậm chí không phải là ADAL. Chỉ cần một cái gì đó để có được mã thông báo OAuth.

Trả lời

4
private static string API_BASE_URL = "https://<CRM DOMAIN>.com/"; 
private static string API_URL = "https://<CRM DOMAIN>.com/api/data/v8.1/"; 
private static string CLIENT_ID = "<CLIENT ID>"; 

static void Main(string[] args) 
{ 
    var ap = AuthenticationParameters.CreateFromResourceUrlAsync(
       new Uri(API_URL)).Result; 

    var authContext = new AuthenticationContext(ap.Authority, false); 

    var userCredential = new UserCredential("<USERNAME>", "<PASSWORD>"); 

    var result = authContext.AcquireToken(API_BASE_URL, CLIENT_ID, userCredential); 

    var httpClient = HttpWebRequest.CreateHttp(Path.Combine(API_URL, "accounts")); 
    httpClient.Headers.Add(HttpRequestHeader.Authorization, "Bearer:" + result.AccessToken); 
    using (var sr = new StreamReader(httpClient.GetResponse().GetResponseStream())) 
    { 
     Console.WriteLine(sr.ReadToEnd()); 
    } 
} 

Lưu ý: Tôi đang sử dụng một phiên bản cũ của ADAL (2.19.208020213) như nó xuất hiện các thông số mật khẩu đã được đưa ra khỏi các nhà xây dựng UserCredential.

EDIT: phiên bản mới nhất của ADAL có UserPasswordCredential mà có thể được sử dụng thay cho UserCredential (và có lẽ đã được bổ sung càng sớm càng Password đã bị xóa khỏi UserCredential)

EDIT 2: CRM bây giờ hỗ trợ Server to Server Authentication mà cho phép bạn tạo một người dùng ứng dụng.

+0

Có. Trường mật khẩu được lấy ra vì bất kỳ lý do gì. Trong thực tế, chúng tôi đã không tìm thấy bất kỳ lớp hoặc phương pháp nào có liên quan đến mật khẩu. Một số lớp có một hàm tạo chấp nhận tên người dùng, UserIdentifier, cho một. Mặc dù mục đích của nó dường như tự động hoàn thành, thay vì bất kỳ nỗ lực nào trong xác thực im lặng. – eltaro

+0

Phải, tôi không chắc chắn tại sao nó bị xóa (blog này http://www.cloudidentity.com/blog/2014/07/08/using-adal-net-to-authenticate-users-via-usernamepassword/ là một trong những tôi nhớ đọc khi nó lần đầu tiên được giới thiệu), nhưng nếu bạn sử dụng phiên bản cụ thể ở trên, bạn có thể xác thực mà không có một popup và mã thông báo sẽ làm việc cho các yêu cầu chống lại CRM. –

+0

Dường như chúng tôi sẽ phải sử dụng giải pháp của bạn. Cái tôi đăng ở đây không cho phép chúng tôi truy cập vào CRM, đưa ra lỗi 401. – eltaro

0

Được rồi, kết thúc tìm một giải pháp cho việc này. Miễn là bạn đã đăng ký ứng dụng của bạn với Azure AD (như một Web App/Web API, không phải là một ứng dụng Native), bạn sẽ nhận được một ID khách hàng và một khóa bí mật cho ứng dụng đó.

Mã để mua token mà không cần phải một cửa sổ pop-up như sau:

AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(
         new Uri(resource+"/api/data/v8.1")).Result; 

AuthenticationContext ac = new AuthenticationContext(ap.Authority); 

AuthenticationResult r = await ac.AcquireTokenAsync(ap.Resource, new ClientCredential(clientId,clientSecret)); 

nguồn là URL cơ sở triển khai Dynamics CRM của bạn.

Thông số xác thực được phát hiện trong thời gian chạy như được đề xuất trong MSDN acticle này.

+0

Bạn đã thử sử dụng thẻ này để thực hiện cuộc gọi chống lại WebAPI CRM không? Tôi muốn được tò mò nếu mã thông báo bạn có sẽ làm việc khi được chuyển đến CRM vì không có người dùng được chỉ định. Nếu nó hoạt động được những cuộc gọi được thực hiện như trong CRM là ai? –

+1

Chưa. Tuy nhiên, khi bạn đăng ký ứng dụng trong Azure AD, bạn có thể cấp quyền cho Dynamics CRM. Không phải bất kỳ CRM cụ thể, tâm trí bạn, vì vậy tôi muốn giả sử bạn có quyền truy cập vào bất kỳ trường hợp nào được triển khai trên Azure AD đó. Và AuthenticationParameters được thu thập bằng cách ping dụ CRM của chúng ta, mà sau đó chúng ta sử dụng để xác thực đối với AD bên dưới bằng cách gửi AuthenticationParameters.Resource tới AcquireTokenAsync(). – eltaro

+0

Nhưng bạn không được xác thực là người dùng, CRM cho phép "quyền được ủy quyền" chứ không phải "quyền của ứng dụng" nghĩa là bạn cần người dùng đã đăng nhập. Khi bạn cung cấp mã thông báo này cho CRM, bạn có thể sẽ nhận được 401. –

2

Đối với những gì nó có giá trị mà không sử dụng ADAL

var postData = new List<KeyValuePair<string, string>> 
     { 
      new KeyValuePair<string, string>("resource", cred.ResourceId), 
      new KeyValuePair<string, string>("grant_type", "client_credentials"), 
      new KeyValuePair<string, string>("client_id", cred.ClientId), 
      new KeyValuePair<string, string>("client_secret", cred.ClientSecret), 

     }; 

     using (var client = new HttpClient()) { 

      string baseUrl = "https://login.windows.net/YourAADInstanceName.onmicrosoft.com/oauth2/"; 
      client.BaseAddress = new Uri(baseUrl);     
      client.DefaultRequestHeaders.Accept.Clear(); 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

      var content = new FormUrlEncodedContent(postData); 

      HttpResponseMessage response = await client.PostAsync("token", content);    
      string jsonString = await response.Content.ReadAsStringAsync();     
      var responseData = JsonConvert.DeserializeObject<Token>(jsonString); 
      return responseData; 
     } 
+0

Điều này xác thực và trả về một accessToken nhưng khi tôi sử dụng mã thông báo, nó cung cấp 401. – Justin

Các vấn đề liên quan