使用Identity Server 4建立Authorization Server (2)
第一部分: 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)