public class CrmAuth
     {
         ///<summary>
         /// Token
         /// </summary>
         public string access_token { get; set; }

         ///<summary>
         /// 类型
         /// </summary>
         public string token_type { get; set; }

         ///<summary>
         /// 有效期 秒
         /// </summary>
         public int expires_in { get; set; }

         ///<summary>
         /// refresh_Token 用于刷新Token
         /// </summary>
         public string refresh_token { get; set; }

         /// <summary>
         /// 请求Token
         /// </summary>
         /// <param name="adfsUri">ADFS地址</param>
         /// <param name="resource">CRM地址</param>
         /// <param name="clientId">客户端ID</param>
         /// <param name="redirectUri">跳转地址</param>
         /// <param name="userName">用户名</param>
         /// <param name="password">密码</param>
         /// <returns></returns>
         public static CrmAuth AcquireToken(string adfsUri, string resource, string clientId, string redirectUri, string userName, string password)
         {
             VerifyParams(adfsUri, resource, clientId, redirectUri, userName, password);

             var url = BuildCodeUrl(adfsUri, resource, clientId, redirectUri);

             var tokenUrl = BuildTokenUrl(adfsUri);

             var list = BuildCodeParams(userName, password);

             //包含上下文的 用WebRequest也可以
             using (var handler = new WebRequestHandler { AllowAutoRedirect = false })
             {
                 using (var httpClient = new HttpClient(handler))
                 {
                     //第1次请求
                     using (var response = httpClient.PostAsync(url, new FormUrlEncodedContent(list)).Result)
                     {
                         // 第2次请求 httpClient 还要用之前的 包含了第一次返回的Cookies
                         using (var response2 = httpClient.GetAsync(response.Headers.Location).Result)
                         {
                             // 获取返回的Code
                             var query = response2.Headers.Location.Query;
                             var col = Utils.GetQueryString(query);
                             var code = col["code"];
                             if (string.IsNullOrWhiteSpace(code))
                             {
                                 throw new Exception(query);
                             }
                             // 第3次请求 请求Token
                             var tokenParams = BuildTokenParams(clientId, code, resource, redirectUri);
                             using (var response3 = httpClient.PostAsync(tokenUrl, new FormUrlEncodedContent(tokenParams)).Result)
                             {
                                 var json = response3.Content.ReadAsStringAsync().Result;
                                 var auth = JsonConvert.DeserializeObject<CrmAuth>(json);
                                 if (auth == null)
                                     throw new Exception(json);
                                 return auth;
                             }

                         }
                     }
                 }
             }
         }

         /// <summary>
         /// 刷新Token
         /// </summary>
         /// <param name="adfsUri"></param>
         /// <param name="refresh_token"></param>
         /// <returns></returns>
         public static CrmAuth CrmRefreshToken(string adfsUri, string refresh_token)
         {
             var tokenUrl = BuildTokenUrl(adfsUri);
             using (var httpClient = new HttpClient())
             {
                 // 请求 请求Token
                 var tokenParams = BuildRefreshTokenParams(refresh_token);
                 using (var response3 = httpClient.PostAsync(tokenUrl, new FormUrlEncodedContent(tokenParams)).Result)
                 {
                     var json = response3.Content.ReadAsStringAsync().Result;
                     var auth = JsonConvert.DeserializeObject<CrmAuth>(json);
                     if (auth == null)
                         throw new Exception(json);
                     return auth;
                 }
             }
         }

         /// <summary>
         /// 验证参数
         /// </summary>
         /// <param name="adfsUri"></param>
         /// <param name="resource"></param>
         /// <param name="clientId"></param>
         /// <param name="redirectUri"></param>
         /// <param name="userName"></param>
         /// <param name="password"></param>
         private static void VerifyParams(string adfsUri, string resource, string clientId, string redirectUri, string userName, string password)
         {
             if (string.IsNullOrWhiteSpace(adfsUri))
                 throw new ArgumentNullException(nameof(adfsUri));
             if (string.IsNullOrWhiteSpace(nameof(resource)))
                 throw new ArgumentNullException(resource);
             if (string.IsNullOrWhiteSpace(clientId))
                 throw new ArgumentNullException(nameof(clientId));
             if (string.IsNullOrWhiteSpace(redirectUri))
                 throw new ArgumentNullException(nameof(redirectUri));
             if (string.IsNullOrWhiteSpace(userName))
                 throw new ArgumentNullException(nameof(userName));
             if (string.IsNullOrWhiteSpace(password))
                 throw new ArgumentNullException(nameof(password));
         }

         /// <summary>
         /// 构建ADFS CODE地址
         /// </summary>
         /// <param name="adfsUri"></param>
         /// <param name="resource"></param>
         /// <param name="clientId"></param>
         /// <param name="redirectUri"></param>
         /// <returns></returns>
         private static string BuildCodeUrl(string adfsUri, string resource, string clientId, string redirectUri)
         {

             if (!adfsUri.EndsWith("/"))
                 adfsUri = adfsUri + "/";
             var url = $"{adfsUri}adfs/oauth2/authorize";

             var response_type = "code";

             var sb = new StringBuilder();
             sb.Append(url);
             sb.Append("?");
             sb.Append($"response_type={response_type}");
             sb.Append("&");
             sb.Append($"client_id={clientId}");
             sb.Append("&");
             sb.Append($"redirect_uri={redirectUri}");
             sb.Append("&");
             sb.Append($"resource={resource}");
             url = sb.ToString();
             return url;
         }

         /// <summary>
         /// 构建ADFS TOKEN地址
         /// </summary>
         /// <param name="adfsUri"></param>
         /// <returns></returns>
         private static string BuildTokenUrl(string adfsUri)
         {
             return $"{adfsUri}adfs/oauth2/token";
         }

         /// <summary>
         /// 构建请求Code参数
         /// </summary>
         /// <param name="userName"></param>
         /// <param name="password"></param>
         /// <returns></returns>
         private static List<KeyValuePair<string, string>> BuildCodeParams(string userName, string password)
         {
             var list = new List<KeyValuePair<string, string>>()
             {
                 new KeyValuePair<string, string>("UserName",userName),
                 new KeyValuePair<string, string>("Password",password),
                 new KeyValuePair<string, string>("Kmsi","true"),
                 new KeyValuePair<string, string>("AuthMethod","FormsAuthentication")
             };
             return list;
         }

         /// <summary>
         /// 构建请求Token参数
         /// </summary>
         /// <param name="clientId"></param>
         /// <param name="code"></param>
         /// <param name="resource"></param>
         /// <param name="redirectUri"></param>
         /// <returns></returns>
         private static List<KeyValuePair<string, string>> BuildTokenParams(string clientId, string code, string resource, string redirectUri)
         {
             var list = new List<KeyValuePair<string, string>>
             {
                 new KeyValuePair<string, string>("grant_type", "authorization_code"),
                 new KeyValuePair<string, string>("client_id", clientId),
                 new KeyValuePair<string, string>("code", code),
                 new KeyValuePair<string, string>("resource", resource),
                 new KeyValuePair<string, string>("redirect_uri", redirectUri)
             };
             return list;
         }

         /// <summary>
         /// 构建请求刷新Token参数
         /// </summary>
         /// <param name="refresh_token"></param>
         /// <returns></returns>
         private static List<KeyValuePair<string, string>> BuildRefreshTokenParams(string refresh_token)
         {
             var list = new List<KeyValuePair<string, string>>
             {
                 new KeyValuePair<string, string>("grant_type", "refresh_token"),
                 new KeyValuePair<string, string>("refresh_token", refresh_token),
             };
             return list;
         }

     }

