JWT权限控制

JWT(Json Web Token)

什么是JWT,它是一种对API的保护方案,为什么要进行保护呢

  1. 防泄漏:你肯定不希望你的数据能被别人随意调用,比如公司的机密信息,不可能每个人都可以访问到
  2. 防攻击:防止被人伪装恶意调用接口,利用网关就把请求拦截在外面,防止对服务器造成资源压力
  3. 防止被人篡改,导致请求不到信息,防重放攻击(案例:在公共网络环境中,请求被截获,稍后被重放或多次重放)

设计原则

  1. 轻量级
  2. 易于开发、测试和部署
  3. 适合于异构系统(跨操作系统、多语言简易实现)
  4. 所有写操作接口(增、删、改 操作)
  5. 非公开的读接口(如:涉密/敏感/隐私 等)

JWT核心知识

claim:claim就是声明,就像身份证上的地址,个人信息

Httpcontext是如何通过claim鉴权的:我们去办业务的时候,需要出示自己的身份证,这个身份证就相当于自己的令牌进行访问

JWT由三部分组成

第一部分是头部,头部分为两部分(Header)

  1. 算法、声明
  2. 类型type:JWT类型

第二部分是载荷相当于HTML中的body(Payload)

第三部分就是签名也是就是密钥(Signature)

基于.NetCore WebApi创建一个简单的token令牌

public ActionResult<IEnumerable<string>>Get()
{
//创建声明Token数组
var claim =newClaim[]
{
newClaim(ClaimTypes.Name,"ylc"),
newClaim(JwtRegisteredClaimNames.Email,"[email protected]"),
newClaim(JwtRegisteredClaimNames.Sub,"Sub")
};
//实例化一个token对象
var token =newJwtSecurityToken(claims:claim);
//生成token
var jwtToken =newJwtSecurityTokenHandler().WriteToken(token);
returnnewstring[]{ jwtToken };
}

启动项目之后我们会得到一个token令牌

粘贴到jwt官网中可以解密,下面介绍了另一种解密方法

token令牌分为两部分,红色部分解析出来代表头部,粉色代表载荷,我们探入的信息

虽然得到令牌,但是头部的加密算法显示none,也没有数字签名,所以下面显示无效签名

到底这个加密算法怎么配置呢,接下来进行扩展

通过查看实例化token的函数发现它有五个重写的构造函数



publicJwtSecurityToken(string issuer =null, string audience =null, IEnumerable<Claim> claims =null, DateTime? notBefore =default(DateTime?), DateTime? expires =default(DateTime?), SigningCredentials signingCredentials =null)
{
if(expires.HasValue && notBefore.HasValue && notBefore >= expires)
{
throw LogHelper.LogExceptionMessage(newArgumentException(LogHelper.FormatInvariant("IDX12401: Expires: ‘{0}‘ must be after NotBefore: ‘{1}‘.", expires.Value, notBefore.Value)));
}
            Payload =newJwtPayload(issuer, audience, claims, notBefore, expires);
            Header =newJwtHeader(signingCredentials);
            RawSignature = string.Empty;
}

我们就声明五个参数

[HttpGet]
public ActionResult<IEnumerable<string>>Get()
{
//创建声明Token数组
var claim =newClaim[]
{
newClaim(ClaimTypes.Name,"ylc"),
newClaim(JwtRegisteredClaimNames.Email,"[email protected]"),
newClaim(JwtRegisteredClaimNames.Sub,"Sub")

};
var key =newSymmetricSecurityKey(Encoding.UTF8.GetBytes("[email protected]"));//密钥大小要超过128bt,最少要16位

//实例化一个token对象
var token =newJwtSecurityToken(
                issuer:"http://localhost:5000",//发起人:当前项目
                audience:"http://localhost:5000",//订阅:我们需要谁去使用这个Token
                claims: claim,//声明的数组
                expires:DateTime.Now.AddDays(1),//当前时间加一小时,一小时后过期
                signingCredentials:newSigningCredentials(key,SecurityAlgorithms.HmacSha256)//数字签名 第一部分是密钥,第二部分是加密方式
);
var jwtToken =newJwtSecurityTokenHandler().WriteToken(token);
returnnewstring[]{ jwtToken };
}

可能会出现一下报错:IDX10603: Decryption failed. Keys tried: ‘[PII is hidden]‘. Exceptions caught: ‘[PII is hidden]‘. token: ‘[PII is hidden]‘ Parameter name: KeySize

安装最新版Microsoft.IdentityModel.Logging nuget包

最后成功运行,加密算法已经显示出HS256

但是最下方还是显示数字签名无效,还要怎么做呢

我们对令牌解密不一定要看官网通过浏览器控制台打印出来也可以

将令牌的一部分放入atob中就可以进行解密

相信做完这些对JWT的三大部分有了一定的了解

声明Claim的两种方式

开始在声明Claim的时候用到了ClaimTypes和JwtRegisteredClaimNames这两种

