ASP.NET Web API與Owin OAuth:使用Access Toke調用受保護的API


在前一篇博文中,我們使用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的整合,讓原本復雜的問題變得簡單。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM