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编辑  收藏  举报

导航