NETCore使用带有权限验证的Swagger
文章目录
Swagger
什么是Swagger
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。方便前后端接口对接。
NuGet安装
打开NuGet程序包,搜索“Swashbuckle.AspNetCore”安装。
注意:NETCore3.0版本需要使用Swashbuckle.AspNetCore5.0以上的版本。我这个用的是NETCore2.2。
Startup注册Swagger
在Startup的ConfigureServices方法中注册Swagger服务。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
#region Swagger
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v0.1.0",//版本号
Title = "ZZTApi文档",//文档标题
Description = "框架说明文档",//文档描述
TermsOfService = "None",//服务条款
Contact = new Contact { Name = "zzt", Email = "000000@qq.com", Url = "www.baidu.com" }//联系人
});
});
#endregion
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
在Startup的Configure方法里面调用Swagger服务
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
#region Swagger
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
});
#endregion
}
- 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界面。可以这样设置:
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
c.RoutePrefix = "";//路径配置,设置为空,表示直接访问该文件。
});
- 1
- 2
- 3
- 4
- 5
有可能每次运行都会默认访问http://localhost:51146/api/values这个路径下的地址。需要在launchSettings.json文件下修改。
为接口添加注释
如图,文档里面我们需要在红框里面为接口添加注释,以方便理解每个接口的功能。
右键项目名称=>属性=>生成,勾选“输出”下面的“xml文档文件”,系统会默认生成一个,你也可以自定义。
这里我用的是相对路径。添加取消警告代码1590。否则会有一些警告。
在接口方法上边添加注释,说明每个接口的功能。
最后在services.AddSwaggerGen里面添加XML文档的路径。
#region Swagger
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v0.1.0",
Title = "ZZTApi文档",
Description = "框架说明文档",
TermsOfService = "None",
Contact = new Contact { Name = "zzt", Email = "529166258@qq.com", Url = "www.baidu.com" }
});
#region 为 Swagger JSON and UI设置xml文档注释路径
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)
var xmlAPIPath = Path.Combine(basePath, "ZZTCoreAPI.xml");//这个就是刚刚配置的xml文件名
var xmlModelPath = Path.Combine(basePath, "ZZTCoreModel.xml");//这个是引用model层的XML文档。设置输出XML文档的方法跟上面的一样。
c.IncludeXmlComments(xmlAPIPath, true);//第二个参数true表示用控制器的XML注释。默认是false
c.IncludeXmlComments(xmlModelPath, true);
#endregion
});
- 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方法里面添加以下代码
#region JWT
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Audience:Secret"]));
services.AddAuthentication("Bearer").AddJwtBearer(o=> {
o.TokenValidationParameters = new TokenValidationParameters
{
//是否开启密钥认证和key值
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
//是否开启发行人认证和发行人
ValidateIssuer = true,
ValidIssuer = Configuration["Audience:Issuer"],
//是否开启订阅人认证和订阅人
ValidateAudience = true,
ValidAudience = Configuration["Audience:Audience"],
//认证时间的偏移量
ClockSkew = TimeSpan.Zero,
//是否开启时间认证
ValidateLifetime = true,
//是否该令牌必须带有过期时间
RequireExpirationTime = true
};
});
#endregion
- 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配置文件里面的一些参数,参数如下:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"Audience": {
"Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs",
"Issuer": "ZZT",
"Audience": "Nobody"
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
注册后需要在Configure
方法里面加入代码app.UseAuthentication();
来开启服务
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//HTTP管道是有先后顺序的,一定要写在 app.Mvc() 之前,否则不起作用。
app.UseAuthentication();
app.UseMvc();
#region Swagger
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
c.RoutePrefix = "";//路径配置,设置为空,表示直接访问该文件,
});
#endregion
}
- 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方法中加入以下代码
// 【授权】,好处就是不用在controller中,写多个 roles 。
// 然后接口授权这么写 [Authorize(Policy = "Admin")]
services.AddAuthorization(options =>
{
options.AddPolicy("Client", policy => policy.RequireRole("Client").Build());
options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
options.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("Admin", "System"));
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
获取JWT的Token
以下代码是获取JWTToken的方法,作用是传入一个model,生成Token,这个model可以根据需求自己定义,涉及主要的两个对象JwtSecurityToken
和JwtSecurityTokenHandler
。
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace ZZTCoreAPI.Common
{
public class JwtHelper
{
public static string IssueJWT(TokenModelJWT tokenModel)
{
var dateTime = DateTime.UtcNow;
string iss = Appsettings.GetConfigure("Audience:Issuer");
string aud = Appsettings.GetConfigure("Audience:Audience");
string secret = Appsettings.GetConfigure("Audience:Secret");
//var claims = new Claim[] //old
var claims = new List<Claim>
{
//下边为Claim的默认配置
new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()),
new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
//这个就是过期时间,目前是过期100秒,可自定义,注意JWT有自己的缓冲过期时间
new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(100)).ToUnixTimeSeconds()}"),
new Claim(JwtRegisteredClaimNames.Iss,iss),
new Claim(JwtRegisteredClaimNames.Aud,aud),
//new Claim(ClaimTypes.Role,tokenModel.Role),//为了解决一个用户多个角色(比如:Admin,System),用下边的方法
};
// 可以将一个用户的多个角色全部赋予;
// 作者:DX 提供技术支持;
claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
//秘钥 (SymmetricSecurityKey 对安全性的要求,密钥的长度太短会报出异常)
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var jwt = new JwtSecurityToken(
issuer: iss,
claims: claims,
signingCredentials: creds);
var jwtHandler = new JwtSecurityTokenHandler();
var encodedJwt = jwtHandler.WriteToken(jwt);
return encodedJwt;
}
}
/// <summary>
/// 令牌
/// </summary>
public class TokenModelJWT
{
/// <summary>
/// Id
/// </summary>
public long Uid { get; set; }
/// <summary>
/// 角色
/// </summary>
public string Role { get; set; }
/// <summary>
/// 职能
/// </summary>
public string Work { get; set; }
}
}
- 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?这是规定。
[HttpGet]
public ActionResult<string> GetToken(string name, string pwd)
{
string jwtStr = string.Empty;
bool suc = false;
//这里就是用户登陆以后,通过数据库去调取数据,分配权限的操作
//这里直接写死了
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pwd))
{
return new JsonResult(new
{
Status = false,
message = "用户名或密码不能为空"
});
}
TokenModelJWT tokenModel = new TokenModelJWT();
tokenModel.Uid = 1;
tokenModel.Role = name;
jwtStr = JwtHelper.IssueJWT(tokenModel);
suc = true;
return Ok(new
{
success = suc,
token = jwtStr
});
}
- 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服务内部:
#region Token绑定到ConfigureServices
//添加header验证信息
//c.OperationFilter<SwaggerHeader>();
var security = new Dictionary<string, IEnumerable<string>> { { "ZZTAPI", new string[] { } }, };
c.AddSecurityRequirement(security);
//方案名称“Blog.Core”可自定义,上下一致即可
c.AddSecurityDefinition("ZZTAPI", new ApiKeyScheme
{
Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"",
Name = "Authorization",//jwt默认的参数名称
In = "header",//jwt默认存放Authorization信息的位置(请求头中)
Type = "apiKey"
});
#endregion
- 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
NETCore使用带有权限验证的Swagger的更多相关文章
- 使用nginx配置带有权限验证的反向代理
环境:centos6u3 1.安装nginx (1)上传nginx nginx-1.14.0.tar.gz.可以从nginx官网下载http://nginx.org/en/download.html ...
- Z从壹开始前后端分离【 .NET Core2.2/3.0 +Vue2.0 】框架之五 || Swagger的使用 3.3 JWT权限验证【必看】
本文梯子 本文3.0版本文章 前言 1.如何给接口实现权限验证? 零.生成 Token 令牌 一.JWT ——自定义中间件 0.Swagger中开启JWT服务 1:API接口授权策略 2.自定义认证之 ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之五 || Swagger的使用 3.3 JWT权限验证【必看】
前言 关于JWT一共三篇 姊妹篇,内容分别从简单到复杂,一定要多看多想: 一.Swagger的使用 3.3 JWT权限验证[修改] 二.解决JWT权限验证过期问题 三.JWT完美实现权限与接口的动态分 ...
- Swagger如何访问Ocelot中带权限验证的API
先亮源代码:https://github.com/axzxs2001/Asp.NetCoreExperiment/tree/master/Asp.NetCoreExperiment/SwaggerDe ...
- 跟我一起学.NetCore之熟悉的接口权限验证不能少(Jwt)
前言 权限管控对于一个系统来说是非常重要的,最熟悉不过的是菜单权限和数据权限,上一节通过Jwt实现了认证,接下来用它实现接口权限的验证,为什么不是菜单权限呢?对于前后端分离而言,称其为接口权限感觉比较 ...
- Swagger生成的接口需要权限验证的处理方法
通常开发API的时候需要对接口进行权限验证,而我们在使用Swagger生成接口文档界面的时候,直接调用需要权限验证的接口会提示"当前用户没有登陆" 为了解决此问题,我们需要更改一下 ...
- 从壹开始前后端分离 [ vue + .netcore 补程 ] 三十一║ Nuxt终篇:基于Vuex的权限验证探究
缘起 哈喽大家好,今天周四啦,楼主明天要正式放假了,这里先祝大家节日快乐咯,希望在家里能继续研究点儿东西吧,今天呢是 nuxt 的最后一篇,主要是对权限登录进行研究,这一块咱们之前在说第一个项目的时候 ...
- .Net Core3.0 WebApi 项目框架搭建 四:JWT权限验证
.Net Core3.0 WebApi 项目框架搭建:目录 什么是JWT 根据维基百科定义,JWT(读作 [/dʒɒt/]),即JSON Web Tokens,是一种基于JSON的.用于在网络上声明某 ...
- Spring MVC 使用拦截器优雅地实现权限验证功能
在上一篇 SpringAOP 实现功能权限校验功能 中虽然用AOP通过抛异常,请求转发等勉强地实现了权限验证功能,但感觉不是那么完美,应该用拦截器来实现才是最佳的,因为拦截器就是用来拦截请求的,在请求 ...
随机推荐
- 关于ORACLE图形化安装过程中出现的竖线的处理办法
这种情况上传个jre 并指定下就好了 ~/database/runInstaller -jreLoc /usr/local/jre1.8.0_191/
- 利用DNS日志进行MySQL盲注
0x01 技术原理 这里是利用load_file这个函数利用smb请求方式请求域名机器下的一个文件,由于计算机对该域名不熟悉所以需要优先请求DNS,所以我们通过DNS日志记录中的内容来获取回显.解决了 ...
- JAVA concurrent包下Semaphore、CountDownLatch等用法
CountDownLatch 跟join的区别 CountDownLatch用处跟join很像,但是CountDownLatch更加灵活,如果子线程有多个阶段a.b.c; 那么我们可以实现在a阶段完成 ...
- 迁移生产环境的GItLab11.3.5到新的服务器
在新的服务器上 rpm安装git 首先停止,Gitlab服务 root@localhost # gitlab-ctl stop 参考了 以下链接: https://blog.csdn.net/liul ...
- Linux服务器PHP后门查杀
shell脚本一句话查找PHP一句话木马 # find ./ -name "*.php" |xargs egrep "phpspy|c99sh|milw0rm|eval( ...
- 第03节-BLE协议各层数据格式概述
本篇博客根据韦大仙的视频,整理所得. 对于BLE系统,它分为上下两块.上面那一块,我们称为host主机.下面这一块是controller,你可以简单的认为它就是一个蓝牙芯片. 对于host这一块,它运 ...
- 16-C#笔记-枚举
枚举同C++ using System; namespace EnumApplication { class EnumProgram { enum Days { Sun, Mon, tue, Wed, ...
- python基础之函数重点
函数的返回值 现在有一个需求,比较两个人的月薪,然后想获取月薪较大人的年薪. 如果需要在程序中拿到函数的处理结果做进一步的处理,则需要函数必须要有返回值. 需要注意的是: return是一个函数结束的 ...
- Educational Codeforces Round 78 (Rated for Div. 2) D. Segment Tree
链接: https://codeforces.com/contest/1278/problem/D 题意: As the name of the task implies, you are asked ...
- 9.consul获取服务实例,调用测试
package main import ( "context" "fmt" "github.com/go-kit/kit/endpoint" ...