这几天一直在研究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. Redis配置总结

    一:常用配置 1.bind,格式为bind 127.0.0.1:这个是很重要的配置,如果bind 127.0.0.1则外部网络是访问不了的(如果外部网络要访问还要开放端口) 2.port,格式为por ...

  2. Spark-1.2.2部署

    1.安装Scala 1.1解压和安装 在Scala官网http://www.scala-lang.org/download/下载Scala安装包,然后解压.(注:JDK的版本最好是1.7及以上,否则S ...

  3. 执行Docker命令报错解决办法

    shim error: docker-runc not installed on system   服务器重启以后,执行docker命令报以上错误,解决办法如下: cd /usr/libexec/do ...

  4. ArcGIS下图层范围不正确的两种处理方式

    ArcGIS下图层范围不正确,偶尔能碰上这种情况,主要表现为“缩放至图层”时,其显示范围与该图层内所有要素的外包围盒范围不一致.针对这个问题,有两种解决办法. 方法一:导出数据.新创建含有要素的Sha ...

  5. Apache Geode with Spark

    在一些特定场景,例如streamingRDD需要和历史数据进行join从而获得一些profile信息,此时形成较小的新数据RDD和很大的历史RDD的join. Spark中直接join实际上效率不高: ...

  6. 记一次IIS站点出错的解决过程

    记一次IIS站点出错的解决过程 以前一直都是人家用着系统出问题了反馈过来这边改,没想到这回就发生在自己使用的过程中 问题经过 我正在执行一个操作,保存了没有返回提示,打开浏览器控制台查看网络,请求返回 ...

  7. 基于Quartz.net的远程任务管理系统 一

    在上一篇绪中,已经介绍了整个项目的情况下了,接下来就是开始一步步做起来了. 首先:先整个我们的Job任务表,以及Job执行日志表.SQL如下: drop table if exists job_inf ...

  8. element ui aside — 侧栏导航菜单移入移出折叠效果

    效果如图,移入移出控制折叠,点击按钮后移入移出不可控制折叠. 功能是很简单的功能,不过昨天这块还是弄了小一个小时,所以记录下来. 发现的问题: 模版上el-aside写上@mouseenter无效 解 ...

  9. 徒手画个disk不容易啊。。。

    static const GLfloat disk_vertex_buffer_data[] = { // quarter 1 0.0f, 0.0f, -1.0f, 0.707f, 0.0f, -0. ...

  10. 理解DDoS防护本质:基于资源较量和规则过滤的智能化系统

    本文由  网易云发布. 随着互联网生态逐渐形成,DDoS防护已经成为互联网企业的刚需要求,网易云安全(易盾)工程师根据DDoS的方方面面,全面总结DDoS的攻防对抗. 1.什么是DDoS DDoS全称 ...