var claim =newClaim[]
{
newClaim(ClaimTypes.Name,"ylc"),
newClaim(JwtRegisteredClaimNames.Email,"[email protected]"),
newClaim(JwtRegisteredClaimNames.Sub,"Sub")
};

F12查看ClaimTypes源码里面写的都是.net Core中提供的常用的静态变量

查看JwtRegisteredClaimNames源码都是JWT自己提供的

但是可能有人想获取令牌中的Email的值,获取不到

接下来就说到获取令牌的三种方式,在这之前要使用http进行上下文注入

[HttpGet("{str}")]
public ActionResult<IEnumerable<string>>Get(string str)
{
///获取Token的三种方式

//第一种直接用JwtSecurityTokenHandler提供的read方法
var jwtHander =newJwtSecurityTokenHandler();
            JwtSecurityToken jwtSecurityToken = jwtHander.ReadJwtToken(str);

//第二种 通过User对象获取
var sub = User.FindFirst(d => d.Type =="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name")?.Value;

//第三种 通过Httpcontext上下文中直接获取
var name = _accessor.HttpContext.User.Identity.Name;
var Claims = _accessor.HttpContext.User.Claims;
var claimstype =(from item in Claims where item.Type == JwtRegisteredClaimNames.Email select item.Value).ToList();

returnnewstring[]{ JsonConvert.SerializeObject(jwtSecurityToken), sub, name, JsonConvert.SerializeObject(claimstype)};
}

然后在postman进行测试,路径后面传入Token令牌,传入的Token的string参数实际是为了方法一,第二三种是没有调用str的,所以它们为空跟Token没有任何关系

除了第一种JwtSecurityTokenHandler获取的值不为空,其他都为空这是为什么呢

刚刚只是生成了令牌并没有出现内存中,也就是在http上下文中,下面就是要说到HttpContext是如何鉴权的

首先我们必须在服务里注册一个Bealer认证,也就是说我们必须注册一个认证才可以获取内容

如何进行 Jwt Bealer认证呢,需要在配置服务的做相应的配置

之前在声明Token的时候指明了发起人订阅人,这里也要对应上,就相当于解密的过程

publicvoidConfigureServices(IServiceCollection services)
{
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddSingleton<IHttpContextAccessor,HttpContextAccessor>();

var keyBase64 ="[email protected]";
var keyByeArray = Encoding.ASCII.GetBytes(keyBase64);
var signkey =newSymmetricSecurityKey(keyByeArray);

var tokenValidationParameters =newTokenValidationParameters//生成了一个Token验证的参数
{
                ValidateIssuerSigningKey =true,
                IssuerSigningKey = signkey,//数字签名
                ValidateIssuer =true,
                ValidIssuer ="http://localhost:5000",//发行人
                ValidateAudience =true,
                ValidAudience ="http://localhost:5000",//订阅人
                ValidateLifetime =true,
                ClockSkew = TimeSpan.FromSeconds(30),
                RequireExpirationTime =true,
};

            services.AddAuthentication("Bearer")//注入服务  1.开启Bearer认证 2.注册Bearer服务
.AddJwtBearer(o =>
{
                 o.TokenValidationParameters = tokenValidationParameters;
});
}

完成Bearer以后,我们再进行postman测试,第二种第三种还是为空,这是什么原因呢

我们通过三步创建令牌之后,通过注入完成我们的认证,还需要开启中间件管道,如果不开启的话,Token令牌还是不能传送到HttpContext上下文,中间件实际就是操作Http上下文。

 app.UseAuthentication();//开启中间件

还差最后一步就是登录,只有登录认证了Bearer才能将Token转化成相应的服务

服务对象在经过中间件的时候添加到HttpContext中,然后赋值给User

通过登录生成Token令牌,返回给客户端,客户端拿着Token,放在header里面,传输给服务器进行校验,校验成功返回数据

返回了三个参数,最后一个还是空

通过项目调试,发现我们之前的Email参数被改名了,原本是JwtRegisteredClaimNames变成了ClaimTypes的声明方法,这就需要解除,.NetCore自己的映射匹配,使用JWT,在ConfigureServices加上

 JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();//把 JwtSecurityToken清除

显示成功

我们在当前GET方法中进行测试加上 [Authorize],把Authorization取消勾选,运行

得到401无状态,我们再把钩点上,成功授权

原文地址:https://www.cnblogs.com/cg-ww/p/12654364.html

时间: 2024-07-31 20:23:38

JWT权限控制的相关文章

从壹开始前后端分离[.netCore 不定期 ] 36 ║解决JWT权限验证过期问题

