原文:NETCore使用带有权限验证的Swagger

Swagger

什么是Swagger

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。方便前后端接口对接。

NuGet安装

打开NuGet程序包,搜索“Swashbuckle.AspNetCore”安装。

注意:NETCore3.0版本需要使用Swashbuckle.AspNetCore5.0以上的版本。我这个用的是NETCore2.2。

Startup注册Swagger

在Startup的ConfigureServices方法中注册Swagger服务。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
  4. #region Swagger
  5. services.AddSwaggerGen(c =>
  6. {
  7. c.SwaggerDoc("v1", new Info
  8. {
  9. Version = "v0.1.0",//版本号
  10. Title = "ZZTApi文档",//文档标题
  11. Description = "框架说明文档",//文档描述
  12. TermsOfService = "None",//服务条款
  13. Contact = new Contact { Name = "zzt", Email = "000000@qq.com", Url = "www.baidu.com" }//联系人
  14. });
  15. });
  16. #endregion
  17. }
  18.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

在Startup的Configure方法里面调用Swagger服务

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  2. {
  3. if (env.IsDevelopment())
  4. {
  5. app.UseDeveloperExceptionPage();
  6. }
  7. app.UseMvc();
  8. #region Swagger
  9. app.UseSwagger();
  10. app.UseSwaggerUI(c =>
  11. {
  12. c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
  13. });
  14. #endregion
  15. }
  16.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

保存后按F5调试,浏览器地址访问http://localhost:51146/swagger/index.html(每个人端口号可能不一样)。

设置默认首页打开Swagger

如果不想每次访问都要输入/swagger/index.html来使用Swagger,希望根目录就是Swagger界面。可以这样设置:

  1. app.UseSwaggerUI(c =>
  2. {
  3. c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
  4. c.RoutePrefix = "";//路径配置,设置为空,表示直接访问该文件。
  5. });
  6.  
    • 1
    • 2
    • 3
    • 4
    • 5

有可能每次运行都会默认访问http://localhost:51146/api/values这个路径下的地址。需要在launchSettings.json文件下修改。

为接口添加注释

如图,文档里面我们需要在红框里面为接口添加注释,以方便理解每个接口的功能。



右键项目名称=>属性=>生成,勾选“输出”下面的“xml文档文件”,系统会默认生成一个,你也可以自定义。

这里我用的是相对路径。添加取消警告代码1590。否则会有一些警告。



在接口方法上边添加注释,说明每个接口的功能。



最后在services.AddSwaggerGen里面添加XML文档的路径。

  1. #region Swagger
  2. services.AddSwaggerGen(c =>
  3. {
  4. c.SwaggerDoc("v1", new Info
  5. {
  6. Version = "v0.1.0",
  7. Title = "ZZTApi文档",
  8. Description = "框架说明文档",
  9. TermsOfService = "None",
  10. Contact = new Contact { Name = "zzt", Email = "529166258@qq.com", Url = "www.baidu.com" }
  11. });
  12. #region 为 Swagger JSON and UI设置xml文档注释路径
  13. var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)
  14. var xmlAPIPath = Path.Combine(basePath, "ZZTCoreAPI.xml");//这个就是刚刚配置的xml文件名
  15. var xmlModelPath = Path.Combine(basePath, "ZZTCoreModel.xml");//这个是引用model层的XML文档。设置输出XML文档的方法跟上面的一样。
  16. c.IncludeXmlComments(xmlAPIPath, true);//第二个参数true表示用控制器的XML注释。默认是false
  17. c.IncludeXmlComments(xmlModelPath, true);
  18. #endregion
  19. });
  20.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

以上代码还添加了一个model层的XML文档。设置方法是一样的。它的效果可以看以下几张图。







以上就是Swagger一些简单应用

JWT

什么是JWT

JWT,即JSON Web Tokens,是一种基于JSON的、用于在网络上声明某种主张的令牌(token)。JWT通常由三部分组成: 头信息(header), 消息体(payload)和签名(signature)。它是一种用于双方之间传递安全信息的表述性声明规范。JWT作为一个开放的标准(RFC 7519),定义了一种简洁的、自包含的方法,从而使通信双方实现以JSON对象的形式安全的传递信息。

注册授权认证服务

