这几天一直在研究DotNetOpenAuth,源码处处是坑啊!写此文只为大家更顺利掌握DotNetOpenAuth使用方法,尽量少走弯路。

说明一下:我的环境是Win7 64   VS2015 update2

废话少说,踏坑开始:

新建项目:

右键引用:

搜索 dotnetopenauth,勾选包括预发行版:

提示安装一大堆东西:

可以看到Web.config添加了很多东西,稍后再讲这个

diff --git a/MvcOAuthServer/MvcAuth2Client/Web.config b/MvcOAuthServer/MvcAuth2Client/Web.config
index 5da5b22..ef7ea07
--- a/MvcOAuthServer/MvcAuth2Client/Web.config
+++ b/MvcOAuthServer/MvcAuth2Client/Web.config
@@ -, +, @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!--
   For more information on how to configure your ASP.NET application, please visit
   http://go.microsoft.com/fwlink/?LinkId=301880
@@ -, +, @@
   <configSections>
     <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
     <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
-  </configSections>
+  <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core">
+            <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+            <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+        <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true" /><section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth.OpenId" requirePermission="false" allowLocation="true" /></sectionGroup></configSections>
   <connectionStrings>
-    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-MvcAuth2Client-20160504102822.mdf;Initial Catalog=aspnet-MvcAuth2Client-20160504102822;Integrated Security=True"
-      providerName="System.Data.SqlClient" />
+    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-MvcAuth2Client-20160504102822.mdf;Initial Catalog=aspnet-MvcAuth2Client-20160504102822;Integrated Security=True" providerName="System.Data.SqlClient" />
   </connectionStrings>
   <appSettings>
     <add key="webpages:Version" value="3.0.0.0" />
@@ -, +, @@
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
-        <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
+        <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
         <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
       </dependentAssembly>
     </assemblyBinding>
-  </runtime>
+  <!-- This prevents the Windows Event Log ,  and  references relink
+             to MVC  so libraries such  will work with it.
+        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+            <dependentAssembly>
+                <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
+                <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
+            </dependentAssembly>
+        </assemblyBinding>
+         --></runtime>
   <entityFramework>
     <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
       <parameters>
@@ -, +, @@
       <compiler language=" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
     </compilers>
   </system.codedom>
-</configuration>
\ No newline at end of file
+<system.net>
+        <defaultProxy enabled="true" />
+        <settings>
+            <!-- This setting causes .NET to check certificate revocation lists (CRL)
+                 before trusting HTTPS certificates.  But this setting tends to not
+                 be allowed in shared hosting environments. -->
+            <!--<servicePointManager checkCertificateRevocationList="true"/>-->
+        </settings>
+    </system.net><dotNetOpenAuth>
+        <messaging>
+            <untrustedWebRequest>
+                <whitelistHosts>
+                    <!-- Uncomment to enable communication with localhost (should generally not activate in production!) -->
+                    <!--<add name="localhost" />-->
+                </whitelistHosts>
+            </untrustedWebRequest>
+        </messaging>
+        <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
+        <reporting enabled="true" />
+    <!-- This is an optional configuration section where aspects of dotnetopenauth can be customized. --><!-- For a complete set of configuration options see http://www.dotnetopenauth.net/developers/code-snippets/configuration-options/ --><openid>
+        <provider>
+            </provider><relyingParty>
+                <security requireSsl="false">
+                    <!-- Uncomment the trustedProviders tag if your relying party should only accept positive assertions from a closed set of OpenID Providers. -->
+                    <!--<trustedProviders rejectAssertionsFromUntrustedProviders="true">
+                        <add endpoint="https://www.google.com/accounts/o8/ud" />
+                    </trustedProviders>-->
+                </security>
+                <behaviors>
+                    <!-- The following OPTIONAL behavior allows RPs to use SREG only, but be compatible
+                         with OPs that use Attribute Exchange (in various formats). -->
+                    <add type="DotNetOpenAuth.OpenId.RelyingParty.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth.OpenId.RelyingParty" />
+                </behaviors>
+            </relyingParty></openid></dotNetOpenAuth><uri>
+        <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+             which is necessary for OpenID urls with unicode characters in the domain/host name.
+             It  escaping mode, which OpenID and OAuth require. -->
+        <idn enabled="All" />
+        <iriParsing enabled="true" />
+    </uri></configuration>
\ No newline at end of file

其实真正用到的只有这三个:

可以把其它的删掉。

添加一个空控制器:

修改AuthorizeController的内容:

 public class AuthorizeController : Controller
    {
        private static readonly WebServerClient Client;
        private static AuthorizationServerDescription authServerDescription = new AuthorizationServerDescription
        {
            TokenEndpoint = new Uri("http://localhost:50172/OAuth/Token"),
            AuthorizationEndpoint = new Uri("http://localhost:50172/OAuth/Authorize"),
        };
        static AuthorizeController()
        {
            Client = new WebServerClient(authServerDescription, "sampleconsumer", "samplesecret");
        }

        public async Task<ActionResult> Index()
        {
            IAuthorizationState authorization = await Client.ProcessUserAuthorizationAsync(Request, Response.ClientDisconnectedToken);
            if (authorization == null)
            {
                List<string> scopes = new List<string>();
                scopes.Add("http://tempuri.org/IDataApi/GetName");
                var request =
                                await Client.PrepareRequestUserAuthorizationAsync(scopes, cancellationToken: Response.ClientDisconnectedToken);
                await request.SendAsync();
                return Content("done");
            }
            else
            {
                TimeSpan timeLeft = authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
                string token = authorization.AccessToken;
                ));
                return Content(result);
            }
        }
    }

运行吧http://localhost:18180/Authorize

报错了吧:

是不是想哭,这个问题我在网上找了很久,还是在http://stackoverflow.com/  上找到了答案

凶手就是System.Net.Http.Formatting

这个是Microsoft.AspNet.WebApi.Client 包里的,DotNetOpenAuth所依赖的版本是4.0.0,所以要替换下,打开Nuget包管理器,搜索Microsoft.AspNet.WebApi.Client,

在右侧版本下拉框中拉到最下面,选4.0.20505

结果又报错了:

这里需要在选项中依赖项行为从最低改成忽略依赖项:

再点更新就出现了熟悉的窗口了:

可以看到Web.config中的变化:

      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
      </dependentAssembly>

确认下版本:

再次运行,又报错了

是不是又要哭了,没关系,接着来。

打开:https://github.com/DotNetOpenAuth

先看 DotNetOpenAuth.Samples

先别着急下,看看这个:

看到这个标志就别下载了,下载下来后生成是通不过的,怎么样,是不是又想哭了,官方给的样例都是跑不起来的

那看另外一个源码吧:

https://github.com/DotNetOpenAuth/DotNetOpenAuth

还好这个是编译通过的,下到本地,解压,打开,重新生成,这里会自动加载程序包

如果你的VS没有开启自动下载程序包的话需要手动开启:

提示重新生成成功,可是在输出窗口又出了一堆错:

看到这里是不是要疯了。。。

很多人在这个时候就崩溃了,我也是,可是我在另外一台电脑上输出窗口是关闭了的,我没看到这个提示,于是我把OAuthAuthorizationServer设置为启动项目就跑起来了:

结果发现即便输出窗口报错也是能跑起来的,这个时候你的内心一定是极度崩溃的。。。

好了,服务端开启后再开启客户端:OAuthClient

然后你就会发现源码里的这个跑起来是没有问题的,并没有报我们自己项目里的那个错误,好吧,这个时候就要看看到底是哪里不同

还是这三个dll:

DotNetOpenAuth.Core

DotNetOpenAuth.OAuth2

DotNetOpenAuth.OAuth2.Client

在VS中看两个项目中都是5.0.0.0,完全一样,但当你在Windows中打开时就有区别了:

左边是自己项目里的,右边是源码中引用的,废话不多说,把自己项目里的这三个都替换成源码里的

再次运行:http://localhost:18180/Authorize

提示要求Https,这里可以改下配置

修改dotNetOpenAuth.messaging节点:

<!-- Relaxing SSL requirements is useful for simple samples, but NOT a good idea in production. -->
        <messaging relaxSslRequirements="true">
            <untrustedWebRequest>
                <whitelistHosts>
                    <!-- Uncomment to enable communication with localhost (should generally not activate in production!) -->
                    <!--<add name="localhost" />-->
                </whitelistHosts>
            </untrustedWebRequest>
        </messaging>

但是生产环境不建议这么做,稍后会介绍搭建Https。

修改后再运行就没问题了,当然,现在还没有搭建服务端,那就先用源码的服务端来测试吧。

修改源码-->Sample-->OAuth2-->OAuthAuthorizationServer  中Web.config中的数据库连接:

<connectionStrings>
        <add name="DatabaseConnectionString"
            connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=DotNetOpenAuth;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
            providerName="System.Data.SqlClient"/>
    </connectionStrings>

运行,Home中有一个创建数据库按钮

点击即可创建数据库

