DotNetOpenAuth实践之搭建验证服务器

系列目录:

DotNetOpenAuth实践系列(源码在这里)

 

 

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

本次搭建环境:

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

 

一、环境搭建

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

DotNetOpenAuth实践之搭建验证服务器_第1张图片

 

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

DotNetOpenAuth实践之搭建验证服务器_第2张图片

DotNetOpenAuth实践之搭建验证服务器_第3张图片

 

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

DotNetOpenAuth实践之搭建验证服务器_第4张图片

输入DotNetOpenAuth 安装DotNetOpenAuth v5.0.0-alpha3

DotNetOpenAuth实践之搭建验证服务器_第5张图片

添加完成后

DotNetOpenAuth实践之搭建验证服务器_第6张图片

 

二、编写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实践之搭建验证服务器_第7张图片

放到项目中

DotNetOpenAuth实践之搭建验证服务器_第8张图片

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

 

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

DotNetOpenAuth实践之搭建验证服务器_第9张图片

在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实践之搭建验证服务器_第10张图片

 

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

 

 

 

更新:

OAuthController代码添加内容类型

 1 using System.Collections.Generic;
 2 using System.Linq;
 3 using System.Threading.Tasks;
 4 using System.Web;
 5 using System.Web.Mvc;
 6 using System.Web.Script.Services;
 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             Response.ContentType = response.Content.Headers.ContentType.ToString(); 22             return response.AsActionResult();
23         }
24     }
25 }

 

鉴于有人不知道Windows签名制作,下篇我们一起来看看如何制作一个认证服务器可以使用的签名证书

你可能感兴趣的:(DotNetOpenAuth实践之搭建验证服务器)