Web API在OWIN下實現OAuth
OAuth(Open Authorization)
為用戶資源的授權提供了一個安全的、開放而又簡易的標准。與以往的授權方式不同之處是OAuth的授權不會使第三方觸及到用戶的帳號信息(如用戶名與密碼),即第三方無需使用用戶的用戶名與密碼就可以申請獲得該用戶資源的授權,因此OAuth是安全的。
本節目錄:
1.創建一個控制台項目(其實類庫都可以)ApiServer
Nuget引用:
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost
或者引用以下三個
Install-Package Microsoft.AspNet.WebApi.Owin (讓WebApi作為中間件)
Install-Package Microsoft.Owin.Hosting (Hosting接口默認使用HttpListener作為Server)
Install-Package Microsoft.Owin.Host.HttpListener (默認的Server實現)
2.添加Startup類
|  
                
                 1 
                 
               
                 2 
                 
               
                 3 
                 
               
                 4 
                 
               
                 5 
                 
               
                 6 
                 
               
                 7 
                 
               
                 8 
                 
               
                 9 
                 
               
                 10 
                 
               
                 11 
                 
               
                 12 
                 
               
                 13 
                 
               
                 14 
                 
               
                 15 
                 
               
                 16 
                 
               
                 17 
                 
               
                 18 
                 
               
                 19 
                  |  
               
               public  
                 void  
                 Configuration(IAppBuilder app) 
                { 
                     
                 // 有關如何配置應用程序的詳細信息,請訪問 http://go.microsoft.com/fwlink/?LinkID=316888 
                     
                 ApiConfig(app); 
                } 
                private  
                 static  
                 void  
                 ApiConfig(IAppBuilder app) 
                { 
                     
                 var  
                 config =  
                 new  
                 HttpConfiguration(); 
                     
                 config.Routes.MapHttpRoute( 
                         
                 name:  
                 "DefaultApi" 
                 , 
                         
                 routeTemplate:  
                 "api/{controller}/{action}/{id}" 
                 , 
                         
                 defaults:  
                 new  
                 { id = RouteParameter.Optional , action = RouteParameter.Optional } 
                         
                 ); 
                     
                 app.UseWebApi(config); 
                } 
                 |  
             
如何讓Owin關聯到Startup類的方法,可以看我的博客:
[ASP.NET] 下一代ASP.NET開發規范:OWIN
3.創建一個Api控制器
|  
                
                 1 
                 
               
                 2 
                 
               
                 3 
                 
               
                 4 
                 
               
                 5 
                 
               
                 6 
                 
               
                 7 
                  |  
               
               public  
                 class  
                 ValuesController : ApiController 
                { 
                     
                 public  
                 string  
                 Get() 
                     
                 { 
                         
                 return  
                 "Never、C" 
                 ; 
                     
                 } 
                } 
                 |  
             
4.Main方法啟動
|  
                
                 1 
                 
               
                 2 
                 
               
                 3 
                 
               
                 4 
                 
               
                 5 
                 
               
                 6 
                 
               
                 7 
                 
               
                 8 
                 
               
                 9 
                  |  
               
               static  
                 void  
                 Main( 
                 string 
                 [] args) 
                { 
                     
                 using  
                 (WebApp.Start<Startup>(url)) 
                     
                 { 
                         
                 Console.WriteLine( 
                 "開啟成功" 
                 ); 
                         
                 Console.ReadLine(); 
                     
                 } 
                } 
                 |  
             
5.瀏覽器訪問

在上面的Owin Web API的基礎上,開始實現OAuth.
Nuget:
Install-Package Microsoft.Owin.Security.OAuth(owin的oauth的實現)
使用OAuth會要求Owin使用UseOAuthBearerTokens認證方式,所以引用
Install-Package Microsoft.AspNet.Identity.Owin
1.在Startup添加一個中間件配置
|  
                
                 1 
                 
               
                 2 
                 
               
                 3 
                 
               
                 4 
                 
               
                 5 
                 
               
                 6 
                 
               
                 7 
                 
               
                 8 
                 
               
                 9 
                 
               
                 10 
                 
               
                 11 
                  |  
               
               private  
                 static  
                 void  
                 OAuthConfig(IAppBuilder app) 
                     
                 { 
                         
                 var  
                 OAuthOptions =  
                 new  
                 OAuthAuthorizationServerOptions 
                         
                 { 
                             
                 TokenEndpointPath =  
                 new  
                 PathString( 
                 "/token" 
                 ), 
                             
                 Provider =  
                 new  
                 OTWAuthorizationServerProvider(), 
                             
                 AccessTokenExpireTimeSpan = TimeSpan.FromDays(14), 
                             
                 AllowInsecureHttp =  
                 true 
                 , 
                         
                 }; 
                         
                 app.UseOAuthBearerTokens(OAuthOptions); 
                     
                 } 
                 |  
             
並且設置Web API使用OAuth
|  
                
                 1 
                 
               
                 2 
                  |  
               
               config.Filters.Add( 
                 new  
                 HostAuthenticationFilter(OAuthDefaults.AuthenticationType));  
                 //添加的配置 
                app.UseWebApi(config); 
                 |  
             
