------------恢复内容开始------------

使用jwt进行认证授权的主要流程

参考博客(https://www.cnblogs.com/RayWang/p/9536524.html)(https://www.cnblogs.com/laozhang-is-phi/p/9511869.html

1)客户端向授权服务系统发起请求,申请获取“令牌”。

2)授权服务根据用户身份,生成一张专属“令牌”,并将该“令牌”以JWT规范返回给客户端

3)客户端将获取到的“令牌”放到http请求的headers中后,向主服务系统发起请求。主服务系统收到请求后会从headers中获取“令牌”,并从“令牌”中解析出该用户的身份权限,然后做出相应的处理(同意或拒绝返回资源)

前两点还好做,一直不太清楚第三点是怎么写的

1)通过自定义中间件

其实实现思路就是将用户身份权限写到jwt令牌中,客户端将返回的令牌存储好(一般是存在Cookie中),以后每次调用接口都要将该令牌携带上。服务端收到请求后,(以下都写在一个中间件里,用app.use....)提取令牌,先进行认证,如果不合法(比如被篡改),将驳回请求。如果认证通过,则从令牌中提取身份,进行授权操作,将该身份赋予http请求,放行请求。

(jwt令牌的密钥是防止内容被篡改,而不是保护jwt字符串中的信息)

{
/// <summary>
/// 授权中间件
/// </summary>
public class JwtAuthorizationFilter
{
private readonly RequestDelegate _next; /// <summary>
///
/// </summary>
/// <param name="next"></param>
public JwtAuthorizationFilter(RequestDelegate next)
{
_next = next;
} /// <summary>
///
/// </summary>
/// <param name="httpContext"></param>
/// <returns></returns>
public Task Invoke(HttpContext httpContext)
{
//检测是否包含'Authorization'请求头,如果不包含则直接放行
if (!httpContext.Request.Headers.ContainsKey("Authorization"))
{
return _next(httpContext);
}
var tokenHeader = httpContext.Request.Headers["Authorization"];
tokenHeader = tokenHeader.ToString().Substring("Bearer ".Length).Trim(); TokenModel tm = JwtHelper.SerializeJWT(tokenHeader); //BaseBLL.TokenModel = tm;//将tokenModel存入baseBll //授权
var claimList = new List<Claim>();
var claim = new Claim(ClaimTypes.Role, tm.Role);
claimList.Add(claim);
var identity = new ClaimsIdentity(claimList);
var principal = new ClaimsPrincipal(identity);
httpContext.User = principal; return _next(httpContext);
}
}
}

 (2)JWT的Bearer认证

Microsofr.AspNetCore.Authentication源码里有一个JwtBearerHandler类,用来专门处理JWT认证,它将提取Request的Authorization头信息,验证值是否以Bearer开头,然后获得具体的token,对token进行解密,最后验证是否合法,如果合法,将提取的用户信息塞到HttpContext.User中,我们可以注入HttpContextAccessor,这样在任何地方就可以通过依赖获得HttpContext.User,得到用户的一切信息,其实这就是替代了我们自己写的中间件

那么,ASP.NET core是什么时候将认证交由JwtBearerHandler处理的呢?Authentication是在Middleware层进行处理,这里就有一个内置的AuthenticationMiddleware。当收到请求后,它找出你所配置的所有认证方式,如果你的[Authorize]属性指定了具体的方式,如[Authorize(AuthenticationSchema='Bearer')],它会找到指定的AuthenticationHandler,交由它处理,如果你没有指定,它将交由默认的AuthenticationHandler处理,以上的例子,我们已经配置了默认的认证方式,services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme),其中JwtBearerDefaults.AuthenticationScheme就是我们配置的默认认证方式,它的值就是Bearer

services.AddAuthentication(x =>
{
//看这个单词熟悉么?没错,就是上边错误里的那个。
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})// 也可以直接写字符串,AddAuthentication("Bearer")
.AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,//参数配置在下边
ValidateIssuer = true,
ValidIssuer = audienceConfig["Issuer"],//发行人
ValidateAudience = true,
ValidAudience = audienceConfig["Audience"],//订阅人
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,//这个是缓冲过期时间,也就是说,即使我们配置了过期时间,这里也要考虑进去,过期时间+缓冲,默认好像是7分钟,你可以直接设置为0
RequireExpirationTime = true,
}; });

扩展

JwtBearer认证中,默认是通过Http的Authorization头来获取的,这也是最推荐的做法,但是在某些场景下,我们可能会使用Url或者是Cookie来传递Token,那要怎么来实现呢?

其实实现起来非常简单,如前几章介绍的一样,JwtBearer也在认证的各个阶段为我们提供了事件,来执行我们的自定义逻辑:

.AddJwtBearer(o =>
{
o.Events = new JwtBearerEvents()
{
OnMessageReceived = context =>
{
context.Token = context.Request.Query["access_token"];
return Task.CompletedTask;
}
};
o.TokenValidationParameters = new TokenValidationParameters
{
...
};

然后在Url中添加access_token=[token],然后就可以直接在浏览器中访问,cookie同理。

商城完成过程中我一开始一直在看Microsoft.AspNetCore.Identit的相关配置,一直想从这里找到自定义修改实现上述功能的方法

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-3.1&tabs=visual-studio)但是确实我最后也没有完成,我想实现角色授权资源管理,从这里是跑歪了感觉,浪费了很多时间,一定要把 Authentication 和 Identity 当作是两个东西,一旦混淆,你就容易陷入进去。

Jwt实现权限与接口的动态分配

参考博客(https://www.cnblogs.com/laozhang-is-phi/p/10139204.html

官方文档(https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-2.2#authorization-handlers

1.首先看一下我们的实体模型设计

 

2,然后明确一下几个类是干什么的

IAuthorizationRequirement是一种没有方法的标记服务,来定义策略的要求

IAuthorizationHandler负责检查是否满足要求,是否允许授权(Task HandleAsync(AuthorizationHandlerContext context);)

AuthorizationHandlerContext类是标记处理程序使用的要求是否已满足(多在HandleAsync中调用)

值得注意的是这个类中的User属性 ClaimsPrincipal (名词解析https://www.cnblogs.com/savorboard/p/aspnetcore-identity.html

AuthenticationScheme(验证方案名称)

然后我们会新建以下几个类

PermissionItem

PermissionRequirement 令牌必要参数类

PermissionHandler 自定义授权处理器

一句话说明这个过程就是Authorizationhandler根据Authorizationrequriement参数的信息为根据进行判断然后标注AuthorizationHandlerContext

以上就是一般流程讲解,想要集成到项目里,还有考虑易班授权机制,毕竟我们做的是易班的站内应用

HttpContext.User.Claims与jwt里的claims什么联系?是相同的身份证

集成到易班站内应用项目中

简单一张图介绍一下易班的授权

易班的授权和一般的outh2还不太一样,但是理解之后会发现好像更简便,因为在一个站内应用已经经过了一次登录授权所以每一次访问都是给一个code,后端解密看看有没有授权,没有就重定向授权界面,有就获得token,用来访问易班api

登录接口 :接收前端传来的code,判断有没有授权,没有返回false,有得到uid,查一下数据库有没有这个注册过,没有注册过就解析code获得token访问易班api获取用户资料保存到数据库,并根据资料返回一个jwt,如果数据库已经有用户资料,就根据资料重新颁发一个jwt,因为数据库角色可能会变化。

1,一个需要注意的点是解密code有两种可能的json,不能直接序列化为授权成功时的对象,先用jobject做一下判断

2,颁发令牌与动态授权主要看的老张的博客,不过做了不少改动,主要是IAuthorizationRequirement类,看官方文档的例子这个类就是来定义策略的要求的,而老张的博客里里面定义了很多属性,在颁发jwt的时候也作为参数传进去,我们这里的要求不是很高就是看claim中的角色信息符不符合要求就行感觉,所以PermissionRequirement存一下角色相关的就可以,毕竟一个项目的 IAuthorizationRequirement的子类也不唯一,要验证其他的还可以多写个Handler做扩展

看一下关键的两个地方

public class ClaimsRequirementHandler : AuthorizationHandler<ClaimRequirement>
{ protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
ClaimRequirement requirement)
{ var claim = context.User.Claims.FirstOrDefault(c => c.Type == requirement.ClaimName);
if (claim != null && requirement.ClaimValue.Contains(claim.Value))
{
context.Succeed(requirement);
}
else
{
context.Fail();
} return Task.CompletedTask;
}
}

  

services.AddAuthorization(options =>
{
options.AddPolicy("CanReviewCommodity", policy => policy.Requirements.Add(new ClaimRequirement(ClaimTypes.Role, "Admin SuperAdmin")));
options.AddPolicy("CanAppointAdmin", policy => policy.Requirements.Add(new ClaimRequirement(ClaimTypes.Role, "SuperAdmin")));
options.AddPolicy("CanBasicoperation", policy => policy.Requirements.Add(new ClaimRequirement(ClaimTypes.Role, "OrdUser Admin SuperAdmin")));
});

  

这里是我自定义的鉴权Handler,可以看出来比较简略,就是验证一下角色信息匹不匹配,没有上升到验证接口资源的层面

因此改进的话可以验证的更细一些,改进方案大概就是ClaimRequirement中要增加一个存放(角色对应接口)的属性,一开始为空,可以进入ClaimsRequirementHandler后再去数据库查询角色对应的接口资源,有了这些资源就可以在handler比对一下该请求要访问的url地址在不在角色所拥有的接口资源里,在就成功,不在就是权限不够。以上仅供参考,详细见https://www.cnblogs.com/laozhang-is-phi/p/jwt-api-permission.html

登出接口 :暂时不需要

二手商城集成jwt认证授权的更多相关文章

  1. 【ASP.NET Core学习】使用JWT认证授权

    概述 认证授权是很多系统的基本功能 , 在以前PC的时代 , 通常是基于cookies-session这样的方式实现认证授权 , 在那个时候通常系统的用户量都不会很大, 所以这种方式也一直很好运行, ...

  2. 任务35:JWT 认证授权介绍

    任务35:JWT 认证授权介绍 应用场景主要是移动端或者PC端前后分离的场景 直接对客户端API的请求 例如访问admin/Index 没有权限返回403. 需要客户端手动的再发动请求,这是一个拿to ...

  3. Dotnet core使用JWT认证授权最佳实践(二)

    最近,团队的小伙伴们在做项目时,需要用到JWT认证.遂根据自己的经验,整理成了这篇文章,用来帮助理清JWT认证的原理和代码编写操作. 第一部分:Dotnet core使用JWT认证授权最佳实践(一) ...

  4. Spring Cloud实战 | 最终篇:Spring Cloud Gateway+Spring Security OAuth2集成统一认证授权平台下实现注销使JWT失效方案

    一. 前言 在上一篇文章介绍 youlai-mall 项目中,通过整合Spring Cloud Gateway.Spring Security OAuth2.JWT等技术实现了微服务下统一认证授权平台 ...

  5. 如何简单的在 ASP.NET Core 中集成 JWT 认证?

    前情提要:ASP.NET Core 使用 JWT 搭建分布式无状态身份验证系统 文章超长预警(1万字以上),不想看全部实现过程的同学可以直接跳转到末尾查看成果或者一键安装相关的 nuget 包 自上一 ...

  6. Dotnet core使用JWT认证授权最佳实践(一)

    最近,团队的小伙伴们在做项目时,需要用到JWT认证.遂根据自己的经验,整理成了这篇文章,用来帮助理清JWT认证的原理和代码编写操作. 一.JWT JSON Web Token (JWT)是一个开放标准 ...

  7. .net core 学习小结之 JWT 认证授权

    新增配置文件 { "Logging": { "IncludeScopes": false, "Debug": { "LogLeve ...

  8. ASP.NET Core JWT认证授权介绍

    using JWTWebApi.Models; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetC ...

  9. asp.net core-14.JWT认证授权 生成 JWT Token

    源码下载 语言组织能力不好 ,看这个 视频 用visual studio code打开文件,运行dotnet watch run 之后在postman里面去访问 拿到Token后

随机推荐

  1. 常用的函数式接口Function接口和常用的函数式接口Function接口默认方法andThen

    常用的函数式接口Function接口 package com.yang.Test.FunctionStudy; import java.util.function.Function; /** * ja ...

  2. Modbus转BACnet IP网关

    BACnet是楼宇自动化和控制网络数据通信协议的缩写.它是为楼宇自动化网络开发的数据通信协议   根据1999年底互联网上楼宇自动化网络的信息,全球已有数百家国际知名制造商支持BACnet,包括楼宇自 ...

  3. 可以级联的以太网远程IO模块的优点与适用场景

    可以级联的以太网远程IO模块的优点与具体的适用场景 对于数据采集控制点是按照线性分布的场景,比如智慧园区的路灯.桥梁.路灯.数字化工厂.停车场车位监测.智慧停车场.智能停车架.楼宇自动控制系统等场景, ...

  4. 在半小时内从无到有开发并调试一款Chrome扩展(Chrome插件/谷歌浏览器插件)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_120 就在不久之前,我们目前这个毕业班的班长那日同学和我说,他正在公司开发Chrome扩展,看起来很高大上的技术,实际开发却非常简 ...

  5. ASP.NET Core 6框架揭秘实例演示[31]:路由&ldquo;高阶&rdquo;用法

    ASP.NET的路由是通过EndpointRoutingMiddleware和EndpointMiddleware这两个中间件协作完成的,它们在ASP.NET平台上具有举足轻重的地位,MVC和gRPC ...

  6. Java学习(三)Java起源&发展

    目录 Java的诞生 C&C++ Java初生 Java发展(三高: 高可用,高性能,高并发) Java特性和劣势 Java程序运行机制 Java的诞生 C&C++ ​ **1972年 ...

  7. 开发H5程序或者小程序的时候,后端Web API项目在IISExpress调试中使用IP地址,便于开发调试

    在我们开发开发H5程序或者小程序的时候,有时候需要基于内置浏览器或者微信开发者工具进行测试,这个时候可以采用默认的localhost进行访问后端接口,一般来说没什么问题,如果我们需要通过USB基座方式 ...

  8. oracle 怎么查看用户对应的表空间

    oracle 怎么查看用户对应的表空间? 查询用户: 查看数据库里面所有用户,前提是你是有 dba 权限的帐号,如 sys,system: select * from dba_users; 查看你能管 ...

  9. Spring(二)-生命周期 + 自动装配(xml) +自动装配(注解)

    1.生命周期 **Spring容器的 bean **的生命周期: 1.1 默认生命周期 1.1.1 生命周期 调用构造方法,创建实例对象: set方法,给实例对象赋值: init 初始化方法 初始化对 ...

  10. Jetpack架构组件学习(4)——APP Startup库的使用

    最近在研究APP的启动优化,也是发现了Jetpack中的App Startup库,可以进行SDK的初始化操作,于是便是学习了,特此记录 原文:Jetpack架构组件学习(4)--App Startup ...