从零开始Blazor Server(5)--权限验证
序
之前我们一直使用的是微软自带的身份验证方式,即使用[Authorize]
标签来做。
但是这种方式十分不灵活,微软推荐的方式是加Policy
,但是这种方式对我们来说还是不够灵活。
所以本节我们用完全自己校验的方式完成权限验证。
OnNavigateAsync介绍
在 App.razor 里面的Router
节点,微软给了一个OnNavigateAsync
方法,这个方法在每次路由跳转的时候都会执行,所以我们可以把我们的权限验证搬到这里来。
App.razor
首先,我们在Router
节点上增加OnNavigateAsync
:
<Router AppAssembly="@typeof(App).Assembly" OnNavigateAsync="PermissionCheck">
这里我们的方法叫做PermissionCheck
。
然后我们来看这个PermissionCheck
方法。
private void PermissionCheck(NavigationContext context)
{
var whiteList = Furion.App.Configuration["WhiteList"];
if (whiteList != null && whiteList.Split(',').Contains(context.Path))
{
return;
}
var user = Furion.App.User;
if (user == null)
{
NavigationManager.NavigateTo("/Login");
return;
}
if (user.Identity?.IsAuthenticated != true)
{
NavigationManager.NavigateTo("/Login");
return;
}
if (!int.TryParse(user.FindFirst(ClaimTypes.Role)?.Value, out var roleId))
{
NavigationManager.NavigateTo("/Login");
return;
}
var permission = PermissionEntity
.Where(x => x.Roles!.Any(y => y.Id == roleId) && x.Url == context.Path).First();
if (permission == null)
{
NavigationManager.NavigateTo("/Login");
}
}
这里我们需要把Login
这个页面拿出来,因为我们的Login
页面应该是一个白名单页面,无需登录也可以访问,所以我在appsettings.json
中增加了一项,为WhiteList
,这里面以,
分隔,所有在这里面的路径都是白名单路径,可以不用登录直接访问。
"WhiteList": "Login"
这里注意,
OnNavigateAsync
给的Path
是相对路径,不带最前面的/
,所以我们的Login
也不能有/
。
这里判断如果是白名单,则直接return
,正常跳转。
var user = Furion.App.User;
if (user == null)
{
NavigationManager.NavigateTo("/Login");
return;
}
if (user.Identity?.IsAuthenticated != true)
{
NavigationManager.NavigateTo("/Login");
return;
}
然后获取我们的登录信息,如果没有登录,那么直接跳转到Login
页面。
if (!int.TryParse(user.FindFirst(ClaimTypes.Role)?.Value, out var roleId))
{
NavigationManager.NavigateTo("/Login");
return;
}
这里获取我们当时在LoginController
里的RoleId
。
这里注意,我稍微改了一下,之前的文章里我们这里面放的是
RoleName
,本来是打算根据用户再获取权限,但是后来想想有点麻烦,就稍微改动了一下,具体的可以看下新的源码。实战中建议还是不要直接放RoleId
进去,因为这个玩意在实战中往往是一对多的。
var permission = PermissionEntity
.Where(x => x.Roles!.Any(y => y.Id == roleId) && x.Url == context.Path).First();
if (permission == null)
{
NavigationManager.NavigateTo("/Login");
}
最后我们判断一下数据库里这个角色有没有这个路径的权限,如果没有,我们就跳转。
这样我们就可以实现根据path来判断权限了。
这里由于是教程类的,所以所有的判断我都是直接从数据库里取得,正式使用的时候建议放到缓存里面,如果没有页面都走一次数据库,那么数据库的压力会非常大。
默认数据的路径我稍微修改了一下,去掉了前面的
/
,这里直接把数据库给删掉,然后重新运行就行了。
源码在github:https://github.com/j4587698/BlazorLearn,分支lesson5
从零开始Blazor Server(5)--权限验证的更多相关文章
- 从零开始Blazor Server(15)--总结
我们用了14篇文章,基本上把一个后台管理系统需要的UI部分都说的差不多了.所以这套文章也该到了结束的时候了. 这里面有很多问题,比如我们直接使用UI来拉数据库信息而没有使用service,再比如我们大 ...
- 从零开始Blazor Server(1)--项目搭建
项目介绍 本次项目准备搭建一个使用Furion框架,Blazor的UI使用BootstrapBlazor.数据库ORM使用Freesql的后台管理系统. 目前的规划是实现简单的注册,登录.增加管理员跟 ...
- 从零开始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 ...
- 从零开始Blazor Server(6)--基于策略的权限验证
写这个的原因 现在BootstrapBlazor处于大更新时期,Menu组件要改为泛型模式. 本来我们的这一篇应该是把Layout改了,但是改Layout肯定要涉及到菜单,如果现在写了呢,就进入一个发 ...
- 从零开始Blazor Server(7)--使用Furion权限验证
序 上面两篇我们讲了怎么用OnNavigateAsync来验证权限,又写了怎么用策略来验证权限. 其实我们既然集成了Fution,就可以用Furion带的方式来验证. 创建AdminHandler 我 ...
- 从零开始Blazor Server(2)--整合数据库
开篇 上一篇文章我们留了个尾巴,没有把freesql整合进去,这篇文章我们来整合. 目前的思路呢,是做一个简单的四不像的RABC,也有用户.角色. 权限三部分. 但是其中每个用户只有一个角色,即用户和 ...
- 从零开始Blazor Server(4)--登录系统
说明 上一篇文章中我们添加了Cookie授权,可以跳转到登录页了.但是并没有完成登录,今天我们来完成它. 我们添加Cookie授权的时候也说了,这套跟MVC一模一样,所以我们登录也是跟MVC一模一样. ...
随机推荐
- 一键解决Win10 LTSC 2021官方镜像存在的问题
一键解决Win10 LTSC 2021官方镜像存在的问题 由于适用了win10 ltsc 2021之后,发现官方镜像存在一些致命的bug.但是本人又喜欢这个官方精简的系统,所以进行了一些修复.并将搜集 ...
- Spring Boot配置全局异常捕获
1 SpringBoot配置全局的异常捕获 项目的说明 配置thymeleaf作为视图模板 ExceptionController.java模拟测试用 MyAjaxExceptionHandler.j ...
- Java 对象实现 Serializable 的原因
java.io.Serializable 是 Java 中的一种标记接口(marker interface).标记接口是一种特殊的接口,java.io.Serializable 接口没有任何方法,也没 ...
- pymysql.err.OperationalError: (1054, "Unknown column 'aa' in 'field list'")(已解决)
错误描述: 今天使用python连接mysql数据库进行数据添加时,出现报错"pymysql.err.OperationalError: (1054, "Unknown colum ...
- ATM+购物车项目流程
目录 需求分析 架构设计 功能实现 搭建文件目录 conf配置文件夹 lib公共功能文件夹 db数据文件夹 interface业务逻辑层文件夹 core表现层文件夹 测试 最外层功能(src.py) ...
- 『忘了再学』Shell基础 — 20、Shell中的运算符
目录 1.Shell常用运算符 2.Shell中数值运算的方法 (1)方式一 (2)方式二 (3)方式三(推荐) 1.Shell常用运算符 Shell中常用运算符如下表: 优先级数值越大优先级越高,具 ...
- Vue基础篇之 插槽 slot
- Tomcat启动失败:java.lang.NoSuchMethodError: org.apache.tomcat.util.res.StringManager.getManager(Ljava/lang/Class;)Lorg/apache/tomcat/util/res/StringManager
项目开发中发现服务器上Tomcat启动失败 开始定位 第一步:打开tomcat日志catalina.log: 2017-07-25 17:02:43,799 [Catalina-startStop-1 ...
- 变量作用域——JavaSE基础
变量作用域 局部变量.成员变量.静态变量的区别 类型 声明位置 从属于 生命周期 局部变量 方法或语句块内部 方法/语句块 从声明位置开始,直到方法或语句块执行完毕,局部变量消失 成员变量 (实例变量 ...
- Docker容器安装RabbitMQ
Docker容器安装RabbitMQ 准备资料 erlang的rpm安装包 https://github.com/rabbitmq/erlang-rpm/releases rabbitmq的rpm安装 ...