2.自定義的provider
|  
                
                 1 
                 
               
                 2 
                 
               
                 3 
                 
               
                 4 
                 
               
                 5 
                 
               
                 6 
                 
               
                 7 
                 
               
                 8 
                 
               
                 9 
                 
               
                 10 
                 
               
                 11 
                 
               
                 12 
                 
               
                 13 
                 
               
                 14 
                 
               
                 15 
                 
               
                 16 
                 
               
                 17 
                 
               
                 18 
                 
               
                 19 
                 
               
                 20 
                 
               
                 21 
                 
               
                 22 
                  |  
               
               public  
                 class  
                 OTWAuthorizationServerProvider : OAuthAuthorizationServerProvider 
                { 
                     
                 //1.驗證客戶 
                     
                 public  
                 override  
                 Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 
                     
                 {<br>        
                 //此處可以判斷client和user <br> 
                         
                 //this.ClientId = clientId; 
                         
                 //this.IsValidated = true; 
                         
                 //this.HasError = false; 
                         
                 context.Validated( 
                 "自定義的clientId" 
                 ); 
                         
                 return  
                 base 
                 .ValidateClientAuthentication(context); 
                     
                 } 
                     
                 //授權客戶 
                     
                 public  
                 override  
                 Task GrantClientCredentials(OAuthGrantClientCredentialsContext context) 
                     
                 { 
                         
                 var  
                 ticket =  
                 new  
                 AuthenticationTicket( 
                 new  
                 ClaimsIdentity( 
                 new 
                 [] {  
                 new  
                 Claim(ClaimTypes.Name,  
                 "Never、C" 
                 ) }, context.Options.AuthenticationType),  
                 null 
                 ); 
                         
                 //this.Ticket = ticket; 
                         
                 //this.IsValidated = true; 
                         
                 //this.HasError = false; 
                         
                 context.Validated(ticket); 
                         
                 return  
                 base 
                 .GrantClientCredentials(context); 
                     
                 } 
                } 
                 |  
             
3.用客戶端來調用我們的(建議不要用單元測試,此處新建一個控制台項目)
|  
                
                 1 
                 
               
                 2 
                 
               
                 3 
                 
               
                 4 
                 
               
                 5 
                 
               
                 6 
                 
               
                 7 
                  |  
               
               static  
                 void  
                 Main( 
                 string 
                 [] args) 
                { 
                     
                 var  
                 client =  
                 new  
                 HttpClient(); 
                     
                 var  
                 rst = client.PostAsync(url +  
                 "token" 
                 ,  
                 new  
                 StringContent( 
                 "grant_type=client_credentials" 
                 )).Result.Content.ReadAsStringAsync().Result; 
                     
                 Console.WriteLine(rst); 
                } 
                 |  
             
4.先啟動服務端,再啟動客戶端

1.ValuesController添加特性Authorize
|  
                
                 1 
                 
               
                 2 
                 
               
                 3 
                 
               
                 4 
                 
               
                 5 
                 
               
                 6 
                 
               
                 7 
                 
               
                 8 
                  |  
               
               [Authorize] 
                public  
                 class  
                 ValuesController : ApiController 
                { 
                     
                 public  
                 string  
                 Get() 
                     
                 { 
                         
                 return  
                 User.Identity.Name; 
                     
                 } 
                } 
                 |  
             
訪問會返回
{"Response status code does not indicate success: 401 (Unauthorized)."}
2.客戶端引用
Install-Package Newtonsoft.Json -Version 7.0.1
3.修改Main方法,帶上Token
|  
                
                 1 
                 
               
                 2 
                 
               
                 3 
                 
               
                 4 
                 
               
                 5 
                 
               
                 6 
                 
               
                 7 
                 
               
                 8 
                 
               
                 9 
                 
               
                 10 
                 
               
                 11 
                 
               
                 12 
                 
               
                 13 
                 
               
                 14 
                 
               
                 15 
                 
               
                 16 
                 
               
                 17 
                 
               
                 18 
                 
               
                 19 
                 
               
                 20 
                  |  
               
               class  
                 Program 
                { 
                     
                 static  
                 void  
                 Main( 
                 string 
                 [] args) 
                     
                 { 
                         
                 var  
                 client =  
                 new  
                 HttpClient(); 
                         
                 var  
                 rst = client.PostAsync(url +  
                 "token" 
                 ,  
                 new  
                 StringContent( 
                 "grant_type=client_credentials" 
                 )).Result.Content.ReadAsStringAsync().Result; 
                         
                 var  
                 obj = JsonConvert.DeserializeObject<Token>(rst); 
                         
                 client.DefaultRequestHeaders.Authorization =  
                 new  
                 AuthenticationHeaderValue( 
                 "Bearer" 
                 , obj.AccessToken); 
                         
                 rst = client.GetStringAsync(url +  
                 "api/values" 
                 ).Result; 
                         
                 Console.WriteLine(rst); 
                         
                 Console.ReadLine(); 
                     
                 } 
                } 
                public  
                 class  
                 Token 
                { 
                     
                 [JsonProperty( 
                 "Access_Token" 
                 )] 
                     
                 public  
                 string  
                 AccessToken {  
                 get 
                 ;  
                 set 
                 ; } 
                } 
                 |  
             
4.先啟動服務端,再啟動客戶端

擴展
其實OAuth自己也能實現,本質是生成一個加密的唯一的字符串
OAuth的實現方案還有DotNetOpenAuth、Thinktecture IdentityServer
本文地址:http://neverc.cnblogs.com/p/4970996.html
參考:
http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/
http://www.cnblogs.com/dudu/p/4569857.html