缘起 哈喽,老张的不定期更新的日常又开始了,在咱们的前后端分离的.net core 框架中,虽然已经实现了权限验证<框架之五 || Swagger的使用 3.3 JWT权限验证[修改]>,只不过还是有一些遗留问题,最近有不少的小伙伴发现了这样的一些问题,本来想着直接就在原文修改,但是发现可能怕有的小伙伴看不到,就单发一条推送吧,所以我还是单写出一篇文章来说明解决这些问题,希望对无论是正在开发权限管理系统,还是平时需要数据库动态绑定权限分配的你有一些启发和思考.今天咱们注意解决这三个问题: 1.

gin-jwt对API进行权限控制

前言 之前文章简单介绍了如何运行gin+vue的前后端分离开源项目,该项目是学习了Gin实践教程后结合vue-element-admin写的,该教程讲得很详细,适合入门Gin.本篇文章将介绍gin+vue的前后端分离开源项目中如何使用gin-jwt对API进行权限验证. 安装gin-jwt 在GOPATH目录下运行 go get github.com/appleboy/gin-jwt 初始化jwt中间件 gin-jwt已经帮我们封装成中间件了,我们只需要设置并实例化它就可以直接用了. 现在来看看

权限控制框架

基本概念 权限系统设计模型分析(DAC,MAC,RBAC,ABAC) 权限控制和OAuth How is OAuth 2 different from OAuth 1? Oauth 1.0,1.0a 和 2.0 的之间的区别有哪些? 几类框架 shiro 极客学院-跟我学 Shiro 或 W3Cschool-跟我学 Shiro,两者内容一样,挑一个看着顺眼的学习即可30分钟学会如何使用Shiro spring security 使用 Spring Security 保护 Web 应用的安全适合初

rbac 权限控制

RBAC 的控制,大致是通过将角色的权限控制,来控制用户的权限. 需要构建的表为 用户表(user) ,角色表(role),节点表(node),三张主表 , 节点表内记录的是所有的权限和方法. 2张关联表,是为了关联3张数据表的,分别未 角色用户表(user_role),角色权限表(role_node),也可将两张表写成字段分别加入到用户表和权限表内; 废话不多说看下,键表语句如下 用户表: CREATE TABLE `wj_admin` ( `id` int(11) NOT NULL AUTO

译-BMC Remedy Action Request System权限控制概述

原文链接:Access control overview 说明: BMC Remedy Action Request System是BMC ITSM产品平台,简称AR 或者Remedy,可实现基于ITIL标准的整个IT管理流程的实施定制.该平台可实现多种权限级别的管理,包括人员.组.角色,以及表.字段.行级别等.本文可以用作其他对权限要求比较精细的系统参考. 为了便于理解,部分名词翻译如下: Server:服务器Form (or table):表单Field (or column):字段Acti

基于MVC4+EasyUI的Web开发框架形成之旅--权限控制

我在上一篇随笔<基于MVC4+EasyUI的Web开发框架形成之旅--框架总体界面介绍>中大概介绍了基于MVC的Web开发框架的权限控制总体思路.其中的权限控制就是分为"用户登录身份验证"."控制器方法权限控制"."界面元素权限控制"三种控制方式,可以为Web开发框架本身提供了很好用户访问控制和权限控制,使得用户界面呈现菜单.Web界面的按钮和内容.Action的提交控制,均能在总体权限功能分配和控制之下. 本篇文章主要细化这三个方面

Orchard 之:Widget,兼看 Layer 在权限控制中的作用

一:Widget 可以理解为控件,可以直接被页面所引用.行为类似与分部页面,比如,我们可以创建一个 商品列表 Widget,然后这个 Widget 就可以被很多页面所引用. 理解 Widget 这个概念,我们不得不理解另外两个概念: 1:Layer Orchard 默认有这么几个层,Default.Authenticated.Anonymous.Disabled.TheHomepage.Layer 用于承载什么时候 Widget 将会被展现,这么讲大家一定觉得很抽象,其实 Layer 存在的意义

SpringMVC + Mybatis + SpringSecurity(权限控制到方法按钮) + Rest(服务) + Webservice(服务) + Quartz(定时调度)+ Lucene(搜索引擎) + HTML5 bootstrap + Maven项目构建绝对开源平台

框架整合: Springmvc + Mybatis + Shiro(权限) + REST(服务) + WebService(服务) + JMS(消息) + Lucene(搜搜引擎) + Quartz(定时调度) + Bootstrap Html5(支持PC.IOS.Android) 需要源码请加Q:3121026417   此处[源码获取地址] 框架简介: 项目Maven构建,真实大型互联网架构,做到高并发,大数据处理,整个项目使用定制化服务思想,提供模块化.服务化.原子化的方案,将功能模块进行

CloudStack API访问权限控制

在我写开始之前,请先看下CS中国社区的一篇文章http://www.cloudstack-china.org/2012/12/1465.html,在第1点里讲了关于权限级别,command属性文件位置等问题.不过4.3现在的除了command.properties外,作者提到的其它properties文件现在好像都没有了,而且command里面现在形如***command=15,"="后面不再有处理请求命令的类. API请求由ApiServlet拦截后,会调用verifyRequest