NetCoreApi框架搭建三、JWT授权验证)
1.首先还是粘贴大神的链接
虽然说大神的博客已经讲得很详细了,但是此处还是自己动手好点。
首先配置Startup Swagger的验证

2.新建一个项目存放tokenmodel和生成token并且存入缓存

以上是tokenmodel 具体属性可以自定义

缓存帮助类安装nuget包Microsoft.Extensions.Caching.Memory
代码:
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Text;
namespace MyFirstFrame.Token.Model
{
/// 缓存
public class RayPIMemoryCache
{
public static MemoryCache _cache = new MemoryCache(new MemoryCacheOptions());
/// 验证缓存项是否存在
///缓存Key
///
public static bool Exists(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
object cached;
return _cache.TryGetValue(key,out cached);
}
///
/// 获取缓存
///
///缓存Key
///
public static object Get(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.Get(key);
}
///
/// 添加缓存
///
///缓存Key
///缓存Value
///滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)
///绝对过期时长
///
public static bool AddMemoryCache(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_cache.Set(key, value,new MemoryCacheEntryOptions().SetSlidingExpiration(expiresSliding).SetAbsoluteExpiration(expiressAbsoulte));
return Exists(key);
}
}
}
生成token字符串

代码:
using Microsoft.Extensions.Caching.Memory;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text; namespace MyFirstFrame.Token.Model
{
///
/// 令牌类
///
public class RayPIToken
{
public RayPIToken()
{
}
/// 获取JWT字符串并存入缓存
public static string IssueJWT(TokenModel tokenModel, TimeSpan expiresSliding, TimeSpan expiresAbsoulte)
{
DateTime UTC = DateTime.UtcNow;
Claim[] claims = new Claim[]
{
new Claim(JwtRegisteredClaimNames.Sub,tokenModel.Sub),//Subject,
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),//JWT ID,JWT的唯一标识
new Claim(JwtRegisteredClaimNames.Iat, UTC.ToString(), ClaimValueTypes.Integer64),//Issued At,JWT颁发的时间,采用标准unix时间,用于验证过期
};
JwtSecurityToken jwt = new JwtSecurityToken(
issuer: "MyFirstFrame",//jwt签发者,非必须
audience: tokenModel.Uname,//jwt的接收该方,非必须
claims: claims,//声明集合
expires: UTC.AddHours(12),//指定token的生命周期,unix时间戳格式,非必须
signingCredentials: new Microsoft.IdentityModel.Tokens
.SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII.GetBytes("MyFirstFrame's Secret Key")), SecurityAlgorithms.HmacSha256));//使用私钥进行签名加密
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);//生成最后的JWT字符串
RayPIMemoryCache.AddMemoryCache(encodedJwt, tokenModel, expiresSliding, expiresAbsoulte);//将JWT字符串和tokenModel作为key和value存入缓存
return encodedJwt;
}
}
}
新建中间件:TokenAuth

代码:
using Microsoft.Extensions.Caching.Memory;
using Microsoft.AspNetCore.Http;
using MyFirstFrame.Token.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks; namespace MyFirstFrame.AuthHelper
{
///
/// Token验证授权中间件
///
public class TokenAuth
{
///
/// http委托
///
private readonly RequestDelegate _next;
///
/// 构造函数
///
///
public TokenAuth(RequestDelegate next)
{
_next = next;
}
///
/// 验证授权
///
///
///
public Task Invoke(HttpContext httpContext)
{
//获取请求头部
var headers = httpContext.Request.Headers;
//检测是否包含'Authorization'请求头,如果不包含返回context进行下一个中间件,用于访问不需要认证的API
if (!headers.ContainsKey("Authorization"))
{
return _next(httpContext);
}
var tokenStr = headers["Authorization"];
try
{
string jwtStr = tokenStr.ToString().Substring("Bearer ".Length).Trim();
//验证缓存中是否存在该jwt字符串
if (!RayPIMemoryCache.Exists(jwtStr))
{
return httpContext.Response.WriteAsync("非法请求");
}
TokenModel tm = ((TokenModel)RayPIMemoryCache.Get(jwtStr));
//提取tokenModel中的Sub属性进行authorize认证
List lc = new List();
Claim c = new Claim(tm.Sub + "Type", tm.Sub);
lc.Add(c);
ClaimsIdentity identity = new ClaimsIdentity(lc);
ClaimsPrincipal principal = new ClaimsPrincipal(identity);
httpContext.User = principal;
return _next(httpContext);
}
catch (Exception)
{
return httpContext.Response.WriteAsync("token验证异常");
}
} }
}
在Startup配置注意这里需要放在app.UseMvc();上面

