crm on premise IFD 部署下提供oauth 2.0 集成自定义应用
很多情况下我们的CRM系统会和弟三方应用集成,一般情况我们会开发一个中间站点来提供web api 给弟三方应用。
参考:http://alexanderdevelopment.net/post/2015/01/24/authenticating-from-a-node-js-client-to-dynamics-crm-via-ad-fs-and-oauth2/
利用adfs 带的auto2.0可以有一种简单的方式和弟三方应用集成。我们做的只需要类似像和微信、微博、QQ集成弟三登录功能一样实现 ADFS oauth 2.0
弟一步 在ADFS上注册一个client ,生成的 ClientId、RedirectUri (指跳转页面),在ADFS中没有密码这个属性,在请求code的时候 会用这两个属性代替clientid和密码
Add-AdfsClient -ClientId "aa106265-fb3b-49e0-a0e8-6840b3d71ac2" -Name "hongfu dynamics CRM ADFS Client" -RedirectUri "http://localhost:21313/Default.aspx"
弟二步在我们自己的程序中注册登录代码
逻辑比较简单
1 用户进入登录页面
2 用户点击登录,页面会跳转到ADFS的登录页面,注意URL
3 在ADFS实现 登录后,回转到我们之前 定义的RedirectUri,URL中会传一个code参数
4 在登录面的onload 事件中读取出 code,去adfs请求token
string url = string.Format("{0}adfs/oauth2/token" , _adfs); string body = string.Format("grant_type=authorization_code&client_id={0}&redirect_uri={1}&code={2}" , _clientID, Server.UrlEncode(_returnURL), code); var requestJson = JsonConvert.SerializeObject(new { grant_type = "authorization_code", client_id = _clientID, redirect_uri = Server.UrlEncode(_returnURL) , code = code }); HttpClient client = new HttpClient(); HttpContent content = new StringContent(body); content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); var tokenstr = client.PostAsync(url, content).Result.Content.ReadAsStringAsync().Result;
5 请求完token后,再使用token调用CRM webapi ,查询出当前用户和客户信息
6 实现 代码如下
using System; using System.Collections.Generic; using System.IdentityModel.Tokens; using System.Linq; using System.Net; using System.Threading; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Net.Http; using Newtonsoft.Json; using System.Net.Http.Headers; public partial class _Default : Page { // // Add-AdfsClient -ClientId "aa106265-fb3b-49e0-a0e8-6840b3d71ac2" -Name "hongfu dynamics CRM ADFS Client" -RedirectUri "http://localhost:21313/Default.aspx" private static AuthenticationContext _authenticationContext; // TODO Set these string values as approppriate for your app registration and organization. // For more information, see the SDK topic "Walkthrough: Register an app with Active Directory". private const string _clientID = "aa106265-fb3b-49e0-a0e8-6840b3d71ac2"; public const string CrmServiceUrl = "https://crm.crmad.com:446/"; public const string _adfs = "https://adfs.crmad.com/"; public const string _returnURL = "http://localhost:21313/Default.aspx"; protected void Page_Load(object sender2, EventArgs e) { System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true); if (!string.IsNullOrEmpty(Request["code"])) { GetToken(Request["code"]); //3. Client request access token } } //<snippetModernOdataAppAuthDiscovery> /// <summary> /// Discover the authentication authority. /// </summary> /// <param name="serviceUrl">The URL of the organization's SOAP endpoint. </param> /// <returns>The authority URL.</returns> /// <remarks>The service URL must contain the SdkClient property.</remarks> /// <example>https://contoso.crm.dynamics.com/XRMServices/2011/Organization.svc/web?SdkClientVersion=6.1.0.533;</example> public static string DiscoveryAuthority(Uri serviceUrl) { // Use AuthenticationParameters to send a request to the organization's endpoint and // receive tenant information in the 401 challenge. HttpWebResponse response = null; try { // Create a web request where the authorization header contains the word "Bearer". HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(serviceUrl); // The response is to be encoded. httpWebRequest.ContentType = "application/x-www-form-urlencoded"; response = (HttpWebResponse)httpWebRequest.GetResponse(); } catch (WebException ex) { response = (HttpWebResponse)ex.Response; } finally { if (response != null) response.Dispose(); } // Return the authority URL. return response.ToString(); } //</snippetModernOdataAppAuthDiscovery> protected void Button1_Click(object sender, EventArgs e) { string url = string.Format("{0}adfs/oauth2/authorize?response_type=code&client_id={1}&resource={2}&redirect_uri={3}" , _adfs, _clientID, Server.UrlEncode(CrmServiceUrl), Server.UrlEncode(_returnURL)); Response.Redirect(url); } public class CRMToken { public string access_token { get; set; } public string token_type { get; set; } public string expires_in { get; set; } public string refresh_token { get; set; } } void GetToken(string code) { string url = string.Format("{0}adfs/oauth2/token" , _adfs); string body = string.Format("grant_type=authorization_code&client_id={0}&redirect_uri={1}&code={2}" , _clientID, Server.UrlEncode(_returnURL), code); var requestJson = JsonConvert.SerializeObject(new { grant_type = "authorization_code", client_id = _clientID, redirect_uri = Server.UrlEncode(_returnURL) , code = code }); HttpClient client = new HttpClient(); HttpContent content = new StringContent(body); content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); var tokenstr = client.PostAsync(url, content).Result.Content.ReadAsStringAsync().Result; var token = JsonConvert.DeserializeObject<CRMToken>(tokenstr); using (HttpClient httpClient = new HttpClient()) { httpClient.Timeout = new TimeSpan(0, 2, 0); // 2 minutes httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.access_token); //GET [Organization URI]/api/data/v8.1/accounts?$select=name&$top=3 HTTP/1.1 // Accept: application / json //OData - MaxVersion: 4.0 //OData - Version: 4.0 var api = string.Format("{0}api/data/v8.1/accounts?$select=name&$top=3", CrmServiceUrl); httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); var str = httpClient.GetStringAsync(api).Result; this.TextBox1.Text = str; } using (HttpClient httpClient = new HttpClient()) { httpClient.Timeout = new TimeSpan(0, 2, 0); // 2 minutes httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.access_token); //GET [Organization URI]/api/data/v8.1/accounts?$select=name&$top=3 HTTP/1.1 // Accept: application / json //OData - MaxVersion: 4.0 //OData - Version: 4.0 var api = string.Format("{0}api/data/v8.1/WhoAmI()", CrmServiceUrl); httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); var str = httpClient.GetStringAsync(api).Result; this.Label1.Text = str; } } protected void Button1_Click1(object sender, EventArgs e) { string url = string.Format("{0}adfs/oauth2/authorize?response_type=code&client_id={1}&resource={2}&redirect_uri={3}" , _adfs, _clientID, Server.UrlEncode(CrmServiceUrl), Server.UrlEncode(_returnURL)); Response.Redirect(url); } }
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server"> <p> <br /> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click1" Text="登录CRM" /> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> </p> <p> <asp:TextBox ID="TextBox1" runat="server" Height="183px" TextMode="MultiLine" Width="833px"></asp:TextBox> </p> </asp:Content>
posted on 2016-08-21 00:33 HelloHongfu 阅读(1187) 评论(2) 编辑 收藏 举报