在Startup的ConfigureServices方法里面添加以下代码

  1. #region JWT
  2. var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Audience:Secret"]));
  3. services.AddAuthentication("Bearer").AddJwtBearer(o=> {
  4. o.TokenValidationParameters = new TokenValidationParameters
  5. {
  6. //是否开启密钥认证和key值
  7. ValidateIssuerSigningKey = true,
  8. IssuerSigningKey = signingKey,
  9. //是否开启发行人认证和发行人
  10. ValidateIssuer = true,
  11. ValidIssuer = Configuration["Audience:Issuer"],
  12. //是否开启订阅人认证和订阅人
  13. ValidateAudience = true,
  14. ValidAudience = Configuration["Audience:Audience"],
  15. //认证时间的偏移量
  16. ClockSkew = TimeSpan.Zero,
  17. //是否开启时间认证
  18. ValidateLifetime = true,
  19. //是否该令牌必须带有过期时间
  20. RequireExpirationTime = true
  21. };
  22. });
  23. #endregion
  24.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

其中Configuration[“Audience:xxx”]是读取appsettings.json配置文件里面的一些参数,参数如下:

  1. {
  2. "Logging": {
  3. "LogLevel": {
  4. "Default": "Warning"
  5. }
  6. },
  7. "AllowedHosts": "*",
  8. "Audience": {
  9. "Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs",
  10. "Issuer": "ZZT",
  11. "Audience": "Nobody"
  12. }
  13. }
  14.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

注册后需要在Configure方法里面加入代码app.UseAuthentication();来开启服务

  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  2. {
  3. if (env.IsDevelopment())
  4. {
  5. app.UseDeveloperExceptionPage();
  6. }
  7. //HTTP管道是有先后顺序的,一定要写在 app.Mvc() 之前,否则不起作用。
  8. app.UseAuthentication();
  9. app.UseMvc();
  10. #region Swagger
  11. app.UseSwagger();
  12. app.UseSwaggerUI(c =>
  13. {
  14. c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
  15. c.RoutePrefix = "";//路径配置,设置为空,表示直接访问该文件,
  16. });
  17. #endregion
  18. }
  19.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

API接口添加授权策略

在接口方法上边加入Authorize特性,表示该接口需要进行授权认证。

带上Roles参数表示是基于角色的策略



如果有多个角色授权的话,在Startup的ConfigureServices方法中加入以下代码

  1. // 【授权】,好处就是不用在controller中,写多个 roles 。
  2. // 然后接口授权这么写 [Authorize(Policy = "Admin")]
  3. services.AddAuthorization(options =>
  4. {
  5. options.AddPolicy("Client", policy => policy.RequireRole("Client").Build());
  6. options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
  7. options.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("Admin", "System"));
  8. });
  9.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

获取JWT的Token

以下代码是获取JWTToken的方法,作用是传入一个model,生成Token,这个model可以根据需求自己定义,涉及主要的两个对象JwtSecurityTokenJwtSecurityTokenHandler

  1. using Microsoft.IdentityModel.Tokens;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IdentityModel.Tokens.Jwt;
  5. using System.Linq;
  6. using System.Security.Claims;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace ZZTCoreAPI.Common
  10. {
  11. public class JwtHelper
  12. {
  13. public static string IssueJWT(TokenModelJWT tokenModel)
  14. {
  15. var dateTime = DateTime.UtcNow;
  16. string iss = Appsettings.GetConfigure("Audience:Issuer");
  17. string aud = Appsettings.GetConfigure("Audience:Audience");
  18. string secret = Appsettings.GetConfigure("Audience:Secret");
  19. //var claims = new Claim[] //old
  20. var claims = new List<Claim>
  21. {
  22. //下边为Claim的默认配置
  23. new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()),
  24. new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
  25. new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
  26. //这个就是过期时间,目前是过期100秒,可自定义,注意JWT有自己的缓冲过期时间
  27. new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(100)).ToUnixTimeSeconds()}"),
  28. new Claim(JwtRegisteredClaimNames.Iss,iss),
  29. new Claim(JwtRegisteredClaimNames.Aud,aud),
  30. //new Claim(ClaimTypes.Role,tokenModel.Role),//为了解决一个用户多个角色(比如:Admin,System),用下边的方法
  31. };
  32. // 可以将一个用户的多个角色全部赋予;
  33. // 作者:DX 提供技术支持;
  34. claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
  35. //秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常)
  36. var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
  37. var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
  38. var jwt = new JwtSecurityToken(
  39. issuer: iss,
  40. claims: claims,
  41. signingCredentials: creds);
  42. var jwtHandler = new JwtSecurityTokenHandler();
  43. var encodedJwt = jwtHandler.WriteToken(jwt);
  44. return encodedJwt;
  45. }
  46. }
  47. /// <summary>
  48. /// 令牌
  49. /// </summary>
  50. public class TokenModelJWT
  51. {
  52. /// <summary>
  53. /// Id
  54. /// </summary>
  55. public long Uid { get; set; }
  56. /// <summary>
  57. /// 角色
  58. /// </summary>
  59. public string Role { get; set; }
  60. /// <summary>
  61. /// 职能
  62. /// </summary>
  63. public string Work { get; set; }
  64. }
  65. }
  66.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

