从零开始Blazor Server(6)--基于策略的权限验证
写这个的原因
现在BootstrapBlazor
处于大更新时期,Menu
组件要改为泛型模式。
本来我们的这一篇应该是把Layout
改了,但是改Layout
肯定要涉及到菜单,如果现在写了呢,就进入一个发布就过时的状态,就很尴尬,所以后面的就稍微拖一拖。
加上昨天有人说我用OnNavigateAsync
违反单一性原则,要用策略,所以这里我们说下策略怎么做。
添加策略相关的代码
首先我们要有一个实现IAuthorizationRequirement
接口的类,这个类没有什么特别的要求,我们就写一个空类来处理。
public class AdminRequirement : IAuthorizationRequirement
{
}
然后要写一个Handler,来继承这个AuthorizationHandler<AdminRequirement>
,其中泛型是我们上面的实现接口的类。
public class AdminRequirementHandler : AuthorizationHandler<AdminRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AdminRequirement requirement)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
}
实现HandleRequirementAsync
方法,这个方法就是我们的关键方法,授权的实现就在这里面。
其中默认的授权状态是Fail
,如果我们希望允许通过,就执行context.Succeed(requirement);
来告诉策略我们认证成功了。
添加授权认证
在Program.cs
里我们需要把这两个都注册进去,首先注册我们的Handler
builder.Services.AddSingleton<IAuthorizationHandler, AdminRequirementHandler>();
然后注册我们的授权策略
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("Admin", policy => policy.Requirements.Add(new AdminRequirement()));
});
这里的Admin
就是我们的策略名字。
使用策略
在我们需要认证的位置增加特性@attribute [Authorize(Policy = "Admin")]
,然后在我们的授权策略里打断点,应该就会发现断点进入了。
将RouteData传入
因为Blazor里面我们拿不到HttpContext
,所以没法用Request.Path
的方式来拿到url,所以只能使用将RouteData
作为Resource
传入,然后使用attribute
的方式拿到。
这里我们在App.razor
里传入routeData
<AuthorizeRouteView Resource="@routeData" RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
<NotAuthorized>
<RedirectToLogin></RedirectToLogin>
</NotAuthorized>
</AuthorizeRouteView>
然后修改HandleRequirementAsync
。
if (context.User.Identity?.IsAuthenticated != true)
{
return Task.CompletedTask;
}
if (!int.TryParse(context.User.FindFirst(ClaimTypes.Role)?.Value, out var roleId))
{
return Task.CompletedTask;
}
if (context.Resource is RouteData routeData)
{
var routeAttr = routeData.PageType.CustomAttributes.FirstOrDefault(x =>
x.AttributeType == typeof(RouteAttribute));
if (routeAttr == null)
{
context.Succeed(requirement);
}
else
{
var url = routeAttr.ConstructorArguments[0].Value as string;
var permission = PermissionEntity
.Where(x => x.Roles!.Any(y => y.Id == roleId) && x.Url == url).First();
if (permission != null)
{
context.Succeed(requirement);
}
}
}
return Task.CompletedTask;
}
这里跟上一篇的处理思路整体一样,首先我们判断如果用户都没登录,那就直接失败,如果登录了我们就去拿RoleId
,拿不到自然就失败。
不同点在下面,我们没法直接拿到Path
,所以我们只能去找RouteAttribute
,其实就是我们的@page
路由。这里我们也可以自己定义一个Attribute
取自己的。
如果我们没找到这个,证明这应该不是个blazor页面,我们就暂时让它成功。
如果找到了,那么我们就找routeAttr.ConstructorArguments[0].Value as string
,这里面就是对应的路由地址了。
下面就跟之前一样,用路由地址来判断是否是又权限就行了。
源码在github: https://github.com/j4587698/BlazorLearn,分支lesson6
从零开始Blazor Server(6)--基于策略的权限验证的更多相关文章
- Forms身份验证和基于Role的权限验证
Forms身份验证和基于Role的权限验证 从Membership到SimpleMembership再到ASP.NET Identity,ASP.NET每一次更换身份验证的组件,都让我更失望.Memb ...
- 从零开始Blazor Server(5)--权限验证
序 之前我们一直使用的是微软自带的身份验证方式,即使用[Authorize]标签来做. 但是这种方式十分不灵活,微软推荐的方式是加Policy,但是这种方式对我们来说还是不够灵活. 所以本节我们用完全 ...
- 从零开始Blazor Server(1)--项目搭建
项目介绍 本次项目准备搭建一个使用Furion框架,Blazor的UI使用BootstrapBlazor.数据库ORM使用Freesql的后台管理系统. 目前的规划是实现简单的注册,登录.增加管理员跟 ...
- 从零开始Blazor Server(15)--总结
我们用了14篇文章,基本上把一个后台管理系统需要的UI部分都说的差不多了.所以这套文章也该到了结束的时候了. 这里面有很多问题,比如我们直接使用UI来拉数据库信息而没有使用service,再比如我们大 ...
- 从零开始Blazor Server(3)--添加cookie授权
认证方式简述 Blazor Server微软官方还是推荐直接使用Cookie授权,因为本来Blazor Server就是前后端不分离的.不存在Cookie跨域等一系列问题. 只要不是使用SSO之类的统 ...
- 从零开始Blazor Server(8)--增加菜单以及调整位置
这篇干啥 这篇文章主要是把前面的一些东西稍微调整一下,使其更适合后面的内容. 主要是两个事,一个是把原来的PermissionEntity直接变成MenuEntity,直接让最后一级是菜单,这样后面就 ...
- 从零开始Blazor Server(9)--修改Layout
目前我们的MainLayout还是默认的,这里我们需要修改为BootstrapBlazor的Layout,并且处理一下菜单. 修改MainLayout BootstrapBlazor已经自带了一个La ...
- 从零开始学 Java - Spring AOP 实现用户权限验证
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
- 从壹开始前后端分离 [ vue + .netcore 补程 ] 三十一║ Nuxt终篇:基于Vuex的权限验证探究
缘起 哈喽大家好,今天周四啦,楼主明天要正式放假了,这里先祝大家节日快乐咯,希望在家里能继续研究点儿东西吧,今天呢是 nuxt 的最后一篇,主要是对权限登录进行研究,这一块咱们之前在说第一个项目的时候 ...
随机推荐
- CentOS6.x静默安装Oracle12c
一.准备 1.1 安装环境 系统要求 内存 > 2G 安装目录空间 > 6.5G /tmp目录空间 > 1G 操作系统 cat /etc/redhat-release 用rpm命令确 ...
- 一条更新SQL的内部执行及日志模块
一条更新SQL的内部执行 学习MySQL实战45讲,非常推荐学 还是老图: 上文复习 在执行查询语句的时候,会执行连接器(总要连上才能搞事情),然后去查询缓存(MySQL8+删除了),有数据返回,没数 ...
- 分享一个 SpringCloud Feign 中所埋藏的坑
背景 前段时间同事碰到一个问题,需要在 SpringCloud 的 Feign 调用中使用自定义的 URL:通常情况下是没有这个需求的:毕竟都用了 SpringCloud 的了,那服务之间的调用都是走 ...
- Fast-Rcnn学习笔记
Fast-Rcnn学习笔记 paper code Fast-RCNN总览 step1:图片先放进卷积层 step2:再卷积层的特征图谱上回映射出对应的感兴趣区域 step3:集过一层ROI Pooli ...
- 第06组 Beta冲刺 (1/6)
目录 1.1 基本情况 1.2 冲刺概况汇报 1.郝雷明 2. 方梓涵 3.曾丽莉 4.黄少丹 5. 董翔云 6.杜筱 7.鲍凌函 8.詹鑫冰 9.曹兰英 10.吴沅静 1.3 冲刺成果展示 1.1 ...
- 多态——JavaSE基础
多态 同一个方法可以根据对象的不同采取不同的动作 一个对象的实际类型是确定的,但可以指向对象的引用类型有很多 基本条件: 有继承关系 子类重写父类方法 父类引用指向子类对象Father f1 = ne ...
- Xmind演讲主题大纲
参考:https://www.bilibili.com/video/BV1Rb411s7VG?p=9
- LoRa无线传输技术与LoRaWAN无线模块的区别
有不少人分不清LoRaWAN无线模块与LoRa网关无线传输技术到底有什么区别,他们在物联网领域的应用到底是什么样的. LoRaWAN指的是MAC层的组网协议,而LoRa是一个物理层的协议.虽然现有的L ...
- Kafka 的稳定性
一.事务 1. 事务简介 1.1 事务场景 producer发的多条消息组成⼀个事务这些消息需要对consumer同时可⻅或者同时不可⻅ producer可能会给多个topic,多个partition ...
- 皓远的第二次博客作业(最新pta集,链表练习及期中考试总结)
前言: 知识点运用:正则表达式,有关图形设计计算的表达式和算法,链表的相关知识,Java类的基础运用,继承.容器与多态. 题量:相较于上次作业,这几周在java方面的练习花了更多的精力和时间,所要完成 ...