只对ADFS有效,Azure AD没用过应该不适用吧

主要就是模拟表单请求

redirectUri没有实际用户只是取返回的code,可以AllowAutoRedirect=true,返回在redirectUri内做code解析Token再返回
OAuthMessageHandler 单例HttpClient使用
RefreshToken请求返回来的没有 refresh_token 不知道为什么?
 

代码 :

https://github.com/JadynWong/Dynamics365WebAPIClient/blob/master/Standard/D365WebApiClient.Standard/Auth/Dynamics365Auth.cs

Configure Windows Server 2012 R2 for Dynamics 365 applications that use OAuth

参考

https://technet.microsoft.com/en-us/library/hh699726.aspx?f=255&MSPPError=-2147217396

http://www.cloudriven.fi/en/cloud-9-en/how-to-make-dynamics-365-web-api-queries-using-oauth/

https://msdn.microsoft.com/zh-cn/library/gg334767.aspx#bkmk_includeFormattedValues

流程

https://blog.scottlogic.com/2015/03/09/OAUTH2-Authentication-with-ADFS-3.0.html

原文地址:http://www.cnblogs.com/WJvsToo/p/8194288.html

Dynamics365 WebAPI ADFS token 获取的更多相关文章

  1. MVC WebApi 实现Token验证

    基于令牌的认证 我们知道WEB网站的身份验证一般通过session或者cookie完成的,登录成功后客户端发送的任何请求都带上cookie,服务端根据客户端发送来的cookie来识别用户. WEB A ...

  2. ASP.NET WebApi实现Token验证

    记录笔记,在博客园中有很多实现Token的方法,这是我看过他们学到的,然后找到适合自己的解决方案,自己无聊总结一下学习经验写下的 WebApi后端接口实现Token验证 Token是在客户端频繁向服务 ...

  3. Asp.Net WebAPI 中Cookie 获取操作方式

    1. /// <summary> /// 获取上下文中的cookie /// </summary> /// <returns></returns> [H ...

  4. 十二、存token获取token刷新token发送header头

    //测试token //获取token function setToken(data){ var storage = window.localStorage; if(!storage){ alert( ...

  5. golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息

    golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放 ...

  6. Java微信公众平台开发(六)--微信开发中的token获取

    转自:http://www.cuiyongzhi.com/post/44.html (一)token的介绍 引用:access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access ...

  7. c# webapi 过滤器token、sign认证、访问日志

    1.token认证 服务端登录成功后分配token字符串.记录缓存服务器,可设置有效期 var token = Guid.NewGuid().ToString().Replace("-&qu ...

  8. Spring Cloud云架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)

    上一篇我根据框架中OAuth2.0的使用总结,画了SSO单点登录之OAuth2.0 登出流程,今天我们看一下根据用户token获取yoghurt信息的流程: /** * 根据token获取用户信息 * ...

  9. 整合spring cloud云架构 - 根据token获取用户信息

    根据用户token获取yoghurt信息的流程: /** * 根据token获取用户信息 * @param accessToken * @return * @throws Exception */ @ ...

