微軟動態CRM專家羅勇 ,回復332或者20190505可方便獲取本文,同時可以在第一間得到我發布的最新博文信息,follow me!
本文很多內容來自 John Towgood 撰寫的Dynamics 365 Online Authenticate with Client Credentials?,也著重參考了官方的?Use Single-Tenant server-to-server authentication?,我根據新的Azure Portal界面做了一些操作上的變化,并且改了一些代碼,還使用ADAL來簡化代碼。
登錄?https://portal.azure.com?,點擊左邊的 【Azure Active Directory】 ,然后再點擊 【App registrations】 ,再點擊【New registration】
輸入一個合適的名稱,Supported account types保持默認的?Accounts in this organizational directory only (Orgname) 不變,點擊【Register】按鈕。因為Redirect URI用不上所以不輸入。
注冊成功后會產生 Application (client) ID,記錄下來備用,同時也記錄下 Directory (tenant) ID。
再點擊左邊的【API Permissions】,再點擊右邊的 【+ Add a permission】按鈕。
選擇 【Dynamics CRM】? (也可以選擇使用 PowerApps Runtime Serive 這個權限),
選擇 【Delegated permissions】 > 【user_impersonation】后點擊【Add permissions】按鈕。
?
?
?
然后點擊【Grant admin consent for Orgname】,
在彈出的提示中選擇【Yes】。
然后點擊【Certificates & secrets】 > 【+ New client secret】,輸入合適的Description,在點擊【Add】按鈕。
會自動生成Client secrets,這里需要點擊生成的secret旁邊的【copy to clipboard】圖標將其復制下來,記得在這個步驟復制下來,因為離開這個頁面后就看不到這個secret了。
然后需要創建 一個Azure AD 用戶,點擊左側的【Azure Active Directory】> 【Users】。
然后點擊【New user】。
為用戶輸入Name,User Name,然后點擊【Create】按鈕。
最后還需要到Dynamics 365 Customer Engagement中創建一個Application User。導航到 Settings > Security > Users,切換到【Application Users】,點擊命令欄的【NEW】按鈕。
記得要切換到 APPLICATION USER這個窗體,輸入的內容如下,Application ID就是前面步驟記錄的Application (client) ID,其余的就是前面步驟創建的Azure AD user信息。
保存后會自動填充?Application ID URI 和 Azure AD Object ID 字段的值。
當然還需要給這個用戶授予至少一個角色才行,官方建議不要授予系統標準角色,我這里復制了一個標準角色授予給他。
如果用Postman來獲取access token的話,如下圖:
下面就是用代碼如何做了,不多說,看代碼:
using Newtonsoft.Json;using System;using System.Collections.Generic;using System.Net.Http;using System.Net.Http.Headers;using System.Threading.Tasks;?namespace UsingWebAPI{public class AuthenticationResponse{public string access_token { get; set; }public int expires_in { get; set; }public int expires_on { get; set; }public int ext_expires_in { get; set; }public int not_before { get; set; }public string resource { get; set; }public string token_type { get; set; }}class Program{?static string resourceUrl = "https://crm219270.crm5.dynamics.com/";static string clientId = "de8dd947-a3e3-48ec-8602-c3063f11dc29";static string clientSecret = "5FsXh2*oNyLRm]Go1a9hD.[]=k54GNOZ";static string tenantId = "3e28b187-1c5c-42f5-a1be-3f47570da35d";
static void Main(string[] args){GetAuthenticationResponse();Console.ReadKey();}?private static async void GetAuthenticationResponse(){List<KeyValuePair<string, string>> vals = new List<KeyValuePair<string, string>>();?vals.Add(new KeyValuePair<string, string>("client_id", clientId));vals.Add(new KeyValuePair<string, string>("resource", resourceUrl));vals.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));vals.Add(new KeyValuePair<string, string>("client_secret", clientSecret));string tokenUrl = string.Format("https://login.windows.net/{0}/oauth2/token", tenantId);?using (HttpClient httpClient = new HttpClient()){httpClient.DefaultRequestHeaders.Add("Cache-Control", "no-cache");HttpContent content = new FormUrlEncodedContent(vals);HttpResponseMessage hrm = httpClient.PostAsync(tokenUrl, content).Result;AuthenticationResponse authenticationResponse = null;if (hrm.IsSuccessStatusCode){string data = await hrm.Content.ReadAsStringAsync();authenticationResponse = JsonConvert.DeserializeObject<AuthenticationResponse>(data);await DataOperations(authenticationResponse);}else{Console.WriteLine("Error." + hrm.ReasonPhrase);}}}?private static async Task DataOperations(AuthenticationResponse authResult){using (HttpClient httpClient = new HttpClient()){httpClient.BaseAddress = new Uri(resourceUrl);httpClient.Timeout = new TimeSpan(, , ); //2 minuteshttpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.access_token);string content = JsonConvert.SerializeObject(new { name = "A Account", telephone1 = ""});HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "api/data/v9.1/accounts");request.Content = new StringContent(content);request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");HttpResponseMessage response = await httpClient.SendAsync(request);if (response.IsSuccessStatusCode){Console.WriteLine("Account created.");}else{Console.WriteLine(String.Format("Failed to create account, reason is '{0}'.", response.ReasonPhrase));}}}}}
當然,如果使用ADAL的話,代碼會更加簡單點:
using Microsoft.IdentityModel.Clients.ActiveDirectory;using Newtonsoft.Json;using System;using System.Net.Http;using System.Net.Http.Headers;?namespace UsingWebAPI{class Program{?static string resourceUrl = "https://crm219270.crm5.dynamics.com/";static string clientId = "de8dd947-a3e3-48ec-8602-c3063f11dc29";static string clientSecret = "5FsXh2*oNyLRm]Go1a9hD.[]=k54GNOZ";static string tenantId = "3e28b187-1c5c-42f5-a1be-3f47570da35d";?static void Main(string[] args){AuthAndInvoke();Console.ReadKey();}?private static async void AuthAndInvoke(){var credentials = new ClientCredential(clientId, clientSecret);var authContext = new AuthenticationContext("https://login.microsoftonline.com/" + tenantId);var result = await authContext.AcquireTokenAsync(resourceUrl, credentials);using (HttpClient httpClient = new HttpClient()){httpClient.BaseAddress = new Uri(resourceUrl);httpClient.Timeout = new TimeSpan(, , ); //2 minuteshttpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");httpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);string content = JsonConvert.SerializeObject(new { name = "A Account", telephone1 = "" });HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "api/data/v9.1/accounts");request.Content = new StringContent(content);request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");HttpResponseMessage response = await httpClient.SendAsync(request);if (response.IsSuccessStatusCode){Console.WriteLine("Account created.");}else{Console.WriteLine(String.Format("Failed to create account, reason is '{0}'.", response.ReasonPhrase));}}}}}
可以看到代碼創建的account的owner是我們前面步驟的Application User,是以該用戶身份在運行的。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的【转】!Dynamics 365 Online通过OAuth 2 Client Credential授权(Server-to-Server Authentication)后调用Web API的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。