標籤:
在前一篇博文中,我們使用OAuth的Client Credential Grant授權方式,在服務端通過CNBlogsAuthorizationServerProvider(Authorization Server的一個實現)成功發放了Access Token,並在用戶端成功拿到了Access Token。
那Access Token有什麼用呢?在OAuth中對Resource Server(比如Web API)存取權限的驗證都是基於Access Token。不管是什麼樣的用戶端來調用,Resource Server總是鐵面無私,只認Access Token。
在ASP.NET Web API中啟用OAuth的Access Token驗證非常簡單,只需在相應的Controller或Action加上[Authorize]標記,比如:
[Authorize]public class ValuesController : ApiController{ // GET api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; }}
加上[Authorize]之後,如果不使用Access Token,調用API時就會出現如下的錯誤:
{"Message":"Authorization has been denied for this request."}
這時你也許會問,為什麼一加上[Authorize]就會有這個效果?原來的Forms驗證怎麼不起作用了?
原因是你在用Visual Studio建立ASP.NET Web API項目時,VS自動幫你添加了相應的代碼,開啟WebApiConfig.cs,你會看到下面這2行代碼:
config.SuppressDefaultHostAuthentication();config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
就是這2行代碼,改變了[Authorize]的作用。
在ASP.NET Web API中啟用OAuth驗證就這麼簡單(簡單的背後是微軟實現了基於OWIN的OAuth,實現原始碼在Katana項目中)。
那在用戶端如何使用Access Token調用Web API呢?
也很簡單,只要在http要求標頭中加上Bearer:Token即可,用戶端調用範例程式碼如下:
public class OAuthClientTest { private HttpClient _httpClient; public OAuthClientTest() { _httpClient = new HttpClient(); _httpClient.BaseAddress = new Uri("http://openapi.cnblogs.com"); } [Fact] public async Task Call_WebAPI_By_Access_Token() { var token = await GetAccessToken(); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); Console.WriteLine(await (await _httpClient.GetAsync("/api/values")).Content.ReadAsStringAsync()); } private async Task<string> GetAccessToken() { var parameters = new Dictionary<string, string>(); parameters.Add("client_id", "1234"); parameters.Add("client_secret", "5678"); parameters.Add("grant_type", "client_credentials"); var response = await _httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters)); var responseValue = await response.Content.ReadAsStringAsync(); return JObject.Parse(responseValue)["access_token"].Value<string>(); } }
運行結果如下:
["value1","value2"]
搞定!
ASP.NET Web API與基於Owin實現的OAuth的整合,讓原本複雜的問題變得簡單。
ASP.NET Web API與Owin OAuth:使用Access Toke調用受保護的API