ASP.NET OAuth 2.0 新手上路


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

1

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

2

如果這個地方你輸入錯,會獲取失敗

Authorization     Bearer后面空格 在輸入access_token 

源碼下載


免責聲明!

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



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