随机推荐

  1. 算法时间计算:logA(N)与O(n)

    算法运行时间估算常见O(log(n))log:求对数例:a^b=na为底数,b为n的对数记作:logA(n)=b  ->求N的对数 计算器验算:计算器的log默认以10为底  输入 10,log ...

  2. LeetCode 第五题 最长的回文字符串 (JAVA)

    Longest Palindromic Substring 简介:字符串中最长的回文字符串 回文字符串:中心对称的字符串 ,如 mom,noon 问题详解: 给定一个字符串s,寻找字符串中最长的回文字 ...

  3. 关于sniff函数的一个小坑

    最近在用scapy模块写一个关于WiFi的脚本时用到sniff函数,其中遇到了一个小坑,记录如下: sniff函数是在指定网卡上每次嗅探到一个数据包后然后将它传给prn指定的函数.

  4. Django组件-forms

    forms组件 校验字段功能 针对一个实例:注册用户 模型:models.py class UserInfo(models.Model): name=models.CharField(max_leng ...

  5. 【转载】IIS出现“HTTP 错误 500.0,C:\php\php-cgi.exe - FastCGI 进程意外退出”解决方法

    昨天给大家介绍了在windows+iis的平台上搭建支持php+mysql平台的文章,教程步骤都是笔者一步一个操作然后一个记录介绍给大家的,实机演练,教程绝对切实可用,但是不同的同学在不同的环境下按照 ...

  6. KNN与K-Means的区别

    KNN(K-Nearest Neighbor)介绍 Wikipedia上的 KNN词条 中有一个比较经典的图如下: KNN的算法过程是是这样的: 从上图中我们可以看到,图中的数据集是良好的数据,即都打 ...

  7. day13-迭代器及生成器

    iterable:可迭代的:iterator:迭代器: print(dir([ ]))  #打印出列表所拥有的所有方法: 可迭代协议:只要含有__iter__方法的都是可迭代的. 迭代器协议:含有__ ...

  8. vs2010编译error_code

    C1083 : 现象: xxxxx.cpp clxx:fatal error C1083:无法打开源文件: “..\..\..\..\src\folder1\folder2\folder3\folde ...

  9. ubantu/centos修改系统时间

    前言:有时系统上的时间和真实的时间对应不是,或者有特殊需求,需要修改系统时间.但是对应多台的服务器系统更改时间,手动的话很麻烦,这就需要写脚本或者搭建时间服务器了,统一时间,以下是对于一个不同系统修改 ...

  10. (四)Knockout 表单

    click <div> You've clicked <span data-bind="text: numberOfClicks"></span> ...