標籤:
1)用Visual Studio 2013/2015建立一個Web API 4項目,VS會產生一堆OAuth相關代碼。
2)開啟Startup.Auth.cs ,精簡一下代碼,我們只需要實現以Client Credentials Grant授權方式拿到token,其它無關代碼全部清除,最終剩下如下代碼:
using System;using System.Collections.Generic;using System.Linq;using Microsoft.AspNet.Identity;using Microsoft.AspNet.Identity.EntityFramework;using Microsoft.Owin;using Microsoft.Owin.Security.Cookies;using Microsoft.Owin.Security.Google;using Microsoft.Owin.Security.OAuth;using Owin;using WebApi4.Providers;using WebApi4.Models;namespace WebApi4{ public partial class Startup { public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; } public static string PublicClientId { get; private set; } // 有關配置身分識別驗證的詳細資料,請訪問 http://go.microsoft.com/fwlink/?LinkId=301864 public void ConfigureAuth(IAppBuilder app) { var OAuthOptions = new OAuthAuthorizationServerOptions { TokenEndpointPath = new PathString("/token"),//擷取Token的地址 樣本:http://localhost:54342/token Provider = new CustomAuthorizationServerProvider(),// AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),//Token有效期間 AllowInsecureHttp = true }; app.UseOAuthBearerTokens(OAuthOptions); } }}
3)建立一個新的類 CustomAuthorizationServerProvider,並繼承自 OAuthAuthorizationServerProvider,重載 OAuthAuthorizationServerProvider() 與 GrantClientCredentials() 這兩個方法。代碼如下:
using Microsoft.Owin.Security;using Microsoft.Owin.Security.OAuth;using System;using System.Collections.Generic;using System.Linq;using System.Security.Claims;using System.Threading.Tasks;using System.Web;namespace WebApi4.Providers{ public class CustomAuthorizationServerProvider : OAuthAuthorizationServerProvider { /// <summary> /// 在 ValidateClientAuthentication() 方法中擷取用戶端的 client_id 與 client_secret 進行驗證 /// 在 GrantClientCredentials() 方法中對用戶端進行授權,授了權就能發 access token /// </summary> /// <param name="context"></param> /// <returns></returns> public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId; string clientSecret; context.TryGetBasicCredentials(out clientId, out clientSecret);//使用Basic Authentication傳遞clientId與clientSecret;使用Form Authentication TryGetFormCredentials if (clientId == "xsj" && clientSecret == "1989") { context.Validated(clientId); } return base.ValidateClientAuthentication(context); } public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context) { var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType); oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, "xsj")); var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties()); context.Validated(ticket); return base.GrantClientCredentials(context); } }}
4)然後寫用戶端調用代碼測試一下:
using System;using System.Collections.Generic;using System.Linq;using System.Net.Http;using System.Net.Http.Headers;using System.Text;using System.Web;using System.Web.Mvc;namespace WebApi4.Controllers{ public class HomeController : Controller { public ActionResult Index() { ViewBag.Title = "Home Page"; return View(); } public ContentResult Get_Accesss_Token_By_Client_Credentials_Grant() { //Home/Get_Accesss_Token_By_Client_Credentials_Grant
//使用Form Authentication 傳遞 clientId與clientSecret //HttpClient _httpClient = new HttpClient(); //_httpClient.BaseAddress = new Uri("http://localhost:54342"); //var parameters = new Dictionary<string, string>(); //parameters.Add("client_id", "xsj"); //parameters.Add("client_secret", "1989"); //parameters.Add("grant_type", "client_credentials");// //string result = _httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters)).Result.Content.ReadAsStringAsync().Result; //return Content(result);
//使用Basic Authentication傳遞clientId與clientSecret var clientId = "xsj";//使用者名稱 var clientSecret = "1989";//密碼 HttpClient _httpClient = new HttpClient(); _httpClient.BaseAddress = new Uri("http://localhost:54342"); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret))); var parameters = new Dictionary<string, string>(); parameters.Add("grant_type", "client_credentials"); string result = _httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters)).Result.Content.ReadAsStringAsync().Result; return Content(result); } }}
返回結果:
{"access_token":"aH7eq761wPUqjffAW0Q9qoxY1LxQ3bXVSFnjIIXOmG2u_PpSVYxW5xmdr1tYWFFSYN4X2vPKqW0HFFSoNNdG6Os3zU-_NAG5AYcJMcotYPkvqQbkueaHXzDf8qvWIIbyLI0u7oxhTNyV_OpEuZkUUcUceCBoLOc9_y4Ff627UEvQErZriTK_OoT0atxsyKftxUW2m0pUxHLWpb2p6Ys25g","token_type":"bearer","expires_in":1209599}
註:使用Basic Authentication傳遞clientId與clientSecret,服務端CustomAuthorizationServerProvider中的TryGetFormCredentials()改為TryGetBasicCredentials()
使用Fiddler獲得Token:
【參考資料】
http://www.cnblogs.com/dudu/p/4569857.html
http://www.hackered.co.uk/articles/asp-net-mvc-creating-an-oauth-client-credentials-grant-type-token-endpoint
在ASP.NET中基於Owin OAuth使用Client Credentials Grant授權發放Token