1. 程式人生 > >使用Identity Server 4建立Authorization Server (2)

使用Identity Server 4建立Authorization Server (2)

可能 參數 ecif fig register startup 類型 cal mat

第一部分: http://www.cnblogs.com/cgzl/p/7780559.html

第一部分主要是建立了一個簡單的Identity Server.

接下來繼續:

建立Web Api項目

如圖可以在同一個解決方案下建立一個web api項目:

技術分享

(可選)然後修改webapi的launchSettings.json, 我習慣使用控制臺, 所以把IISExpress相關的都刪掉, 並且把端口改成5001:

{
  "profiles": {
    "WebApi": {
      "commandName": "Project",
      "launchBrowser": true,
      
"launchUrl": "api/values", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, "applicationUrl": "http://localhost:5001/" } } }

為Web Api添加Swagger幫助頁面

完全依照官方文檔安裝swagger即可: https://docs.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-swagger?tabs=visual-studio

通過nuget安裝或者通過package manager console:

Install-Package Swashbuckle.AspNetCore

在Startup的ConfigureServices註冊並配置Swagger, 然後在StartUp的Configure方法使用Swagger中間件:

// This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            
// Register the Swagger generator, defining one or more Swagger documents services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" }); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // Enable middleware to serve generated Swagger as a JSON endpoint. app.UseSwagger(); // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint. app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); }); app.UseMvc(); }

可以運行一下項目, 通過地址: http://localhost:5001/swagger/ 訪問swagger幫助頁面:

技術分享

添加庫IdentityServer4.AccessTokenValidation

webapi配置identity server就需要對token進行驗證, 這個庫就是對access token進行驗證的. 通過nuget安裝:

技術分享

在Startup的ConfigureServices裏面註冊配置:

services.AddMvcCore()
                .AddAuthorization()
                .AddJsonFormatters();

            services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.RequireHttpsMetadata = false;
                    options.Authority ="http://localhost:5000";
                    options.ApiName = "socialnetwork";
                });

這裏AddAuthentication()是把驗證服務註冊到DI, 並配置了Bearer作為默認模式.

AddIdentityServerAuthentication()是在DI註冊了token驗證的處理者.

由於是本地運行, 所以就不使用https了, RequireHttpsMetadata = false. 如果是生產環境, 一定要使用https.

Authority指定Authorization Server的地址.

ApiName要和Authorization Server裏面配置ApiResource的name一樣.

然後, 在Startup的Configure方法裏配置Authentication中間件.

app.UseAuthentication();

app.UseMvc();

這句話就是在把驗證中間件添加到管道裏, 這樣每次請求就會調用驗證服務了. 一定要在UserMvc()之前調用.

當在controller或者Action使用[Authorize]屬性的時候, 這個中間件就會基於傳遞給api的Token來驗證Authorization, 如果沒有token或者token不正確, 這個中間件就會告訴我們這個請求是UnAuthorized(未授權的).

添加[Authorize]屬性:

打開ValuesController, 在Controller上面添加這個屬性:

    [Authorize]
    [Route("api/[controller]")]
    public class ValuesController : Controller

然後運行 webapi:

會自動打開這個網址: http://localhost:5001/api/values

Chrome按F12, 打開調試窗口的network折頁 (按F12以後可能需要刷新一下瀏覽器):

技術分享

401, 顯示該請求為UnAuthorized.

也可以使用postman:

技術分享

還是401.

也可以使用swagger, 依然401:

技術分享

所以我們首先需要獲取到一個token. 不過需要把Authorization Server也跑起來.

點擊解決方案屬性, 讓兩個項目都啟動:

技術分享

然後運行, 使用postman先獲取token:

技術分享

如果報錯的話, 可能是生成的證書有問題, 上次文章裏面有一個參數rsa我後邊寫的是2014, 寫錯了, 應該是2048. 如果報錯就重新生成一個吧.

然後復制一下 access_token的值. 回到api/values的那個請求, 把access_token貼到Authorization Header的值裏面, 前邊要加上Bearer表示類型, 還有一個空格.

技術分享

這樣, 請求就會通過驗證, 返回200和正確的值.

看一下Authorization Server的控制臺信息:

技術分享

會發現有人請求了這個地址, 事實上這就是api從identity server請求獲取public key, 然後在webapi裏用它來驗證token.

如果你改變了token的一個字母, 請求結果就會變成401.

在ValuesController裏面設斷點看看Claims

技術分享

使用User.Claims來獲取claims.

看看claims, 裏面包含著authorization server的信息, 包括client, scope等等. 這些都是從token裏面來的, 這個token在這肯定不是被篡改過的, 因為它已經從authorization server驗證過了.

上面這種驗證 我們使用的是client_credentials. 下面我們使用resourceownerpassword這個flow來試試:

在postman裏面這樣請求token, grant_type改成password, 然後添加username和password:

技術分享

然後復制token, 請求api/values, 還看那個斷點:

技術分享

這時claims和之前不一樣了. 這裏有sub (subject), 它是用戶的id, 還有一些其他信息.

分析一下Token

去https://jwt.io/ 可以分析一下這個token:

技術分享

token分為三個部分, 每個部分之間使用一個點來分開.

我們知道第一個部分是Header, 包括算法和類型等信息:

技術分享

第二部分是Payload(數據), 就是斷點裏Claims的數據:

技術分享

第三部分是簽名:

技術分享

比較忙, 這次寫的比較少. 看來還能寫很多集... - -!

使用Identity Server 4建立Authorization Server (2)