基于.NetCore3.1搭建项目系列 —— 认证授权方案之Swagger加锁
1
開始
在之前的使用Swagger做Api文檔中,我們已經(jīng)使用Swagger進(jìn)行開發(fā)接口文檔,以及更加方便的使用。這一轉(zhuǎn)換,讓更多的接口可以以通俗易懂的方式展現(xiàn)給開發(fā)人員。而在后續(xù)的內(nèi)容中,為了對api資源的保護(hù),我們引入了認(rèn)證授權(quán)方案,利用HTTP提供了一套標(biāo)準(zhǔn)的身份驗證框架,服務(wù)端可以用來針對客戶端的請求發(fā)送質(zhì)詢(challenge),客戶端根據(jù)質(zhì)詢提供應(yīng)答身份驗證憑證,進(jìn)而實現(xiàn)對資源的保護(hù)。
因為之前在使用Swagger的系列中還沒有加身份認(rèn)證授權(quán)這一塊,所以我們使用的接口都是沒有進(jìn)行資源保護(hù)的,而再后續(xù)又對認(rèn)證授權(quán)這一塊進(jìn)行講解又沒有將Swagger好好的利用起來,使得每一次要測試授權(quán)認(rèn)證的時候,都得使用postman在Hearer請求頭中加入Authorization屬性,導(dǎo)致每測試一個接口就得輸入一次token令牌來實現(xiàn)認(rèn)證,重復(fù)操作頻繁,降低工作效率。
這個時候,我們剛好發(fā)現(xiàn),Swagger已經(jīng)幫我們是實現(xiàn)了一次輸入令牌,不同接口多次調(diào)用,提高效率。這樣,我們就可以將之前的Swagger系列和認(rèn)證授權(quán)系列相結(jié)合。
說干就干。。。
2
回顧
Swagger系列:
基于.NetCore3.1系列 —— 使用Swagger做Api文檔 (上篇)
基于.NetCore3.1系列 —— 使用Swagger做Api文檔 (下篇)
基于.NetCore3.1系列 —— 使用Swagger導(dǎo)出文檔 (番外篇)
基于.NetCore3.1系列 —— 使用Swagger導(dǎo)出文檔 (補充篇)
JWT認(rèn)證授權(quán)系列:
基于.NetCore3.1系列 —— 認(rèn)證方案之初步認(rèn)識JWT
基于.NetCore3.1系列 —— 認(rèn)證授權(quán)方案之JwtBearer認(rèn)證
基于.NetCore3.1系列 —— 認(rèn)證授權(quán)方案之授權(quán)初識
基于.NetCore3.1系列 —— 認(rèn)證授權(quán)方案之授權(quán)揭秘 (上篇)
基于.NetCore3.1系列 —— 認(rèn)證授權(quán)方案之授權(quán)揭秘 (下篇)
3
開始
3.1. 添加Swagger
這里我們使用這個系列中的源碼,允許發(fā)現(xiàn),這個在沒有使用配置我們授權(quán)認(rèn)證代碼的情況下,資源api都是處于沒有保護(hù)的情況下,任何人都可以調(diào)用使用,沒有安全性。
? ? ? ??public void ConfigureServices(IServiceCollection services){services.AddSwaggerGen(c =>{c.SwaggerDoc("V1", new OpenApiInfo{Version = "V1", ? //版本Title = $"XUnit.Core 接口文檔-NetCore3.1", ?//標(biāo)題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);//獲取應(yīng)用程序所在目錄(絕對,不受工作目錄影響,建議采用此方法獲取路徑)//var basePath = AppContext.BaseDirectory;var xmlPath = Path.Combine(basePath, "XUnit.Core.xml");//這個就是剛剛配置的xml文件名c.IncludeXmlComments(xmlPath);//默認(rèn)的第二個參數(shù)是false,對方法的注釋// c.IncludeXmlComments(xmlPath,true); //這個是controller的注釋});services.AddControllers();}3.2. 添加認(rèn)證授權(quán)
基于之前的認(rèn)證授權(quán)方案系列,我們這一節(jié)的認(rèn)證授權(quán)就使用之前使用的基于自定義策略授權(quán)的方式,實現(xiàn)授權(quán)。
3.2.1. 定義權(quán)限策略
定義一個權(quán)限策略PermissionRequirement,這個策略并包含一些屬性。
public class PermissionRequirement: IAuthorizationRequirement {public string _permissionName { get; }public PermissionRequirement(string PermissionName){_permissionName = PermissionName;} }3.2.2. 再定義一個策略處理類
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;} }3.2.3. 下面展示了如何將自定義要求添加到策略
(請注意,由于這是自定義要求,因此沒有擴(kuò)展方法,而必須繼續(xù)處理策略對象的整個 Requirements 集合):
? ??public void ConfigureServices(IServiceCollection services){services.AddControllers();//基于自定義策略授權(quán)services.AddAuthorization(options =>{options.AddPolicy("customizePermisson",policy => policy.Requirements.Add(new PermissionRequirement("admin")));});//此外,還需要在 IAuthorizationHandler 類型的范圍內(nèi)向 DI 系統(tǒng)注冊新的處理程序:services.AddScoped<IAuthorizationHandler, PermissionRequirementHandler>();// 如前所述,要求可包含多個處理程序。如果為授權(quán)層的同一要求向 DI 系統(tǒng)注冊多個處理程序,有一個成功就足夠了。}3.2.4. 應(yīng)用自定義的策略的特性
指定當(dāng)前用戶必須是應(yīng)用對控制器或控制器內(nèi)的操作,如
? ?[Authorize(Policy = "customizePermisson")]public class MovieController : ControllerBase{}3.3. 添加Swagger鎖
利用Swagger為我們提供的接口,在AddSwaggerGen服務(wù)中,添加保護(hù)api資源的描述。
??var openApiSecurity = new OpenApiSecurityScheme{Description = "JWT認(rèn)證授權(quán),使用直接在下框中輸入Bearer {token}(注意兩者之間是一個空格)\"",Name = "Authorization", ?//jwt 默認(rèn)參數(shù)名稱In = ParameterLocation.Header, ?//jwt默認(rèn)存放Authorization信息的位置(請求頭)Type = SecuritySchemeType.ApiKey};添加請求頭的Header中的token,傳遞到后臺。
c.OperationFilter<SecurityRequirementsOperationFilter>();開啟加權(quán)鎖
c.OperationFilter<AddResponseHeadersFilter>(); c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();代碼整合如下:在ConfigureServices服務(wù)中
? ? ? ??services.AddSwaggerGen(c =>{c.SwaggerDoc("V1", new OpenApiInfo{Version = "V1", ? //版本Title = $"XUnit.Core 接口文檔-NetCore3.1", ?//標(biāo)題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);//獲取應(yīng)用程序所在目錄(絕對,不受工作目錄影響,建議采用此方法獲取路徑)//var basePath = AppContext.BaseDirectory;var xmlPath = Path.Combine(basePath, "XUnit.Core.xml");//這個就是剛剛配置的xml文件名// c.IncludeXmlComments(xmlPath);//默認(rèn)的第二個參數(shù)是false,對方法的注釋c.IncludeXmlComments(xmlPath,true); // 這個是controller的注釋#region 加鎖var openApiSecurity = new OpenApiSecurityScheme{Description = "JWT認(rèn)證授權(quán),使用直接在下框中輸入Bearer {token}(注意兩者之間是一個空格)\"",Name = "Authorization", ?//jwt 默認(rèn)參數(shù)名稱In = ParameterLocation.Header, ?//jwt默認(rèn)存放Authorization信息的位置(請求頭)Type = SecuritySchemeType.ApiKey};c.AddSecurityDefinition("oauth2", openApiSecurity);c.OperationFilter<AddResponseHeadersFilter>();c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();c.OperationFilter<SecurityRequirementsOperationFilter>();#endregion});c.AddSecurityDefinition("oauth2", openApiSecurity); 這里的方案名稱必須是oauth2
4
運行
在未加鎖的情況下,效果如下:
加上鎖的程序后,執(zhí)行后發(fā)現(xiàn),
執(zhí)行效果:
5
總結(jié)
通過上面的匯總,我們已經(jīng)實現(xiàn)將Swagger和net core身份認(rèn)證授權(quán)才能訪問接口
在以后測試接口授權(quán)的時候,就可以直接通過Swagger中的鎖來調(diào)試運行,減少重復(fù)添加令牌進(jìn)行操作。
搜索關(guān)注公眾號【DotNet技術(shù)谷】--回復(fù)【加鎖】,可獲取本篇文章的源碼。
總結(jié)
以上是生活随笔為你收集整理的基于.NetCore3.1搭建项目系列 —— 认证授权方案之Swagger加锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Core微服务开发服务间调用篇
- 下一篇: 你知道技术委员会吗?嗯,一个既重要却又鸡