在以前的使用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
在未加锁的状况下,效果以下:
加上锁的程序后,执行后发现,
执行效果: