DotNetOpenAuth 使用指南
这几天一直在研究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=\"Web\" /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
先别着急下,看看这个:
看到这个标志就别下载了,下载下来后生成是通不过的,怎么样,是不是又想哭了,官方给的样例都是跑不起来的
那看另外一个源码吧:
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 使用指南的更多相关文章
- DotNet 资源大全中文版,内容包括:编译器、压缩、应用框架、应用模板、加密、数据库、反编译、IDE、日志、风格指南等
DotNet 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-dotnet 是由 quozd 发起和维护.内容包括:编译器. ...
- JavaScript权威指南 - 函数
函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...
- UE4新手之编程指南
虚幻引擎4为程序员提供了两套工具集,可共同使用来加速开发的工作流程. 新的游戏类.Slate和Canvas用户接口元素以及编辑器功能可以使用C++语言来编写,并且在使用Visual Studio 或 ...
- JavaScript权威指南 - 对象
JavaScript对象可以看作是属性的无序集合,每个属性就是一个键值对,可增可删. JavaScript中的所有事物都是对象:字符串.数字.数组.日期,等等. JavaScript对象除了可以保持自 ...
- JavaScript权威指南 - 数组
JavaScript数组是一种特殊类型的对象. JavaScript数组元素可以为任意类型,最大容纳232-1个元素. JavaScript数组是动态的,有新元素添加时,自动更新length属性. J ...
- const extern static 终极指南
const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...
- Atitit.研发管理软件公司的软资产列表指南
Atitit.研发管理软件公司的软资产列表指南 1. Isv模型下的软资产1 2. 实现层面implet1 3. 规范spec层1 4. 法则定律等val层的总结2 1. Isv模型下的软资产 Sof ...
- HA 高可用软件系统保养指南
又过了一年 618,六月是公司一年一度的大促月,一般提前一个月各系统就会减少需求和功能的开发,转而更多去关注系统可用性.稳定性和管控性等方面的非功能需求.大促前的准备工作一般叫作「备战」,可以把线上运 ...
- 第六代智能英特尔® 酷睿™ 处理器图形 API 开发人员指南
欢迎查看第六代智能英特尔® 酷睿™ 处理器图形 API 开发人员指南,该处理器可为开发人员和最终用户提供领先的 CPU 和图形性能增强.各种新特性和功能以及显著提高的性能. 本指南旨在帮助软件开发人员 ...
随机推荐
- HDU 1716 排列2 (格式问题+排列)
题意:. 析:我们完全可以STL里面的函数next_permutation(),然后方便,又简单,这个题坑就是在格式上. 行末不能有空格,结尾不能有空行,不大好控制,必须控制好第一次数. 这个题本应该 ...
- 微信post xml 消息编码问题
site:mp.weixin.qq.com utf 微信卡券接口说明 - 微信公众平台开发者文档 所有API接口POST的数据只支持utf8编码,否则会返回报错. 以上是获取的部分信息 这个尽管有点模 ...
- 使用Revel(go)开发网站
Revel很好的利用了Go语言的goroutine,把每一个request都分配到了goroutine里.不用再写一大堆的回调.如果你写过nodejs的话就会深刻的体会到callback hell是什 ...
- 判断tableVIew滑动的方向
首先设置一个旧的偏移量为0; self.oldContent = 0; - (void)scrollViewDidScroll:(UIScrollView *)scrollView { if (scr ...
- 四则运算(Java)--温铭淇,付夏阳
GitHub项目地址: https://github.com/fxyJAVA/Calculation 四则运算项目要求: 程序处理用户需求的模式为: Myapp.exe -n num -r size ...
- Backup--查看备份还原需要的空间
--====================================================== --使用于SQL SERVER 2008 和SQL SERVER 2008 R2 ) ...
- JavaScript模块化与esl.js
2016-2-2 晚上 松合时代公寓中 1.前端为什么需要模块化? http://requirejs.org/docs/why.html 2.https://github.com/ecomfe/esl ...
- Weekly Contest 132
1025. Divisor Game Alice and Bob take turns playing a game, with Alice starting first. Initially, th ...
- robot framework —— 变量文件
何为变量文件? 变量文件中包含了测试数据中的变量.虽然变量可以通过变量表格中创建, 或者通过命令行设置, 不过这些方法有所局限, 而变量文件可以动态地创建任意类型的变量. 变量文件一般由Python模 ...
- 关于Boolean()
Boolean(value); 如果省略 value 参数,或者设置为 0.-0.null."".false.undefined 或 NaN,则该对象设置为 false. 否则设置 ...