在以前的使用Swagger作Api文檔中,咱們已經使用Swagger進行開發接口文檔,以及更加方便的使用。這一轉換,讓更多的接口能夠以通俗易懂的方式展示給開發人員。而在後續的內容中,爲了對api資源的保護,咱們引入了認證受權方案,利用HTTP提供了一套標準的身份驗證框架,服務端能夠用來針對客戶端的請求發送質詢(challenge),客戶端根據質詢提供應答身份驗證憑證,進而實現對資源的保護。html
由於以前在使用Swagger的系列中尚未加身份認證受權這一塊,因此咱們使用的接口都是沒有進行資源保護的,而再後續又對認證受權這一塊進行講解又沒有將Swagger好好的利用起來,使得每一次要測試受權認證的時候,都得使用postman在Hearer請求頭中加入Authorization屬性,致使每測試一個接口就得輸入一次token令牌來實現認證,重複操做頻繁,下降工做效率。c#
這個時候,咱們恰好發現,Swagger已經幫咱們是實現了一次輸入令牌,不一樣接口屢次調用,提升效率。這樣,咱們就能夠將以前的Swagger系列和認證受權系列相結合。api
說幹就幹。。。安全
Swagger系列:框架
基於.NetCore3.1系列 —— 使用Swagger作Api文檔 (上篇)ide
基於.NetCore3.1系列 —— 使用Swagger作Api文檔 (下篇)post
基於.NetCore3.1系列 —— 使用Swagger導出文檔 (番外篇)測試
基於.NetCore3.1系列 —— 使用Swagger導出文檔 (補充篇)ui
JWT認證受權系列:調試
基於.NetCore3.1系列 —— 認證方案之初步認識JWT
基於.NetCore3.1系列 —— 認證受權方案之JwtBearer認證
基於.NetCore3.1系列 —— 認證受權方案之受權初識
基於.NetCore3.1系列 —— 認證受權方案之受權揭祕 (上篇)
基於.NetCore3.1系列 —— 認證受權方案之受權揭祕 (下篇)
這裏咱們使用以前Swagger系列中的源碼,能夠發現這個在沒有使用配置咱們認證受權代碼的狀況下,資源api都是處於沒有保護的狀況下,任何人均可以調用使用,沒有安全性。
public void ConfigureServices(IServiceCollection services) { services.AddSwaggerGen(c => { c.SwaggerDoc("V1", new OpenApiInfo { Version = "V1", //版本 Title = $"XUnit.Core 接口文檔-NetCore3.1", //標題 Description = $"XUnit.Core Http API v1", //描述 Contact = new OpenApiContact { Name = "艾三元", Email = "", Url = new Uri("http://i3yuan.cnblogs.com") }, License = new OpenApiLicense { Name = "艾三元許可證", Url = new Uri("http://i3yuan.cnblogs.com") } }); var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//獲取應用程序所在目錄(絕對,不受工做目錄影響,建議採用此方法獲取路徑) //var basePath = AppContext.BaseDirectory; var xmlPath = Path.Combine(basePath, "XUnit.Core.xml");//這個就是剛剛配置的xml文件名 c.IncludeXmlComments(xmlPath);//默認的第二個參數是false,對方法的註釋 // c.IncludeXmlComments(xmlPath,true); //這個是controller的註釋 }); services.AddControllers(); }
基於以前的認證受權方案系列,咱們這一節的認證受權就使用以前使用的基於自定義策略受權的方式,實現受權。
定義一個權限策略PermissionRequirement
,這個策略幷包含一些屬性。
public class PermissionRequirement: IAuthorizationRequirement { public string _permissionName { get; } public PermissionRequirement(string PermissionName) { _permissionName = PermissionName; } }
public class PermissionRequirementHandler : AuthorizationHandler<PermissionRequirement> { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) { var role = context.User.FindFirst(c => c.Type == ClaimTypes.Role); if (role != null) { var roleValue = role.Value; if (roleValue==requirement._permissionName) { context.Succeed(requirement); } } return Task.CompletedTask; } }
(請注意,因爲這是自定義要求,所以沒有擴展方法,而必須繼續處理策略對象的整個 Requirements
集合):
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); //基於自定義策略受權 services.AddAuthorization(options => { options.AddPolicy("customizePermisson", policy => policy .Requirements .Add(new PermissionRequirement("admin"))); }); //此外,還須要在 IAuthorizationHandler 類型的範圍內向 DI 系統註冊新的處理程序: services.AddScoped<IAuthorizationHandler, PermissionRequirementHandler>(); // 如前所述,要求可包含多個處理程序。若是爲受權層的同一要求向 DI 系統註冊多個處理程序,有一個成功就足夠了。 }
指定當前用戶必須是應用對控制器或控制器內的操做,如
[Authorize(Policy = "customizePermisson")] public class MovieController : ControllerBase { }
利用Swagger爲咱們提供的接口,在AddSwaggerGen服務中,添加保護api資源的描述。
var openApiSecurity = new OpenApiSecurityScheme { Description = "JWT認證受權,使用直接在下框中輸入Bearer {token}(注意二者之間是一個空格)\"", Name = "Authorization", //jwt 默認參數名稱 In = ParameterLocation.Header, //jwt默認存放Authorization信息的位置(請求頭) Type = SecuritySchemeType.ApiKey };
添加請求頭的Header中的token,傳遞到後臺。
c.OperationFilter<SecurityRequirementsOperationFilter>();
開啓加權鎖
c.OperationFilter<AddResponseHeadersFilter>(); c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
代碼整合以下:在ConfigureServices服務中
services.AddSwaggerGen(c => { c.SwaggerDoc("V1", new OpenApiInfo { Version = "V1", //版本 Title = $"XUnit.Core 接口文檔-NetCore3.1", //標題 Description = $"XUnit.Core Http API v1", //描述 Contact = new OpenApiContact { Name = "艾三元", Email = "", Url = new Uri("http://i3yuan.cnblogs.com") }, License = new OpenApiLicense { Name = "艾三元許可證", Url = new Uri("http://i3yuan.cnblogs.com") } }); var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//獲取應用程序所在目錄(絕對,不受工做目錄影響,建議採用此方法獲取路徑) //var basePath = AppContext.BaseDirectory; var xmlPath = Path.Combine(basePath, "XUnit.Core.xml");//這個就是剛剛配置的xml文件名 // c.IncludeXmlComments(xmlPath);//默認的第二個參數是false,對方法的註釋 c.IncludeXmlComments(xmlPath,true); // 這個是controller的註釋 #region 加鎖 var openApiSecurity = new OpenApiSecurityScheme { Description = "JWT認證受權,使用直接在下框中輸入Bearer {token}(注意二者之間是一個空格)\"", Name = "Authorization", //jwt 默認參數名稱 In = ParameterLocation.Header, //jwt默認存放Authorization信息的位置(請求頭) Type = SecuritySchemeType.ApiKey }; c.AddSecurityDefinition("oauth2", openApiSecurity); c.OperationFilter<AddResponseHeadersFilter>(); c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>(); c.OperationFilter<SecurityRequirementsOperationFilter>(); #endregion });
c.AddSecurityDefinition("oauth2", openApiSecurity);
這裏的方案名稱必須是oauth2
在未加鎖的狀況下,效果以下:
加上鎖的程序後,執行後發現,
執行效果: