這是一篇待在草稿箱半年之久的文章
連我自己都不知道我的草稿箱有多少未發布的文章了。這應該是我在上一家公司未解散之前寫的,記得當時是要做一個開發者中心,很不幸。
今天,打開草稿箱有種莫名的傷感,看到這個一系列關於 OAuth 的草稿(其實也就兩篇而已),我決定重新發表出來。因為,我看到之前簡單寫的一個一行代碼,發送郵件的小工具,放到Github上以后,好多大的企業在免費使用,如:某某新聞網、某某雲服務和一家硬件公司等,其實我非常高興的,因為我一直在免費使用好多開源社區的福利。有機會做一點微薄的貢獻,這個世界會更好。
你在北方的寒夜里瑟瑟如狗,我在南方的艷陽里看你發抖
我的朋友圈反正今天早上是被「雪」爆了,而我依然穿着短袖。看到老三拍了兩張帶有老家標志建築物的雪景照,發了條朋友圈說我有點想家了,老二回復說:回來唄。突然,鼻子一酸...回復他:老子在擠地鐵!!!回屁家。然后,我喝了口涼水后心情大好!
回到正題,你肯定已經了解到什么是 OAuth 2.0 了,你說它不就是一個協議么,但是那些第三方接口都有什么ClientId
、ClientSecret
、Access Token
、Refresh Token
等等之類的,看着都頭暈,這些到底是什么阿阿阿?。是這樣的,我也如你一樣苦惱,這些到底都是什么鬼、干什么的?這篇文章就講清道明這些東西到底是什么鬼!!!
一個開發者中心的授權流程是怎樣的
上文好像說到我們要開發一個「開發者中心」,所以,我想先講一下這個所謂的「開發者中心」是怎樣把數據開放給開發者的。
正如你所知道的數據是無價的,我們並不想任何人
都能通過我們的開放平台來獲取數據。舉個栗子:你家有好多書,其實你並不看,但有好多朋友想看,你又不想任何人都能去你家拿走你心愛的《C#入門經典》,首先他要向你說明他想借你的書看看,你同意后說:你請我吃飯
吧,然后我給你我家鑰匙
你自己去取吧,我忙。這個過程就叫做:授權!請你吃飯可以理解為ClientId
、ClientSecret
,你家的鑰匙就是所謂的Token
。
夠了夠了,你說的這些我都懂,那怎么用代碼要體現呢?
利用 Web API 來實現 OAuth 授權
為什么是 Web API ?
因為 ASP.NET Web API 是針對接口而生的阿。況且它還是REST風格
的哦,更輕量級一些,其實這些都不重要,重要的它夠簡單,十分鍾即可上手。
怎么使用 OAuth 的方式實現授權?
Microsoft.Owin.Security.OAuth,就是它!你要知道這可是.Net的可愛之處,她把你需要的就放在了那里,你用不用她就在那。現在就使用它來實現 OAuth 2.0 中所說的四種授權模式之一的客戶端模式(client credentials)。
Ⅰ. 打開VS2013,新建一個 Web API 項目。源碼
Ⅱ. 在Project右鍵,選擇“管理NuGet程序包”,搜索“Owin”。安裝下面的包:
- Microsoft.Owin.Security.OAuth
- Microsoft.Owin.Security
- Microsoft.Owin
- Microsoft.Owin.Host.SystemWeb(我被它坑了好久)
- OWIN
- Microsoft ASP.Net Web API 2.2 OWIN
- Microsoft ASP.Net Identity OWIN
Ⅲ. 修改 Startup.cs 文件如下,如沒有,則新建。
using ...
[assembly: OwinStartup(typeof (Startup))]
namespace Mafly.OAuth2._0.Demo
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// 有關如何配置應用程序的詳細信息,請訪問 http://go.microsoft.com/fwlink/?LinkID=316888
var config = new HttpConfiguration();
WebApiConfig.Register(config);
//開啟OAuth服務
ConfigureOAuth(app);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app)
{
// Token 生成配置
var oAuthOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true, //允許客戶端使用Http協議請求
AuthenticationMode = AuthenticationMode.Active,
TokenEndpointPath = new PathString("/token"), //請求地址
AccessTokenExpireTimeSpan = TimeSpan.FromHours(2), //token過期時間
//提供認證策略
Provider = new OpenAuthorizationServerProvider()
//RefreshTokenProvider = new RefreshAuthenticationTokenProvider()
};
app.UseOAuthBearerTokens(oAuthOptions);
}
}
}
Ⅳ. 新建OpenAuthorizationServerProvider
public class OpenAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
/// <summary>
/// 驗證客戶端
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
string clientId;
string clientSecret;
context.TryGetFormCredentials(out clientId, out clientSecret);
//context.TryGetBasicCredentials(out clientId, out clientSecret); //Basic認證
//TODO:讀庫,驗證
if (clientId != "malfy" && clientSecret != "111111")
{
context.SetError("invalid_client", "client is not valid");
return;
}
context.OwinContext.Set("as:client_id", clientId);
context.Validated(clientId);
}
/// <summary>
/// 客戶端授權[生成access token]
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context)
{
var oAuthIdentity = new ClaimsIdentity(context.Options.AuthenticationType);
oAuthIdentity.AddClaim(new Claim(ClaimTypes.Name, context.OwinContext.Get<string>("as:client_id")));
var ticket = new AuthenticationTicket(oAuthIdentity, new AuthenticationProperties {AllowRefresh = true});
context.Validated(ticket);
return base.GrantClientCredentials(context);
}
}
Ⅴ. 沒有第五步了。是不是很簡單。源碼
測試
我聽說用postman測試API接口比較爽,然后我就用了它。
Ⅰ. 當沒有獲取Token時,請求/api/values
接口。
Ⅱ. 那好,我們來獲取Token。
Ⅲ. 得到了access_token
,我們添加Headers
,Header:Authorization Value:bearer [token],token就是access_token。
那行,總結一下
我們利用Microsoft.Owin.Security.OAuth
和 Web API 實現了遵循 OAuth 2.0 協議的授權流程,這為我們開發「開發者中心」打下了堅實基礎,讓我們展望美好的未來吧。ps:說的真官方,能不能說人話。
最后一句:源碼在Github上 https://github.com/mafly/OAuth2.0