DotNetOpenAuth搭建驗證伺服器
本次搭建環境:
.net4.5.1 ,DotNetOpenAuth v5.0.0-alpha3,MVC5
一、環境搭建
1、建立一個空的VS解決方案
2、添加驗證伺服器項目,項目選擇MVC,不要內建的身分識別驗證
3、使用Nuget添加DotNetOpenAuth v5.0.0-alpha3
輸入DotNetOpenAuth 安裝DotNetOpenAuth v5.0.0-alpha3
添加完成後
二、編寫DotNetOpenAuth 驗證伺服器關鍵代碼,實現功能
1、添加AuthorizationServerConfiguration.cs
這裡的配置是為了添加方便管理,其實可以不用這個類
using System;using System.Collections.Generic;using System.Linq;using System.Security.Cryptography.X509Certificates;using System.Web;namespace IdefavAuthorizationServer.Code{ /// <summary> /// 驗證伺服器配置 /// </summary> public class AuthorizationServerConfiguration { /// <summary> /// 建構函式 /// </summary> public AuthorizationServerConfiguration() { TokenLifetime = TimeSpan.FromMinutes(5); } /// <summary> /// 簽署憑證 /// </summary> public X509Certificate2 SigningCertificate { get; set; } /// <summary> /// 加密認證 /// </summary> public X509Certificate2 EncryptionCertificate { get; set; } /// <summary> /// Token有效時間 /// </summary> public TimeSpan TokenLifetime { get; set; } }}
2、實現IClientDescription介面
using System;using System.Collections.Generic;using System.Linq;using System.Web;using DotNetOpenAuth.Messaging;using DotNetOpenAuth.OAuth2;namespace IdefavAuthorizationServer.Code{ public class Client : IClientDescription { /// <summary> /// 用戶端名稱client_id /// </summary> public string Name { get; set; } /// <summary> /// 用戶端類型 /// </summary> public int ClientType { get; set; } /// <summary> /// 回調URL /// </summary> public string Callback { get; set; } public string ClientSecret { get; set; } Uri IClientDescription.DefaultCallback { get { return string.IsNullOrEmpty(this.Callback) ? null : new Uri(this.Callback); } } ClientType IClientDescription.ClientType { get { return (ClientType)this.ClientType; } } bool IClientDescription.HasNonEmptySecret { get { return !string.IsNullOrEmpty(this.ClientSecret); } } bool IClientDescription.IsCallbackAllowed(Uri callback) { if (string.IsNullOrEmpty(this.Callback)) { // No callback rules have been set up for this client. return true; } // In this sample, it's enough of a callback URL match if the scheme and host match. // In a production app, it is advisable to require a match on the path as well. Uri acceptableCallbackPattern = new Uri(this.Callback); if (string.Equals(acceptableCallbackPattern.GetLeftPart(UriPartial.Authority), callback.GetLeftPart(UriPartial.Authority), StringComparison.Ordinal)) { return true; } return false; } bool IClientDescription.IsValidClientSecret(string secret) { return MessagingUtilities.EqualsConstantTime(secret, this.ClientSecret); } }}
3、實現IAuthorizationServerHost介面
using System;using System.Collections.Generic;using System.Linq;using System.Security.Cryptography;using System.Web;using DotNetOpenAuth.Messaging.Bindings;using DotNetOpenAuth.OAuth2;using DotNetOpenAuth.OAuth2.ChannelElements;using DotNetOpenAuth.OAuth2.Messages;namespace IdefavAuthorizationServer.Code{ public class IdefavAuthorizationServerHost : IAuthorizationServerHost { /// <summary> /// 配置 /// </summary> private readonly AuthorizationServerConfiguration _configuration; /// <summary> /// 建構函式 /// </summary> /// <param name="config"></param> public IdefavAuthorizationServerHost(AuthorizationServerConfiguration config) { if (config != null) _configuration = config; } /// <summary> /// Token建立 /// </summary> /// <param name="accessTokenRequestMessage"></param> /// <returns></returns> public AccessTokenResult CreateAccessToken(IAccessTokenRequest accessTokenRequestMessage) { var accessToken = new AuthorizationServerAccessToken(); accessToken.Lifetime = _configuration.TokenLifetime;//設定Token的有效時間 // 設定加密公開金鑰 accessToken.ResourceServerEncryptionKey = (RSACryptoServiceProvider)_configuration.EncryptionCertificate.PublicKey.Key; // 設定簽名私密金鑰 accessToken.AccessTokenSigningKey = (RSACryptoServiceProvider)_configuration.SigningCertificate.PrivateKey; var result = new AccessTokenResult(accessToken); return result; } public IClientDescription GetClient(string clientIdentifier) { // 這裡需要去驗證用戶端發送過來的client_id if (string.Equals(clientIdentifier, "idefav", StringComparison.CurrentCulture))// 這裡為了簡明起見沒有使用資料庫 { var client=new Client { Name = "idefav", ClientSecret = "1", ClientType = 1 }; return client; } throw new ArgumentOutOfRangeException("clientIdentifier"); } public bool IsAuthorizationValid(IAuthorizationDescription authorization) { return true; } public AutomatedUserAuthorizationCheckResponse CheckAuthorizeResourceOwnerCredentialGrant(string userName, string password, IAccessTokenRequest accessRequest) { throw new NotImplementedException(); } public AutomatedAuthorizationCheckResponse CheckAuthorizeClientCredentialsGrant(IAccessTokenRequest accessRequest) { AutomatedUserAuthorizationCheckResponse response = new AutomatedUserAuthorizationCheckResponse(accessRequest, true, "test"); return response; } public ICryptoKeyStore CryptoKeyStore { get; } public INonceStore NonceStore { get; } }}
4、實現OAuthController
using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Web;using System.Web.Mvc;using DotNetOpenAuth.Messaging;using DotNetOpenAuth.OAuth2;using IdefavAuthorizationServer.Code;namespace IdefavAuthorizationServer.Controllers{ public class OAuthController : Controller { private readonly AuthorizationServer authorizationServer = new AuthorizationServer(new IdefavAuthorizationServerHost(Common.Configuration)); public async Task<ActionResult> Token() { var response = await authorizationServer.HandleTokenRequestAsync(Request); return response.AsActionResult(); } }}
5、初始化AuthorizationServerConfiguration
這裡採用Windows簽署憑證
放到項目中
製作認證事注意:要加上-a sha1 -sky exchange
到此,基本代碼就寫完了,現在說說要注意的地方,OAuth2預設設定的請求是要求SSL的也就是必須是https//localhost:1111/OAuth/Token,然後我們現在不需要使用SSL加密請求,更改一下WebConfig檔案
在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
請求結果:
這樣我們就拿到了access_token,通過這個access_token我們就可以訪問資原始伺服器了
更新:
OAuthController代碼新增內容類型
using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Web;using System.Web.Mvc;using System.Web.Script.Services;using DotNetOpenAuth.Messaging;using DotNetOpenAuth.OAuth2;using IdefavAuthorizationServer.Code;namespace IdefavAuthorizationServer.Controllers{ public class OAuthController : Controller { private readonly AuthorizationServer authorizationServer = new AuthorizationServer(new IdefavAuthorizationServerHost(Common.Configuration)); public async Task<ActionResult> Token() { var response = await authorizationServer.HandleTokenRequestAsync(Request); Response.ContentType = response.Content.Headers.ContentType.ToString(); return response.AsActionResult(); } }}
DotNetOpenAuth製作Windows簽名
一、工具
makecert.exe,cert2spc.exe,pvk2pfx.exe
百度網盤地址:
連結:http://pan.baidu.com/s/1ntOq3Cd 密碼:j2rn
二、製作
1、建立一個自己簽署的認證和一個私密金鑰檔案用到makecert工具
命令:
makecert -a sha1 -sky exchange -n "CN=發行者名稱" -b 10/18/2015 -e 01/01/2018 -sv 你的名稱.pvk 你的名稱.cer
開啟命令列,並定位到makecert.exe所在目錄
輸入命令
例如: makecert -a sha1 -sky exchange -n "CN=idefav" -b 10/18/2015 -e 01/01/2018 -sv test.pvk test.cer
斷行符號之後,彈出私密金鑰加密密碼
輸入密碼後,目錄裡面就產生了cer和pvk檔案
2、利用認證.cer建立發行者認證.spc,用到cert2spc工具
命令:
cert2spc 你的名稱.cer 你的名稱.spc
輸入命令產生spc檔案
3、從.pvk和.spc格式轉換成.pfx格式,用到pvk2pfx工具
命令:
pvk2pfx -pvk 你的名稱.pvk -pi pvk密碼 -spc 你的名稱.spc
注意:pvk密碼就是上次彈出輸入的密碼
輸入命令斷行符號,彈出認證匯出嚮導
這樣cer和pfx就製作完成了,下面我們把這兩個檔案放到上篇製作的項目中去
改一下Global.axax中的初始化代碼
運行項目使用post工具訪問
成功擷取access_token