.NetCore WebApi——基于JWT的简单身份认证与授权(Swagger)
目录:
.NetCore WebApi——基于JWT的简单身份认证与授权(Swagger)
.NetCore WebApi —— Swagger版本控制
任何项目都有权限这一关键部分。比如我们有许多接口。有的接口允许任何人访问,另有一些接口需要认证身份之后才可以访问;以保证重要数据不会泄露。
关于JWT
维基百科上是这样定义的:
JWT(读作 [/dʒɒt/]),即JSON Web Tokens,是一种基于JSON的、用于在网络上声明某种主张的令牌(token)。JWT通常由三部分组成: 头信息(header), 消息体(payload)和签名(signature)。它是一种用于双方之间传递安全信息的表述性声明规范。JWT作为一个开放的标准(RFC 7519),定义了一种简洁的、自包含的方法,从而使通信双方实现以JSON对象的形式安全的传递信息。
认证的工作流程:
1. 客户端携带用户名、密码向授权服务申请 "令牌(token)"
2.授权服务器验证用户名、密码后根据它的身份生成一张专属的 "令牌" 并JWT的格式规范返回给客户端
3.客户端将获取到的令牌放入到http的请求头中,然后向资源服务器发起请求。服务器根据客户端发送过来的令牌来进行下一步处理(根据身份来响应客户端是否具有当前接口的权限)
如下图所示:
正文:
主要参考园友 在7楼 的这篇文章 https://www.cnblogs.com/RayWang/p/9536524.html
1. 启用Swagger的验证功能
在startup类中新添加红色部分代码。启动项目观察效果。
- // 注册Swagger服务
- services.AddSwaggerGen(c =>
- {
- // 添加文档信息
- c.SwaggerDoc("v1", new Info
- {
- Title = "CoreWebApi",
- Version = "v1",
- Description = "ASP.NET CORE WebApi",
- Contact = new Contact
- {
- Name = "Jee",
- Email = "xiaomaprincess@gmail.com",
- Url = "https://www.cnblogs.com/jixiaosa/"
- }
- });
- #region 读取xml信息
- // 使用反射获取xml文件。并构造出文件的路径
- var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
- var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
- // 启用xml注释. 该方法第二个参数启用控制器的注释,默认为false.
- c.IncludeXmlComments(xmlPath, true);
- #endregion
- #region 启用swagger验证功能
- //添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称一致即可,CoreAPI。
- var security = new Dictionary<string, IEnumerable<string>> { { "CoreAPI", new string[] { } }, };
- c.AddSecurityRequirement(security);
- c.AddSecurityDefinition("CoreAPI", new ApiKeyScheme
- {
- Description = "JWT授权(数据将在请求头中进行传输) 在下方输入Bearer {token} 即可,注意两者之间有空格",
- Name = "Authorization",//jwt默认的参数名称
- In = "header",//jwt默认存放Authorization信息的位置(请求头中)
- Type = "apiKey"
- });
- #endregion
- });
没启动Swagger验证之前是这样的:
启用验证之后再看:多了个小按钮
点开之后是如下界面:文本框里要如输入从服务器获取的Token。格式为:Bearer + 空格+token。 Bearer可以看作是一个默认的规则。
2.生成token
.net core 内置了许多帮助类,巧妙的使用这些类组合,就可以生成我们想要的 token
新建一个tokenl类,编写一个方法来获取JWT字符串
- /// <summary>
- /// 生成JWT字符串
- /// </summary>
- public class Token
- {
- // 密钥,注意不能太短
- public static string secretKey { get; set; } = "xiaomaPrincess@gmail.com";
- /// <summary>
- /// 生成JWT字符串
- /// </summary>
- /// <param name="tokenModel"></param>
- /// <returns></returns>
- public static string GetJWT(TokenModel tokenModel)
- {
- //DateTime utc = DateTime.UtcNow;
- var claims = new List<Claim>
- {
- new Claim(JwtRegisteredClaimNames.Jti,tokenModel.ID.ToString()),
- // 令牌颁发时间
- new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
- new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
- // 过期时间 100秒
- new Claim(JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(100)).ToUnixTimeSeconds()}"),
- new Claim(JwtRegisteredClaimNames.Iss,"API"), // 签发者
- new Claim(JwtRegisteredClaimNames.Aud,"User") // 接收者
- };
- // 密钥
- var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
- var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
- var tokenHandler = new JwtSecurityTokenHandler();
- JwtSecurityToken jwt = new JwtSecurityToken(
- claims: claims,// 声明的集合
- //expires: .AddSeconds(36), // token的有效时间
- signingCredentials: creds
- );
- var handler = new JwtSecurityTokenHandler();
- // 生成 jwt字符串
- var strJWT = handler.WriteToken(jwt);
- return strJWT;
- }
- }
基本信息类
- public class TokenModel
- {
- /// <summary>
- /// ID
- /// </summary>
- public int ID { get; set; }
- /// <summary>
- /// 名称
- /// </summary>
- public string Name { get; set; }
- /// <summary>
- /// 手机
- /// </summary>
- public string Phone { get; set; }
- /// <summary>
- /// 邮箱
- /// </summary>
- public string Email { get; set; }
- /// <summary>
- /// 身份
- /// </summary>
- public string Sub { get; set; }
- }
添加一个方法来获取token
- /// <summary>
- /// 获取令牌
- /// </summary>
- /// <param name="ID">ID</param>
- /// <param name="name">账号</param>
- /// <returns></returns>
- [HttpPost]
- public string GetJwt(int ID,string name)
- {
- TokenModel tokenModel = new TokenModel
- {
- ID = ID,
- Name=name
- };
- return Token.GetJWT(tokenModel);
- }
在Startup类中配置身份认证服务
(1)在ConfigureServices方法中注册服务
- #region 添加验证服务
- // 添加验证服务
- services.AddAuthentication(x =>
- {
- x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
- x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
- }).AddJwtBearer(o =>
- {
- o.TokenValidationParameters = new TokenValidationParameters
- {
- // 是否开启签名认证
- ValidateIssuerSigningKey = true,
- IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Token.secretKey)),
- // 发行人验证,这里要和token类中Claim类型的发行人保持一致
- ValidateIssuer = true,
- ValidIssuer = "API",//发行人
- // 接收人验证
- ValidateAudience = true,
- ValidAudience = "User",//订阅人
- ValidateLifetime = true,
- ClockSkew = TimeSpan.Zero,
- };
- });
- #endregion
(2)在Configure方法中启用验证中间件
- // 启用Swagger中间件
- app.UseSwagger();
- // 配置SwaggerUI
- app.UseSwaggerUI(c =>
- {
- c.SwaggerEndpoint("/swagger/v1/swagger.json", "CoreAPI");
- c.RoutePrefix = string.Empty;
- });
- // 启用认证中间件
- app.UseAuthentication();
- app.UseMvc();
3. 添加一个测试测控制器来检测是否成功
注意要添加 [Authorize]标签
- /// <summary>
- /// 需要身份认证的控制器
- /// </summary>
- [Route("api/[controller]/[action]")]
- [Produces("application/json")]
- [ApiController]
- [Authorize]// 添加授权特性
- public class TestController : ControllerBase
- {
- /// <summary>
- /// 认证通过之后可访问
- /// </summary>
- /// <returns></returns>
- [HttpPost]
- public ActionResult<TokenModel> Get(TokenModel tokenModel)
- {
- return new TokenModel{ ID= };
- }
- }
启动项目
测试一: 在没有获取token时访问此方法
返回401 身份验证未通过
测试二:先访问GetJWT接口获取token,在访问Test接口
最后将获取的token输入到Swagger的文本框中:Bearer +空格+Token
再次访问Test接口:成功返回数据
至此,一个简单身份认证加授权就完成了。
推荐一篇大神的文章 :讲述Claim的
理解ASP.NET Core验证模型(Claim, ClaimsIdentity, ClaimsPrincipal)不得不读的英文博文
源码:GitHub
https://github.com/xiaoMaPrincess/Asp.NetCore-WebApi
多层架构版本:
https://github.com/xiaoMaPrincess/.NetCoreWebApi
.NetCore WebApi——基于JWT的简单身份认证与授权(Swagger)的更多相关文章
- ASP.NET Web API 2系列(四):基于JWT的token身份认证方案
1.引言 通过前边的系列教程,我们可以掌握WebAPI的初步运用,但是此时的API接口任何人都可以访问,这显然不是我们想要的,这时就需要控制对它的访问,也就是WebAPI的权限验证.验证方式非常多,本 ...
- ASP.NET WebApi 基于JWT实现Token签名认证
一.前言 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将会是需要思考的问题.在ASP.NET WebServi ...
- 基于JWT的token身份认证方案
一.使用JSON Web Token的好处? 1.性能问题. JWT方式将用户状态分散到了客户端中,相比于session,可以明显减轻服务端的内存压力. Session方式存储用户id的最大弊病在于S ...
- 基于JWT的token身份认证方案(转)
https://www.cnblogs.com/xiangkejin/archive/2018/05/08/9011119.html 一.使用JSON Web Token的好处? 1.性能问题. JW ...
- springboot结合jwt实现基于restful接口的身份认证
基于restful接口的身份认证,可以采用jwt的方式实现,想了解jwt,可以查询相关资料,这里不做介绍~ 下面直接看如何实现 1.首先添加jwt的jar包,pom.xml中添加依赖包: <de ...
- ASP.NET Core WebApi基于JWT实现接口授权验证
一.ASP.Net Core WebApi JWT课程前言 我们知道,http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再 ...
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(二)
上文已经介绍了Identity Service的实现过程.今天我们继续,实现一个简单的Weather API和一个基于Ocelot的API网关. 回顾 <Angular SPA基于Ocelot ...
- Angular SPA基于Ocelot API网关与IdentityServer4的身份认证与授权(一)
好吧,这个题目我也想了很久,不知道如何用最简单的几个字来概括这篇文章,原本打算取名<Angular单页面应用基于Ocelot API网关与IdentityServer4+ASP.NET Iden ...
- SharePoint 2013 配置基于表单的身份认证
前 言 这里简单介绍一下为SharePoint 2013 配置基于表单的身份认证,简单的说,就是用Net提供的工具创建数据库,然后配置SharePoint 管理中心.STS服务.Web应用程序的三处w ...
随机推荐
- esp-12e折腾
寒假前就从x宝买了esp-12e以及esp32s,当时似乎是想给自己的蓝牙开门升级换代?esp32s拿来过度linux? 寒假放在书包拿回去以为有时间会玩玩,没想到一直耽搁到现在.前两天才拿出来,网上 ...
- R语言学习 第十一篇:日期和时间
R语言的基础包中提供了三种基本类型用于处理日期和时间,Date用于处理日期,它不包括时间和时区信息:POSIXct/POSIXlt用于处理日期和时间,其中包括了日期.时间和时区信息.R内部在存储日期和 ...
- Flask第三方工具组件介绍
flask-wtf组件flask-login组件flask-session组件flask-sqlalchemy组件flask-script组件flask-cache组件flask-assets组件fl ...
- Flask入门之上传文件到服务器
今天要做一个简单的页面,可以实现将文件 上传到服务器(保存在指定文件夹) #Sample.py # coding:utf-8 from flask import Flask,render_templa ...
- python logging method 02
基本用法 下面的代码展示了logging最基本的用法. 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 ...
- PAT1081:Rational Sum
1081. Rational Sum (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Given N ...
- mysql事务之间的隔离级别
事务间未做隔离,会引起下面这些问题. 1.脏读:一个事务可读到另外一个尚未commit的事务中的数据. 2.不可重复读:在一个事务中,读取同一个数据 a,b,按顺序读取,在读a b 之间,另外一个事 ...
- Java公开课-04.异常
一,异常的概念 程序在运行时,发生了我们没有预测的结果,它阻止了程序按照我们预期效果执行 二,怎么保证我们的程序在发生异常以后 ,代码继续执行? 异常处理机制 在程序发生异常以后,还能按照我们事先设定 ...
- tkinter中text文本与scroll滚动条控件(五)
text与scroll控件 import tkinter wuya = tkinter.Tk() wuya.title("wuya") wuya.geometry("30 ...
- Javascript 进阶 继承
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/29194261 1.基于类的继承 下面看下面的代码: <script typ ...