此时可以看到数据库新增了5张表:

并增加了测试Client:

此时再打开我们自己的网站:http://localhost:18180/Authorize

会跳转到登录页面:

要求输入OpenID,这里的OpenID就是授权的系统,一般是一个Url,因为URL是唯一的,这里先用源码中提供的:http://localhost:4864/

这里需要说明一下,源码启动后会在IIS Express中启动多个网站:

输入OpenID后点击登录:

会跳转到OpenID网站的登录页面,如果是Google的话就会跳转到Google的登录页面:

这里使用下面的用户名和密码登录即可:

登录后会询问用户是否可以授权:

授权后我们就拿到access token 了,之后就可以使用token访问其它资源了。

再看一下数据库的变化:

到这里差不多就可以了。

顺便看看怎么使用Google和Facebook的服务:

需要引用DotNetOpenAuth.ApplicationBlock,这个dll在源码里可以找到。

添加GoogleController:

写入代码:

public class GoogleController : Controller
    {
        private static readonly GoogleClient googleClient = new GoogleClient
        {
            ClientIdentifier = ConfigurationManager.AppSettings["googleClientID"],
            ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(ConfigurationManager.AppSettings["googleClientSecret"]),
        };

        public async Task<ActionResult> Index()
        {
            IAuthorizationState authorization = await googleClient.ProcessUserAuthorizationAsync(Request, Response.ClientDisconnectedToken);
            if (authorization == null)
            {
                var request = await googleClient.PrepareRequestUserAuthorizationAsync(scopes: new[]
                {
                    GoogleClient.Scopes.UserInfo.Profile,
                    GoogleClient.Scopes.UserInfo.Email
                }, cancellationToken: Response.ClientDisconnectedToken);
                await request.SendAsync();
                Response.End();
                return Content("Done");
            }
            else
            {
                IOAuth2Graph oauth2Graph = await googleClient.GetGraphAsync(authorization, cancellationToken: Response.ClientDisconnectedToken);

                var name = HttpUtility.HtmlEncode(oauth2Graph.Email);
                return Content("成功授权! Email: " + name);
            }
        }
    }

在web.config中加入配置:

打开https://console.developers.google.com/apis

设置回调地址:

因为Google要求是Https的,所以我们的服务器也要配置Https:

打开项目属性,启用SSL

启动网站,导航到:https://localhost:44337/google

页面跳转到Google进行登录:

登录成功询问授权:

然后就可以调用Google的服务了,比如这里可以拿到Email。

使用Facebook登录的原理是一样的:

public class FacebookController : Controller
    {
        private static readonly FacebookClient facebookClient = new FacebookClient
        {
            ClientIdentifier = ConfigurationManager.AppSettings["facebookAppID"],
            ClientCredentialApplicator = ClientCredentialApplicator.PostParameter(ConfigurationManager.AppSettings["facebookAppSecret"]),
        };
        public async Task<ActionResult> Index()
        {
            IAuthorizationState authorization = await facebookClient.ProcessUserAuthorizationAsync(Request, Response.ClientDisconnectedToken);
            if (authorization == null)
            {
                var request = await facebookClient.PrepareRequestUserAuthorizationAsync(scopes: new[]
                {
                    FacebookClient.Scopes.Email,
                    FacebookClient.Scopes.UserBirthday,
                    //FacebookClient.Scopes.ReadFriendlists,
                    FacebookClient.Scopes.ReadInsights,
                    FacebookClient.Scopes.UserAboutMe,
                    //FacebookClient.Scopes.UserActivities
                },cancellationToken: Response.ClientDisconnectedToken);
                await request.SendAsync();
                Response.End();
                return Content("Done");
            }
            else
            {
                IOAuth2Graph oauth2Graph = await facebookClient.GetGraphAsync(authorization, cancellationToken: Response.ClientDisconnectedToken);
                //// IOAuth2Graph oauth2Graph = facebookClient.GetGraph(authorization, new[] { FacebookGraph.Fields.Defaults, FacebookGraph.Fields.Email, FacebookGraph.Fields.Picture, FacebookGraph.Fields.Birthday });

                var name = HttpUtility.HtmlEncode(oauth2Graph.Name);
                return Content(name);
            }
        }
    }

当然,可以看到上面的代码中注释了两行,原因如下:

这就是使用DotNetOpenAuth的Client进行认证,当然你也可以自己实现,先到授权服务器拿到授权码,然后带着这个授权码去获取token,拿到token后访问接口服务

只不过实现个过程比较繁琐,而OAUTH2是个标准,所以直接使用封装好的Client也没有什么问题。

