OAuth2.0資料 初衷:一直想整理授權系列demo,讓自己項目高端大尚,列出新手授權系列,幫助小白程式員不用在為授權頭疼 OAuth 允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每一個令牌授權一個特定的網站(例如,視頻編輯網站)在特定的時段(例如,接下來的 2 ...
OAuth2.0資料
初衷:一直想整理授權系列demo,讓自己項目高端大尚,列出新手授權系列,幫助小白程式員不用在為授權頭疼
OAuth 允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每一個令牌授權一個特定的網站(例如,視頻編輯網站)在特定的時段(例如,接下來的 2 小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth 讓用戶可以授權第三方網站訪問他們存儲在另外服務提供者的某些特定信息,而非所有內容。
以上概念來自:https://zh.wikipedia.org/wiki/OAuth
詳細理論知識,參考文章如下文章,本文章重在實踐
1.http://www.cnblogs.com/lanxiaoke/p/6358332.html
2.https://www.cnblogs.com/selimsong/p/8037717.html
3.http://www.cnblogs.com/xishuai/p/aspnet-webapi-owin-oauth2.html
項目實踐開發
步驟1和步驟2都行,看官樂意就行
步驟1
通過NuGet安裝
Microsoft.Owin.Security.OAuth
Owin Microsoft.Owin.Host.SystemWeb(重點)
步驟2
Owin Microsoft.Owin.Host.SystemWeb(重點)
Microsoft.Owin.Security.OAuth
Microsoft.Owin.Security.Cookies(可忽略)
Microsoft.AspNet.Identity.Owin
重點在於步驟1少了一個核心dll,少了這個核心dll無法啟動部署owin
新增Startup.cs
[assembly: OwinStartup(typeof(OAuth2.Startup))] namespace OAuth2 { public partial class Startup { public void Configuration(IAppBuilder app) { ConfigureAuth(app); } } }
Owin Microsoft.Owin.Host.SystemWeb 通過這個dll,程式啟動時候註冊,如果不引用,該方法不會生效,看官可以打個斷點試一試
新增Startup.Auth.cs
namespace OAuth2 { public partial class Startup { public void ConfigureAuth(IAppBuilder app) { app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions() { //從url中獲取token,相容hearder方式 //Provider = new QueryStringOAuthBearerProvider("access_token") }); var OAuthOptions = new OAuthAuthorizationServerOptions { AllowInsecureHttp = true, TokenEndpointPath = new PathString("/token"), //獲取 access_token 認證服務請求地址 AuthorizeEndpointPath = new PathString("/authorize"), //獲取 authorization_code 認證服務請求地址 AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(3600), //access_token 過期時間 Provider = new OpenAuthorizationServerProvider(), //access_token 相關認證服務 AuthorizationCodeProvider = new OpenAuthorizationCodeProvider(), //authorization_code 認證服務 RefreshTokenProvider = new OpenRefreshTokenProvider() //refresh_token 認證服務 }; app.UseOAuthBearerTokens(OAuthOptions); //表示 token_type 使用 bearer 方式 } } public class QueryStringOAuthBearerProvider : OAuthBearerAuthenticationProvider { readonly string _name; public QueryStringOAuthBearerProvider(string name) { _name = name; } public override Task RequestToken(OAuthRequestTokenContext context) { var value = context.Request.Query.Get(_name); if (!string.IsNullOrEmpty(value)) { context.Token = value; } return Task.FromResult<object>(null); } } }
眼光犀利的同學肯定註意到這兩個類名相同,命名空間也相同,為什麼沒有報錯 請註意關鍵字 partial
OpenAuthorizationServerProvider示例代碼 詳細見demo,只提代碼需要註意地方
/// <summary> /// 驗證 client 信息 /// </summary> public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { string clientId; string clientSecret; if (!context.TryGetBasicCredentials(out clientId, out clientSecret)) { context.TryGetFormCredentials(out clientId, out clientSecret); } if (clientId != "xishuai" || clientSecret != "123") { context.SetError("invalid_client", "client or clientSecret is not valid"); return; } context.Validated(); }
public string BaseString() { string clientId = "xishuai"; string clientSecret = "123"; return Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret)); }
驗證生效如圖 按照如下格式 key:value,然後base64編碼
context.TryGetBasicCredentials 否則解析不了 驗證不通過
OpenAuthorizationCodeProvider示例代碼 詳細見demo
OpenRefreshTokenProvider 示例代碼 詳細見demo
新增ValueController.cs
public class ValueController : ApiController { // GET api/values access_token驗證才能訪問 [Authorize] [HttpGet] public IEnumerable<string> Index() { return new string[] { "value1", "value2" }; }
//獲取授權code [HttpGet] [Route("api/authorization_code")] public HttpResponseMessage Get(string code) { return new HttpResponseMessage() { Content = new StringContent(code, Encoding.UTF8, "text/plain") }; } }
新增OAuthon2Controller.cs
public class OAuthon2Controller : Controller { //根據你項目埠 private const string HOST_ADDRESS = "http://localhost:60903"; // GET: OAuthon2 直接獲取授權code鏈接,方便獲取code public string Index() { string clientId = "xishuai"; string url = $"{HOST_ADDRESS}/authorize?grant_type=authorization_code&response_type=code&client_id={clientId}&redirect_uri={HttpUtility.UrlEncode($"{HOST_ADDRESS}/api/authorization_code")}"; return url; } }
根據獲取的url, 在將紅色部分url複製出來到瀏覽器中可以獲取到code
現在code有了 將獲取access_token
grant_type:authorization_code
code:圖上紅色url返回給你的
client_id:xishuai 可以理解為appid 自定義,因為代碼中固定了,你可以改
redirect_uri:這個鏈接你也能改的,接受code 在ValueController.cs (action:api/authorization_code)
http://localhost:60903/api/authorization_code
這個地方需要註意 需要和你獲取code redirect_uri保持一致就行
string url = $"{HOST_ADDRESS}/authorize?grant_type=authorization_code&response_type=code&client_id={clientId}&redirect_uri={HttpUtility.UrlEncode($"{HOST_ADDRESS}/api/authorization_code")}";
然後你就拿到access_token 去調用 api/Value/Index
如果這個地方你輸入錯,會獲取失敗
Authorization Bearer後面空格 在輸入access_token