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 ...
随机推荐
- [ElasticSearch]Java API 之 滚动搜索(Scroll API)
一般搜索请求都是返回一"页"数据,无论数据量多大都一起返回给用户,Scroll API可以允许我们检索大量数据(甚至全部数据).Scroll API允许我们做一个初始阶段搜索并且持 ...
- Dmidecode命令
Dmidecode简介 DMI (Desktop Management Interface, DMI)就是帮助收集电脑系统信息的管理系统,DMI信息的收集必须在严格遵照SMBIOS规范的前提下进行. ...
- MySQL数据库 存储引擎,创建表完整的语法,字段类型,约束条件
1.存储引擎 - 存储引擎是用于根据不同的机制处理不同的数据. - 查看mysql中所有引擎: - show engines; - myisam: 5.5以前老的版本使用的存储引擎 - blackho ...
- FastDfs的搭建
一.什么是FastDFS FastDFS是用c语言编写的一款开源的分布式文件系统.FastDFS为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标,使用Fast ...
- WARN Connection to node 2 could not be established. Broker may not be available. (
启动 kafka 集群, 出现这个问题 WARN Connection to node 2 could not be established. Broker may not be available. ...
- Linux性能优化实战学习笔记:第二十七讲
一.案例环境描述 1.环境准备 2CPU,4GB内存 预先安装docker sysstat工具 2.温馨提示 案例中 Python 应用的核心逻辑比较简单,你可能一眼就能看出问题,但实际生产环境中的源 ...
- [LeetCode] 789. Escape The Ghosts 逃离鬼魂
You are playing a simplified Pacman game. You start at the point (0, 0), and your destination is (ta ...
- 第02组 Alpha冲刺(5/6)
队名:無駄無駄 组长博客 作业博客 组员情况 张越洋 过去两天完成了哪些任务 摸鱼 准备"Alpha事后诸葛亮" 提交记录(全组共用) 接下来的计划 沟通前后端成员,监督.提醒他们 ...
- luogu P5606 小 K 与毕业旅行 - 构造 - 多项式
题目传送门 传送门 先考虑 $a_i > 0$ 的情况.考虑构造这样一个顺序:$a_i$ 要么和后面的数的乘积都大于 $w$ 要么都小于等于 $w$. 这个构造可以这样做: vector< ...
- oracle--oracle18C DG搭建(二)
配置清单 任务 数据库 创建主数据库数据文件的备份副本 主 为备用数据库创建控制文件 主 为备用数据库创建参数文件 主 将文件从主系统复制到备用系统 主 设置环境以支持备用数据库 备库 启动物理备用数 ...