系列目錄:
DotNetOpenAuth實踐系列(源碼在這里)
上篇我們講到WCF服務作為資源服務器接口提供數據服務,那么這篇我們介紹WebApi作為資源服務器,下面開始:
一、環境搭建
1、新建WebAPI項目
2、利用Nuget添加DotNetOpenAuth
注意:
Nuget里面的 NotNetOpenAuth 5.0.0 alpha3有bug,要到github(DotNetOpenAuth)里面下源碼自己編譯,用編譯的dll替換掉Nuget引用的dll
3、把上次制作的證書文件拷貝的項目中
二、關鍵代碼編寫
1、公共代碼
ResourceServerConfiguration
1 using System.Security.Cryptography.X509Certificates; 2 3 namespace WebApiResourcesServer.Code 4 { 5 public class ResourceServerConfiguration 6 { 7 public X509Certificate2 EncryptionCertificate { get; set; } 8 public X509Certificate2 SigningCertificate { get; set; } 9 } 10 }
Common.cs
1 namespace WebApiResourcesServer.Code 2 { 3 public class Common 4 { 5 public static ResourceServerConfiguration Configuration = new ResourceServerConfiguration(); 6 } 7 }
Global.cs
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Security.Cryptography.X509Certificates; 5 using System.Web; 6 using System.Web.Http; 7 using System.Web.Mvc; 8 using System.Web.Optimization; 9 using System.Web.Routing; 10 using WebApiResourcesServer.Code; 11 12 namespace WebApiResourcesServer 13 { 14 public class WebApiApplication : System.Web.HttpApplication 15 { 16 protected void Application_Start() 17 { 18 Common.Configuration = new ResourceServerConfiguration 19 { 20 EncryptionCertificate = new X509Certificate2(Server.MapPath("~/Certs/idefav.pfx"), "a"), 21 SigningCertificate = new X509Certificate2(Server.MapPath("~/Certs/idefav.cer")) 22 }; 23 AreaRegistration.RegisterAllAreas(); 24 GlobalConfiguration.Configure(WebApiConfig.Register); 25 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 26 RouteConfig.RegisterRoutes(RouteTable.Routes); 27 BundleConfig.RegisterBundles(BundleTable.Bundles); 28 } 29 } 30 }
注意:
這里有個地方要注意,就是認證服務器上面用公鑰加密,在資源服務器要用私鑰解密,所以ResourceServeConfiguration里面傳進去的證書是和認證服務器里面的是對調的
2、重寫DelegatingHandler
1 using DotNetOpenAuth.OAuth2; 2 using System; 3 using System.Net.Http; 4 using System.Security.Cryptography; 5 using System.Security.Principal; 6 using System.Threading; 7 using System.Threading.Tasks; 8 using System.Web; 9 10 namespace WebApiResourcesServer.Code 11 { 12 public class OAuth2Handler : DelegatingHandler 13 { 14 private static async Task<IPrincipal> VerifyOAuth2(HttpRequestMessage httpDetails, params string[] requiredScopes) 15 { 16 // for this sample where the auth server and resource server are the same site, 17 // we use the same public/private key. 18 var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer((RSACryptoServiceProvider)Common.Configuration.SigningCertificate.PublicKey.Key, (RSACryptoServiceProvider)Common.Configuration.EncryptionCertificate.PrivateKey)); 19 return await resourceServer.GetPrincipalAsync(httpDetails, requiredScopes: requiredScopes); 20 } 21 22 protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 23 { 24 if (request.Headers.Authorization != null && request.Headers.Authorization.Scheme == "Bearer") 25 { 26 27 var principal =VerifyOAuth2(request); 28 29 if (principal.Result != null) 30 { 31 HttpContext.Current.User = principal.Result; 32 Thread.CurrentPrincipal = principal.Result; 33 } 34 35 36 } 37 38 return base.SendAsync(request, cancellationToken); 39 } 40 41 } 42 }
3、App_Start/WebApiConfig.cs里面添加OAuthHandler
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web.Http; 5 using WebApiResourcesServer.Code; 6 7 namespace WebApiResourcesServer 8 { 9 public static class WebApiConfig 10 { 11 public static void Register(HttpConfiguration config) 12 { 13 // Web API 配置和服務 14 config.MessageHandlers.Add(new OAuth2Handler()); 15 // Web API 路由 16 config.MapHttpAttributeRoutes(); 17 18 config.Routes.MapHttpRoute( 19 name: "DefaultApi", 20 routeTemplate: "api/{controller}/{id}", 21 defaults: new { id = RouteParameter.Optional } 22 ); 23 } 24 } 25 }
4、設置要驗證的接口
三、測試
打開解決方案屬性,設置啟動項目,啟動認證服務器和WebApi資源服務器
利用Post工具訪問認證服務器獲取access_token
本次獲取的Token的有效期為5分鍾,超過5分鍾要重新獲取
用access_token范圍WebAPI接口
我們手動改一下Token
下篇我們看一下Webform的ashx做的接口如何做資源服務器實現Authorization