转载

DotNetOpenAuth实践之搭建验证服务器

DotNetOpenAuth是OAuth2的.net版本,利用DotNetOpenAuth我们可以轻松的搭建OAuth2验证服务器,不废话,下面我们来一步步搭建验证服务器

本次搭建环境:

.net4.5.1 ,DotNetOpenAuth v5.0.0-alpha3,MVC5

一、环境搭建

1、新建一个空的VS解决方案

DotNetOpenAuth实践之搭建验证服务器

2、添加验证服务器项目,项目选择MVC,不要自带的身份验证

DotNetOpenAuth实践之搭建验证服务器

DotNetOpenAuth实践之搭建验证服务器

3、使用Nuget添加DotNetOpenAuth v5.0.0-alpha3

DotNetOpenAuth实践之搭建验证服务器

输入DotNetOpenAuth 安装DotNetOpenAuth v5.0.0-alpha3

DotNetOpenAuth实践之搭建验证服务器

添加完成后

DotNetOpenAuth实践之搭建验证服务器

二、编写DotNetOpenAuth 验证服务器关键代码,实现功能

1、添加AuthorizationServerConfiguration.cs

这里的配置是为了添加方便管理,其实可以不用这个类

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Security.Cryptography.X509Certificates;  5 using System.Web;  6   7 namespace IdefavAuthorizationServer.Code  8 {  9     /// <summary> 10     /// 验证服务器配置 11     /// </summary> 12     public class AuthorizationServerConfiguration 13     { 14         /// <summary> 15         /// 构造函数 16         /// </summary> 17         public AuthorizationServerConfiguration() 18         { 19             TokenLifetime = TimeSpan.FromMinutes(5); 20         } 21  22         /// <summary> 23         /// 签名证书 24         /// </summary> 25         public X509Certificate2 SigningCertificate { get; set; } 26  27         /// <summary> 28         /// 加密证书 29         /// </summary> 30         public X509Certificate2 EncryptionCertificate { get; set; } 31  32         /// <summary> 33         /// Token有效时间 34         /// </summary> 35         public TimeSpan TokenLifetime { get; set; } 36     } 37 }

2、实现IClientDescription接口

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Web;  5 using DotNetOpenAuth.Messaging;  6 using DotNetOpenAuth.OAuth2;  7   8 namespace IdefavAuthorizationServer.Code  9 { 10     public class Client : IClientDescription 11     { 12         /// <summary> 13         /// 客户端名称client_id 14         /// </summary> 15         public string Name { get; set; } 16  17         /// <summary> 18         /// 客户端类型 19         /// </summary> 20         public int ClientType { get; set; } 21  22         /// <summary> 23         /// 回调URL 24         /// </summary> 25         public string Callback { get; set; } 26  27         public string ClientSecret { get; set; } 28  29  30         Uri IClientDescription.DefaultCallback 31         { 32             get { return string.IsNullOrEmpty(this.Callback) ? null : new Uri(this.Callback); } 33         } 34  35  36         ClientType IClientDescription.ClientType 37         { 38             get { return (ClientType)this.ClientType; } 39         } 40  41  42         bool IClientDescription.HasNonEmptySecret 43         { 44             get { return !string.IsNullOrEmpty(this.ClientSecret); } 45         } 46  47  48         bool IClientDescription.IsCallbackAllowed(Uri callback) 49         { 50             if (string.IsNullOrEmpty(this.Callback)) 51             { 52                 // No callback rules have been set up for this client. 53                 return true; 54             } 55  56             // In this sample, it's enough of a callback URL match if the scheme and host match. 57             // In a production app, it is advisable to require a match on the path as well. 58             Uri acceptableCallbackPattern = new Uri(this.Callback); 59             if (string.Equals(acceptableCallbackPattern.GetLeftPart(UriPartial.Authority), callback.GetLeftPart(UriPartial.Authority), StringComparison.Ordinal)) 60             { 61                 return true; 62             } 63  64             return false; 65         } 66  67  68         bool IClientDescription.IsValidClientSecret(string secret) 69         { 70             return MessagingUtilities.EqualsConstantTime(secret, this.ClientSecret); 71         } 72  73  74     } 75 }

3、实现IAuthorizationServerHost接口

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Security.Cryptography;  5 using System.Web;  6 using DotNetOpenAuth.Messaging.Bindings;  7 using DotNetOpenAuth.OAuth2;  8 using DotNetOpenAuth.OAuth2.ChannelElements;  9 using DotNetOpenAuth.OAuth2.Messages; 10  11 namespace IdefavAuthorizationServer.Code 12 { 13     public class IdefavAuthorizationServerHost : IAuthorizationServerHost 14     { 15         /// <summary> 16         /// 配置 17         /// </summary> 18         private readonly AuthorizationServerConfiguration _configuration; 19  20         /// <summary> 21         /// 构造函数 22         /// </summary> 23         /// <param name="config"></param> 24         public IdefavAuthorizationServerHost(AuthorizationServerConfiguration config) 25         { 26             if (config != null) 27                 _configuration = config; 28         } 29  30         /// <summary> 31         /// Token创建 32         /// </summary> 33         /// <param name="accessTokenRequestMessage"></param> 34         /// <returns></returns> 35         public AccessTokenResult CreateAccessToken(IAccessTokenRequest accessTokenRequestMessage) 36         { 37             var accessToken = new AuthorizationServerAccessToken(); 38             accessToken.Lifetime = _configuration.TokenLifetime;//设置Token的有效时间 39  40             // 设置加密公钥 41             accessToken.ResourceServerEncryptionKey = 42                 (RSACryptoServiceProvider)_configuration.EncryptionCertificate.PublicKey.Key; 43             // 设置签名私钥 44             accessToken.AccessTokenSigningKey = (RSACryptoServiceProvider)_configuration.SigningCertificate.PrivateKey; 45  46             var result = new AccessTokenResult(accessToken); 47             return result; 48         } 49  50         public IClientDescription GetClient(string clientIdentifier) 51         { 52             // 这里需要去验证客户端发送过来的client_id 53             if (string.Equals(clientIdentifier, "idefav", StringComparison.CurrentCulture))// 这里为了简明起见没有使用数据库 54             { 55                 var client=new Client 56                 { 57                     Name = "idefav", 58                     ClientSecret = "1", 59                     ClientType = 1 60                 }; 61                 return client; 62             } 63             throw new ArgumentOutOfRangeException("clientIdentifier"); 64         } 65  66         public bool IsAuthorizationValid(IAuthorizationDescription authorization) 67         { 68             return true; 69         } 70  71         public AutomatedUserAuthorizationCheckResponse CheckAuthorizeResourceOwnerCredentialGrant(string userName, string password, 72             IAccessTokenRequest accessRequest) 73         { 74             throw new NotImplementedException(); 75         } 76  77         public AutomatedAuthorizationCheckResponse CheckAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest) 78         { 79             AutomatedUserAuthorizationCheckResponse response = new AutomatedUserAuthorizationCheckResponse(accessRequest, true, "test"); 80             return response; 81         } 82  83         public ICryptoKeyStore CryptoKeyStore { get; } 84         public INonceStore NonceStore { get; } 85  86         87     } 88 }

4、实现OAuthController

 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 using System.Threading.Tasks;  5 using System.Web;  6 using System.Web.Mvc;  7 using DotNetOpenAuth.Messaging;  8 using DotNetOpenAuth.OAuth2;  9 using IdefavAuthorizationServer.Code; 10  11 namespace IdefavAuthorizationServer.Controllers 12 { 13     public class OAuthController : Controller 14     { 15         private readonly AuthorizationServer authorizationServer = 16            new AuthorizationServer(new IdefavAuthorizationServerHost(Common.Configuration)); 17  18         public async Task<ActionResult> Token() 19         { 20             var response = await authorizationServer.HandleTokenRequestAsync(Request); 21             return response.AsActionResult(); 22         } 23     } 24 }

5、初始化AuthorizationServerConfiguration

这里采用Windows签名证书

DotNetOpenAuth实践之搭建验证服务器

放到项目中

DotNetOpenAuth实践之搭建验证服务器

制作证书事注意:要加上-a sha1  -sky exchange

到此,基本代码就写完了,现在说说要注意的地方,OAuth2默认设置的请求是要求SSL的也就是必须是https//localhost:1111/OAuth/Token,然后我们现在不需要使用SSL加密请求,更改一下WebConfig文件

DotNetOpenAuth实践之搭建验证服务器

在WebConfig里面设置成如图中那样,就可以不用https访问了

6、我们F5运行项目

使用Post工具发送Post请求访问 http: // localhost:53022/OAuth/token

Body参数:

1 client_id:idefav 2 client_secret:1 3 grant_type:client_credentials

请求结果:

DotNetOpenAuth实践之搭建验证服务器

这样我们就拿到了access_token,通过这个access_token我们就可以访问资源服务器了

正文到此结束
Loading...