下一篇会介绍使用DotNetOpenAuth搭建自己的授权服务器。

DotNetOpenAuth 使用指南的更多相关文章

  1. DotNet 资源大全中文版,内容包括:编译器、压缩、应用框架、应用模板、加密、数据库、反编译、IDE、日志、风格指南等

    DotNet 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-dotnet 是由 quozd 发起和维护.内容包括:编译器. ...

  2. JavaScript权威指南 - 函数

    函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...

  3. UE4新手之编程指南

    虚幻引擎4为程序员提供了两套工具集,可共同使用来加速开发的工作流程. 新的游戏类.Slate和Canvas用户接口元素以及编辑器功能可以使用C++语言来编写,并且在使用Visual Studio 或 ...

  4. JavaScript权威指南 - 对象

    JavaScript对象可以看作是属性的无序集合,每个属性就是一个键值对,可增可删. JavaScript中的所有事物都是对象:字符串.数字.数组.日期,等等. JavaScript对象除了可以保持自 ...

  5. JavaScript权威指南 - 数组

    JavaScript数组是一种特殊类型的对象. JavaScript数组元素可以为任意类型,最大容纳232-1个元素. JavaScript数组是动态的,有新元素添加时,自动更新length属性. J ...

  6. const extern static 终极指南

    const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...

  7. Atitit.研发管理软件公司的软资产列表指南

    Atitit.研发管理软件公司的软资产列表指南 1. Isv模型下的软资产1 2. 实现层面implet1 3. 规范spec层1 4. 法则定律等val层的总结2 1. Isv模型下的软资产 Sof ...

  8. HA 高可用软件系统保养指南

    又过了一年 618,六月是公司一年一度的大促月,一般提前一个月各系统就会减少需求和功能的开发,转而更多去关注系统可用性.稳定性和管控性等方面的非功能需求.大促前的准备工作一般叫作「备战」,可以把线上运 ...

  9. 第六代智能英特尔® 酷睿™ 处理器图形 API 开发人员指南

    欢迎查看第六代智能英特尔® 酷睿™ 处理器图形 API 开发人员指南,该处理器可为开发人员和最终用户提供领先的 CPU 和图形性能增强.各种新特性和功能以及显著提高的性能. 本指南旨在帮助软件开发人员 ...

随机推荐

  1. HDU 1716 排列2 (格式问题+排列)

    题意:. 析:我们完全可以STL里面的函数next_permutation(),然后方便,又简单,这个题坑就是在格式上. 行末不能有空格,结尾不能有空行,不大好控制,必须控制好第一次数. 这个题本应该 ...

  2. 微信post xml 消息编码问题

    site:mp.weixin.qq.com utf 微信卡券接口说明 - 微信公众平台开发者文档 所有API接口POST的数据只支持utf8编码,否则会返回报错. 以上是获取的部分信息 这个尽管有点模 ...

  3. 使用Revel(go)开发网站

    Revel很好的利用了Go语言的goroutine,把每一个request都分配到了goroutine里.不用再写一大堆的回调.如果你写过nodejs的话就会深刻的体会到callback hell是什 ...

  4. 判断tableVIew滑动的方向

    首先设置一个旧的偏移量为0; self.oldContent = 0; - (void)scrollViewDidScroll:(UIScrollView *)scrollView { if (scr ...

  5. 四则运算(Java)--温铭淇,付夏阳

    GitHub项目地址: https://github.com/fxyJAVA/Calculation 四则运算项目要求: 程序处理用户需求的模式为: Myapp.exe -n num -r size ...

  6. Backup--查看备份还原需要的空间

    --====================================================== --使用于SQL SERVER 2008 和SQL SERVER 2008 R2 ) ...

  7. JavaScript模块化与esl.js

    2016-2-2 晚上 松合时代公寓中 1.前端为什么需要模块化? http://requirejs.org/docs/why.html 2.https://github.com/ecomfe/esl ...

  8. Weekly Contest 132

    1025. Divisor Game Alice and Bob take turns playing a game, with Alice starting first. Initially, th ...

  9. robot framework —— 变量文件

    何为变量文件? 变量文件中包含了测试数据中的变量.虽然变量可以通过变量表格中创建, 或者通过命令行设置, 不过这些方法有所局限, 而变量文件可以动态地创建任意类型的变量. 变量文件一般由Python模 ...

  10. 关于Boolean()

    Boolean(value); 如果省略 value 参数,或者设置为 0.-0.null."".false.undefined 或 NaN,则该对象设置为 false. 否则设置 ...