注册缓存和验证:

3.验证使用
为了验证使用我直接写了一个生成token字符串的接口




点击验证,这样你的接口就可以访问成功了。
2019.9.11更新
感觉出现瓶颈了,搭完简单的框架之后就不知道要干嘛了,感觉一下没有目标了,所以就抽空把JWT来深入一下。
前面讲的JWT是存入缓存的,所以用不用JWT生成字符串其实都无所谓,下面讲一下JWT的身份验证。
这生成JWT字符串的类里面加了两个方法,一个是生成字符串,一个是解析字符串的
代码:
///
/// 获取JWT字符串
///
///
///
///
///
public static string IssueJWTNew(TokenModel model)
{
DateTime UTC = DateTime.UtcNow;
Claim[] claims = new Claim[] {
new Claim(JwtRegisteredClaimNames.Sub,model.UserID.ToString()),//Subject,
new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat,UTC.ToString(),ClaimValueTypes.Integer64),
new Claim(ClaimTypes.Role,model.SystemRoleId),
new Claim("Role",model.SystemRoleId.ToString()),
new Claim("Name",model.Name.ToString())
};
//秘钥
var jwtConfig = new JwtAuthConfigModel();
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtConfig.JWTSecretKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
//过期时间
double exp = 0;
switch (model.TokenType)
{
case "Web":
exp = jwtConfig.WebExp;
break;
case "App":
exp = jwtConfig.AppExp;
break;
case "MiniProgram":
exp = jwtConfig.MiniProgramExp;
break;
case "Other":
exp = jwtConfig.OtherExp;
break;
}
JwtSecurityToken jwt = new JwtSecurityToken(
issuer: "XQP.NetCore",
audience: model.Name,
claims: claims,
expires: UTC.AddHours(exp),
signingCredentials: creds
);
var jwtHandler = new JwtSecurityTokenHandler();
var encodedJwt = jwtHandler.WriteToken(jwt);
return encodedJwt;
} ///
/// 解析
///
///
///
public static TokenModel SerializeJWT(string jwtStr)
{
var jwtHandler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
object role = new object(); ;
object name = new object();
try
{
jwtToken.Payload.TryGetValue("Role", out role);
jwtToken.Payload.TryGetValue("Name", out name);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
var tm = new TokenModel
{
UserID = int.Parse(jwtToken.Subject),
SystemRoleId =role.ToString(),
Name = name.ToString(),
};
return tm;
}
同时在登录哪里登录成功之后调用生成字符串的方法,并返回。
实体也根据自己的情况修改了一下,这里其实主要用的角色这个字段
还加了一个配置类,主要配置密钥和过期时间的
最后就是中间件的修改了,这里给解析出来的身份进行了授权。
然后就是Startup配置修改了,这里用的是画红线的那个,大神说可以用多个身份的,我试了没成功,如果有哪位知道原因也可以告诉我一下
然后和之前一下使用就可以了,登录的时候拿到JWT字符串,然后访问接口的时候进行认证(直接用Swagger上的锁就可以)
NetCoreApi框架搭建三、JWT授权验证)的更多相关文章
- .Net Core3.0 WebApi 项目框架搭建 四:JWT权限验证
.Net Core3.0 WebApi 项目框架搭建:目录 什么是JWT 根据维基百科定义,JWT(读作 [/dʒɒt/]),即JSON Web Tokens,是一种基于JSON的.用于在网络上声明某 ...
- NetCoreApi框架搭建三、AutoFac 依赖入注)
这里不多做理论上的解释,因为我感觉自己也不是很完全的理解,所以只是记录我自己做的过程. 首先还是粘贴大神的链接:https://www.cnblogs.com/RayWang/p/11165509.h ...
- 【从零开始搭建自己的.NET Core Api框架】(四)实战!带你半个小时实现接口的JWT授权验证
系列目录 一. 创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...
- Unity 游戏框架搭建 (三) MonoBehaviour单例的模板
上一篇文章讲述了如何设计C#单例的模板.也随之抛出了问题: 如何设计接收MonoBehaviour生命周期的单例的模板? 如何设计? 先分析下需求: 1.约束脚本实例对象的个数. 2.约束 ...
- .Net Core3.0 WebApi 项目框架搭建 三:读取appsettings.json
.Net Core3.0 WebApi 项目框架搭建:目录 appsettings.json 我们在写项目时往往会把一些经常变动的,可能会变动的参数写到配置文件.数据库中等可以存储数据且方便配置的地方 ...
- .Net Core官方的 JWT 授权验证
什么是JWT? JSON Web令牌(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地传输信息作为JSON对象.由于此信息是经过数字签名的,因此可以被验 ...
- 自定义统一api返回json格式(app后台框架搭建三)
在统一json自定义格式的方式有多种:1,直接重写@reposeBody的实现,2,自定义一个注解,自己去解析对象成为json字符串进行返回 第一种方式,我就不推荐,想弄得的话,可以自己去研究一下源码 ...
- NetCoreApi框架搭建(一、swagger插件使用)
1.首先用vs2017创建新的项目 2.开始引入swagger插件 右击项目=>管理NuGet程序包=>搜索Swashbuckle.AspNetCore点击安装 3.打开Startup.c ...
- 基于Web Service的客户端框架搭建三:代理层(Proxy)
前言 代理层的主要工作是调用Web Service,将在FCL层序列化好的Json数据字符串Post到Web Service,然后获得Reponse,再从响应流中读取到调用结果Json字符串,在Dis ...
随机推荐
- Flask配置Cors跨域
1 跨域的理解 跨域是指:浏览器A从服务器B获取的静态资源,包括Html.Css.Js,然后在Js中通过Ajax访问C服务器的静态资源或请求.即:浏览器A从B服务器拿的资源,资源中想访问服务器C的资源 ...
- MP的自动填充功能
用来进行自动填充时间. 使用注解@TableTield(fill=FieldFill.insert)插入时进行性填充 使用注解@TableTield(fill=FieldFill.Update)更新时 ...
- Spark & Scala:
https://blog.csdn.net/do_yourself_go_on/article/details/76033252 Spark源码之reduceByKey与GroupByKey ...
- CF1234A Equalize Prices
洛谷 CF1234A Equalize Prices Again 洛谷传送门 题目描述 You are both a shop keeper and a shop assistant at a sma ...
- 洛谷 U86501 趣味擂台
洛谷 U86501 趣味擂台 题目传送门 题目背景 \(JDFZ\)\(2019\)秋季运动会开始辣!运动会中有一个叫做"趣味擂台"的游戏...... 题目描述 游戏内容是这样的: ...
- Ubuntu16.04安装flume
参考:https://www.cnblogs.com/soyo/p/7686702.html
- Jmeter接口测试,怎么在下一个接口调用上一个接口的数据
常用的两种方式,第二种容易上手1.使用正则提取器 jmeter 如何将上一个请求的结果作为下一个请求的参数——使用正则提取器(http://www.cnblogs.com/0201zcr/p/5089 ...
- Flask-SQLAlchemy相关与Flask-Migrate相关
数据库按照一定规则保存应用数据,应用再发起查询,取回所需的数据.Web应用最常使用基于关系模型的数据库,这种数据库也称为SQL数据库,因为它们使用结构化查询语言SQL.不过近年来文档数据库和键 ...
- AtCoder Grand Contest 035
Preface Atcoder的题都好劲啊,都是我做不动的计数与构造 就当锻炼自己的思维能力了(基本都是bzt教的) A - XOR Circle bzt说这题数据太水了只要判一下所有数异或值是否为\ ...
- [转载]3.2 UiPath鼠标操作文本的介绍和使用
一.鼠标(mouse)操作的介绍 模拟用户使用鼠标操作的一种行为,例如单击,双击,悬浮.根据作用对象的不同我们可以分为对元素的操作.对文本的操作和对图像的操作 二.鼠标对文本的操作在UiPath中的使 ...