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. spring cloud(学习笔记)高可用注册中心(Eureka)的实现(一)

    最近在学习的时候,发现微服务架构中,假如只有一个注册中心,那这个注册中心挂了可怎么办,这样的系统,既不安全,稳定性也不好,网上和书上找了一会,发现这个spring cloud早就想到了,并帮我们解决了 ...

  2. Centos 05 系统目录讲解

    本节内容 1.linux目录结构 2.主目录功能简介 3.重要子目录 linux目录结构 在linux里面,逻辑上所有目录只有一个顶点,根是所有目录的起点. 根下面是类似一个倒挂的树一样的层次结构 可 ...

  3. 【洛谷P1706全排列问题】

    题目描述 输出自然数1到n所有不重复的排列,即n的全排列,要求所产生的任一数字序列中不允许出现重复的数字. 代码如下: #include<iostream>#include<cstd ...

  4. 【原创】大叔问题定位分享(14)Kylin频繁OOM问题

    公司一个kylin集群,每到周二下午就会逐个节点OOM退出,非常有规律,kylin集群5个节点,每个节点分配的内存已经不断增加到70多G,但是问题依旧: 经排查发现,每周二下午kylin集群的请求量确 ...

  5. 使用Elasticsearch-dump迁移ES数据

    1. Elasticsearch-dump 安装 1) yum install epel-release 2) yum install nodejs 3) yum install nodejs npm ...

  6. Source Code Review

    1.berfore we talking abnout the Source Code review,here's what we want to know about the most popula ...

  7. 使用font awesome制作网站常用社交工具联系方式图标

    在公司项目或者个人建站时经常会有这么一个需求,就是在网站的底部以图标的形式加入自己的某些常用社交联系方式,比如QQ.微信.微博.Twitter等等,如果采用传统切图的方式去制作这些图标会有两个缺点: ...

  8. 百度地图api文档实现任意两点之间的最短路线规划

    两个点之间的路线是使用“Marker”点连接起来的,目前还没找到改变点颜色的方法,测试过使用setStyle没有效果. <html><head> <meta http-e ...

  9. Knockout中ko.utils中处理数组的方法集合

    每一套框架基本上都会有一个工具类,如:Vue中的Vue.util.Knockout中的ko.utils.jQuery直接将一些工具类放到了$里面,如果你还需要更多的工具类可以试试lodash.本文只介 ...

  10. Java Spring Boot VS .NetCore (九) Spring Security vs .NetCore Security

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...