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類
        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控制器
    public class ValuesController : ApiController
    {
        public string Get()
        {
            return "Never、C";
        }
    }
 
        
4.Main方法啟動
        static void Main(string[] args)
        {
            const string url = "http://localhost:1234/";
            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添加一個中間件配置
    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
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); //添加的配置
            app.UseWebApi(config);
 
        
2.自定義的provider
    public class OTWAuthorizationServerProvider : OAuthAuthorizationServerProvider
    {
        //1.驗證客戶
        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
       //此處可以判斷client和user 
            //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.用客戶端來調用我們的(建議不要用單元測試,此處新建一個控制台項目)
        static void Main(string[] args)
        {
            const string url = "http://localhost:1234/";
            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
    [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
    class Program
    {
        static void Main(string[] args)
        {
            const string url = "http://localhost:1234/";
            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
http://www.cnblogs.com/xizz/p/5038923.html
