1.OAuth密碼模式
2.在VS中創建WebAPI項目
在nuget中安裝:
Microsoft.AspNet.WebApi.Owin
Microsoft.Owin.Host.SystemWeb
這兩個類庫並添加Owin啟動類Startup
using System; using System.Threading.Tasks; using Microsoft.Owin; using Owin; using Microsoft.Owin.Security.OAuth; [assembly: OwinStartup(typeof(WebAPIOAuth.Startup))] namespace WebAPIOAuth { public class Startup { public void Configuration(IAppBuilder app) { var OAuthOptions = new OAuthAuthorizationServerOptions { AllowInsecureHttp = true, TokenEndpointPath = new PathString("/token"), //獲取 access_token 授權服務請求地址 AuthorizeEndpointPath = new PathString("/authorize"), //獲取 authorization_code 授權服務請求地址 AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(10), //access_token 過期時間 Provider = new OpenAuthorizationServerProvider(), //access_token 相關授權服務 }; app.UseOAuthBearerTokens(OAuthOptions); //表示 token_type 使用 bearer 方式 不記名令牌驗證 } } }
ConfigureOAuth(IAppBuilder app)方法開啟了OAuth服務。簡單說一下OAuthAuthorizationServerOptions中各參數的含義:
AllowInsecureHttp:允許客戶端一http協議請求;
TokenEndpointPath:token請求的地址,即http://localhost:端口號/token;
AccessTokenExpireTimeSpan :token過期時間;
Provider :提供具體的認證策略;
3.繼承授權服務OAuthAuthorizationServerProvider類
重載ValidateClientAuthentication方法驗證客戶端的正確性
重載GrantResourceOwnerCredentials方法實現用戶名密碼的驗證,驗證通過后會頒發token。
public class OpenAuthorizationServerProvider : OAuthAuthorizationServerProvider { /// <summary> /// 驗證調用端的clientid與clientSecret已驗證調用端的合法性(clientid、clientSecret為約定好的字符串)。 /// </summary> /// <param name="context"></param> /// <returns></returns> public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId; string clientSecret; context.TryGetBasicCredentials(out clientId, out clientSecret); if (clientId == "1234" && clientSecret == "5678") { context.Validated(clientId); } await base.ValidateClientAuthentication(context); } /// <summary> /// 通過重載GrantResourceOwnerCredentials獲取用戶名和密碼進行認證 /// </summary> /// <param name="context"></param> /// <returns></returns> public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { //調用后台的登錄服務驗證用戶名與密碼 if (context.UserName != "Admin" || context.Password != "123456") { context.SetError("invalid_grant", "用戶名或密碼不正確。"); return; } var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType); oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties()); context.Validated(ticket); await base.GrantResourceOwnerCredentials(context); } }
在需要驗證的方法處添加[Authorize]標簽,當訪問此接口時必須通過授權驗證才可訪問。
以上服務器端代碼全部完成。
4.創建新的客戶端項目進行測試
添加測試類
class OAuthClientTest { private HttpClient _httpClient; private string token; public OAuthClientTest() { _httpClient = new HttpClient(); _httpClient.BaseAddress = new Uri("http://localhost"); } public async Task<string> GetAccessToken() { var clientId = "1234"; var clientSecret = "5678"; var parameters = new Dictionary<string, string>(); parameters.Add("grant_type", "password"); parameters.Add("username", "Admin"); parameters.Add("password", "123456"); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( "Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret)) ); var response = await _httpClient.PostAsync("OAuthTest/token", new FormUrlEncodedContent(parameters)); var responseValue = await response.Content.ReadAsStringAsync(); if (response.StatusCode == System.Net.HttpStatusCode.OK) { return JObject.Parse(responseValue)["access_token"].Value<string>(); } else { Console.WriteLine(responseValue); return string.Empty; } } public async Task Call_WebAPI_By_Resource_Owner_Password_Credentials_Grant() { if(string.IsNullOrEmpty(token)) token = await GetAccessToken(); Console.WriteLine(token); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); Console.WriteLine(await (await _httpClient.GetAsync("OAuthTest/api/Values")).Content.ReadAsStringAsync()); } }
main方法中調用進行測試:
static void Main(string[] args) { var clientTest = new OAuthClientTest(); var task = clientTest.Call_WebAPI_By_Resource_Owner_Password_Credentials_Grant(); task.Wait(); //var token = clientTest.GetAccessToken(); //var strToken = token.Result; //Console.WriteLine(strToken); Console.ReadLine(); }
結果如下:
其中長串字符為token,"value1, value2"為訪問webapi返回的結果,表明訪問成功。
參考1:http://www.cnblogs.com/xishuai/p/aspnet-webapi-owin-oauth2.html
參考2:http://www.cnblogs.com/Leo_wl/p/4919783.html