以下代码是获取Token的接口,作用是根据传入的账号密码生成一个model传入以下代码中的IssueJWT方法以获取Token返回给前端。前端在 Http 的 Header 里,增加属性Authorization,并把这个Token带上Bearer 即Bearer {Token}这个值赋给Authorization属性作为访问其他接口的授权校验。为什么一定要加Bearer?这是规定。

  1. [HttpGet]
  2. public ActionResult<string> GetToken(string name, string pwd)
  3. {
  4. string jwtStr = string.Empty;
  5. bool suc = false;
  6. //这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
  7. //这里直接写死了
  8. if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pwd))
  9. {
  10. return new JsonResult(new
  11. {
  12. Status = false,
  13. message = "用户名或密码不能为空"
  14. });
  15. }
  16. TokenModelJWT tokenModel = new TokenModelJWT();
  17. tokenModel.Uid = 1;
  18. tokenModel.Role = name;
  19. jwtStr = JwtHelper.IssueJWT(tokenModel);
  20. suc = true;
  21. return Ok(new
  22. {
  23. success = suc,
  24. token = jwtStr
  25. });
  26. }
  27.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

以上就是JWT的应用。

Swagger中开启JWT服务

我们要测试 JWT 授权认证,就必定要输入 Token令牌。Swagger 已经帮我们实现了这个录入 Token令牌的功能,需要在服务中开启:

在ConfigureServices -> AddSwaggerGen 服务中,增加以下代码,注意是swagger服务内部:

  1. #region Token绑定到ConfigureServices
  2. //添加header验证信息
  3. //c.OperationFilter<SwaggerHeader>();
  4. var security = new Dictionary<string, IEnumerable<string>> { { "ZZTAPI", new string[] { } }, };
  5. c.AddSecurityRequirement(security);
  6. //方案名称“Blog.Core”可自定义,上下一致即可
  7. c.AddSecurityDefinition("ZZTAPI", new ApiKeyScheme
  8. {
  9. Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"",
  10. Name = "Authorization",//jwt默认的参数名称
  11. In = "header",//jwt默认存放Authorization信息的位置(请求头中)
  12. Type = "apiKey"
  13. });
  14. #endregion
  15.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

测试流程

F5进入调试,进入Swagger界面,调用刚刚写的GetToken接口获取Token



将Token复制填到Authorize属性



最后访问我们之前加了[Authorize(Roles ="zzt")]特性的接口



可以看到是访问得到的,如果我们不带Token去访问的话会返回401的状态码,请求要求身份验证。

完!

参考文章:https://www.cnblogs.com/laozhang-is-phi/p/9511869.html#autoid-2-0-0

发布了30 篇原创文章 · 获赞 5 · 访问量 1万+

