ASP.NET CORE API Swagger+IdentityServer4授權驗證
簡介
本來不想寫這篇博文,但在網上找到的文章部落格都沒有完整配置資訊,所以這裡記錄下。
不瞭解IdentityServer4的可以看看我之前寫的入門博文
Swagger 官方演示地址
配置IdentityServer4服務端
首先建立一個新的ASP.NET Core專案。
這裡選擇空白項,新建空白專案
等待建立完成後,右鍵單擊專案中的依賴項選擇管理NuGet程式包,搜尋IdentityServer4並安裝:
等待安裝完成後,下載官方提供的UI檔案,並拖放到專案中。下載地址:https://github.com/IdentityServer/IdentityServer4.Quickstart.UI
配置IdentityServer4
在專案中新建檔案Config.cs檔案,原始碼如下:
using IdentityServer4; using IdentityServer4.Models; using IdentityServer4.Test; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace IdentityServer { public static class Config {public static IEnumerable<IdentityResource> GetIdentityResources() { return new IdentityResource[] { new IdentityResources.OpenId(), new IdentityResources.Profile(), }; } /// <summary> /// API資訊/// </summary> /// <returns></returns> public static IEnumerable<ApiResource> GetApis() { return new[] { new ApiResource("demo_api", "Demo API with Swagger") }; } /// <summary> /// 客服端資訊 /// </summary> /// <returns></returns> public static IEnumerable<Client> GetClients() { return new[] { new Client { ClientId = "demo_api_swagger",//客服端名稱 ClientName = "Swagger UI for demo_api",//描述 AllowedGrantTypes = GrantTypes.Implicit,//指定允許的授權型別(AuthorizationCode,Implicit,Hybrid,ResourceOwner,ClientCredentials的合法組合)。 AllowAccessTokensViaBrowser = true,//是否通過瀏覽器為此客戶端傳輸訪問令牌 RedirectUris = { "http://localhost:5001/swagger/oauth2-redirect.html" }, AllowedScopes = { "demo_api" }//指定客戶端請求的api作用域。 如果為空,則客戶端無法訪問 } }; } } }
開啟Startup.cs檔案配置,修改如下:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using IdentityServer4.Quickstart.UI; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; namespace IdentityServer { public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); //配置身份伺服器與記憶體中的儲存,金鑰,客戶端和資源 services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryApiResources(Config.GetApis())//新增api資源 .AddInMemoryClients(Config.GetClients())//新增客戶端 .AddInMemoryIdentityResources(Config.GetIdentityResources())//新增對OpenID Connect的支援 .AddTestUsers(TestUsers.Users); //新增測試使用者 } // 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(); } //IdentityServe app.UseIdentityServer(); //新增靜態資源訪問 app.UseStaticFiles(); // app.UseMvcWithDefaultRoute(); } } }
修改啟動埠為5000,啟動訪問:http://localhost:5000/,效果如下:
API配置
新建ASP.NET CORE API專案,使用NuGet新增包:IdentityServer4.AccessTokenValidation、Swashbuckle.AspNetCore
在API中新增 AuthorizeCheckOperationFilter用於管理IdentityServer4認證處理,程式碼如下:
using Microsoft.AspNetCore.Authorization; using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.SwaggerGen; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace TPL.API { /// <summary> /// IdentityServer4認證過濾器 /// </summary> public class AuthorizeCheckOperationFilter : IOperationFilter { public void Apply(Operation operation, OperationFilterContext context) { //獲取是否新增登入特性 var authAttributes = context.MethodInfo.DeclaringType.GetCustomAttributes(true) .Union(context.MethodInfo.GetCustomAttributes(true)) .OfType<AuthorizeAttribute>().Any(); if (authAttributes) { operation.Responses.Add("401", new Response { Description = "暫無訪問許可權" }); operation.Responses.Add("403", new Response { Description = "禁止訪問" }); //給api新增鎖的標註 operation.Security = new List<IDictionary<string, IEnumerable<string>>> { new Dictionary<string, IEnumerable<string>> {{"oauth2", new[] {"demo_api"}}} }; } } } }
修改API的Startup檔案,修改如下:
using System; using System.Collections.Generic; using IdentityServer4.AccessTokenValidation; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Swashbuckle.AspNetCore.Swagger; namespace TPL.API { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); //使用者校驗 services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme) .AddIdentityServerAuthentication(options => { options.Authority = "http://localhost:5000"; // IdentityServer伺服器地址 options.ApiName = "demo_api"; // 用於針對進行身份驗證的API資源的名稱 options.RequireHttpsMetadata = false; // 指定是否為HTTPS }); //新增Swagger. services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new Info { Title = "Protected API", Version = "v1" }); //向生成的Swagger新增一個或多個“securityDefinitions”,用於API的登入校驗 options.AddSecurityDefinition("oauth2", new OAuth2Scheme { Flow = "implicit", // 只需通過瀏覽器獲取令牌(適用於swagger) AuthorizationUrl = "http://localhost:5000/connect/authorize",//獲取登入授權介面 Scopes = new Dictionary<string, string> { { "demo_api", "Demo API - full access" }//指定客戶端請求的api作用域。 如果為空,則客戶端無法訪問 } }); options.OperationFilter<AuthorizeCheckOperationFilter>(); // 新增IdentityServer4認證過濾 }); } // 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(); } app.UseAuthentication(); // Swagger JSON Doc app.UseSwagger(); // Swagger UI app.UseSwaggerUI(options => { options.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); options.OAuthClientId("demo_api_swagger");//客服端名稱 options.OAuthAppName("Demo API - Swagger-演示"); // 描述 }); app.UseMvc(); } } }
修改Properties資料夾下的launchSettings啟動埠為5001,這裡埠必須跟IdentityServer4中的Config配置的客服端資源中保持一致。
{ "$schema": "http://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:5001", "sslPort": 0 } }, "profiles": { "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, "launchUrl": "swagger", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "TPL.API": { "commandName": "Project", "launchBrowser": true, "launchUrl": "swagger", "applicationUrl": "http://localhost:5001", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
訪問呈現效果如下,從中效果圖中可以看出新增登入按鈕,API控制器中如果新增Authorize特性,對應介面會有一把鎖的標誌:
如果未授權訪問介面返回401,未授權提示:
點選Authorize按鈕會跳轉到IdentityServer4登入頁面,登入授權成功後會自動獲取登入後伺服器返回Token,再次訪問介面即可正常訪問,授權前後效果如下:
到此演示專案完畢。如果需求配合自己的資料庫使用請看我前面寫過的博文 自定義登入即可。