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

solenovex發表於2017-11-05

第一部分: 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的資料:

第三部分是簽名:

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

相關文章