NETCore使用带有权限验证的Swagger的更多相关文章

  1. 使用nginx配置带有权限验证的反向代理

    环境:centos6u3 1.安装nginx (1)上传nginx nginx-1.14.0.tar.gz.可以从nginx官网下载http://nginx.org/en/download.html ...

  2. Z从壹开始前后端分离【 .NET Core2.2/3.0 +Vue2.0 】框架之五 || Swagger的使用 3.3 JWT权限验证【必看】

    本文梯子 本文3.0版本文章 前言 1.如何给接口实现权限验证? 零.生成 Token 令牌 一.JWT ——自定义中间件 0.Swagger中开启JWT服务 1:API接口授权策略 2.自定义认证之 ...

  3. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之五 || Swagger的使用 3.3 JWT权限验证【必看】

    前言 关于JWT一共三篇 姊妹篇,内容分别从简单到复杂,一定要多看多想: 一.Swagger的使用 3.3 JWT权限验证[修改] 二.解决JWT权限验证过期问题 三.JWT完美实现权限与接口的动态分 ...

  4. Swagger如何访问Ocelot中带权限验证的API

    先亮源代码:https://github.com/axzxs2001/Asp.NetCoreExperiment/tree/master/Asp.NetCoreExperiment/SwaggerDe ...

  5. 跟我一起学.NetCore之熟悉的接口权限验证不能少(Jwt)

    前言 权限管控对于一个系统来说是非常重要的,最熟悉不过的是菜单权限和数据权限,上一节通过Jwt实现了认证,接下来用它实现接口权限的验证,为什么不是菜单权限呢?对于前后端分离而言,称其为接口权限感觉比较 ...

  6. Swagger生成的接口需要权限验证的处理方法

    通常开发API的时候需要对接口进行权限验证,而我们在使用Swagger生成接口文档界面的时候,直接调用需要权限验证的接口会提示"当前用户没有登陆" 为了解决此问题,我们需要更改一下 ...

  7. 从壹开始前后端分离 [ vue + .netcore 补程 ] 三十一║ Nuxt终篇:基于Vuex的权限验证探究

    缘起 哈喽大家好,今天周四啦,楼主明天要正式放假了,这里先祝大家节日快乐咯,希望在家里能继续研究点儿东西吧,今天呢是 nuxt 的最后一篇,主要是对权限登录进行研究,这一块咱们之前在说第一个项目的时候 ...

  8. .Net Core3.0 WebApi 项目框架搭建 四:JWT权限验证

    .Net Core3.0 WebApi 项目框架搭建:目录 什么是JWT 根据维基百科定义,JWT(读作 [/dʒɒt/]),即JSON Web Tokens,是一种基于JSON的.用于在网络上声明某 ...

  9. Spring MVC 使用拦截器优雅地实现权限验证功能

    在上一篇 SpringAOP 实现功能权限校验功能 中虽然用AOP通过抛异常,请求转发等勉强地实现了权限验证功能,但感觉不是那么完美,应该用拦截器来实现才是最佳的,因为拦截器就是用来拦截请求的,在请求 ...

随机推荐

  1. elasticsearch regexp查询特殊字符处理

    regexp表面意思就是正则查询,但是如果遇到,查询条件中包含特殊的字符串, 就会发现,需要进行相应的转义处理 需要处理Lucene regexps即可: /** * 转义字符串中的特殊字符 * 仅过 ...

  2. MySQL Execution Plan--文件排序(file sort)

    在MySQL处理ORDER BY语句时,如果查询无法利用索引的有序性,则需要额外操作对数据进行排序.在MySQL中有三种排序算法: 1.快速排序(Quick Sort),对冒泡排序的一种改进,基本思想 ...

  3. Java数据类型(1)

    基本数据类型 A.整型 byte:(8位--1个字节 有符号 以二进制补码表示) 范围:-27~27-1 即 -128~127 short:(16位--2个字节 有符号 以二进制补码表示) 范围:-2 ...

  4. yum lockfile is held by another process

    使用yum安装软件报错 yum lockfile is held by another process 解决方法 rm -f /var/run/yum.pid

  5. 201671010450-姚玉婷-实验十四 团队项目评审&课程学习总结

    项目 内容 所属科目 软件工程http://www.cnblogs.com/nwnu-daizh 作业要求 https://www.cnblogs.com/nwnu-daizh/p/11093584. ...

  6. hadoop exit code 退出码含义

    原文传送门:http://www.2cto.com/database/201308/236519.html "OS error code 1: Operation not permitted ...

  7. browserslist详解

    https://www.jianshu.com/p/d45a31c50711 https://juejin.im/post/5b8cff326fb9a019fd1474d6 https://githu ...

  8. pycharm初识及格式化输出

    #_*_coding:utf-8_*_#作者:王佃元#日期:2019/12/6 #格式化输出name = input("Name")age = input("Age&qu ...

  9. three.js 测试1

    关键看一下里面的注释 代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /& ...

  10. haproxy 配置文件详解 之 配置文件示例

    此示例文件在haproxy1.8.20 测试没有问题: global log 127.0.0.1 local0 info maxconn user nobody group nobody daemon ...