从零开始Blazor Server(6)--基于策略的权限验证
创始人
2024-02-09 19:33:43
0

现在BootstrapBlazor处于大更新时期,Menu组件要改为泛型模式。

本来我们的这一篇应该是把Layout改了,但是改Layout肯定要涉及到菜单,如果现在写了呢,就进入一个发布就过时的状态,就很尴尬,所以后面的就稍微拖一拖。

加上昨天有人说我用OnNavigateAsync违反单一性原则,要用策略,所以这里我们说下策略怎么做。

添加策略相关的代码

首先我们要有一个实现IAuthorizationRequirement接口的类,这个类没有什么特别的要求,我们就写一个空类来处理。

public class AdminRequirement : IAuthorizationRequirement
{}

然后要写一个Handler,来继承这个AuthorizationHandler,其中泛型是我们上面的实现接口的类。

public class AdminRequirementHandler : AuthorizationHandler
{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();

然后注册我们的授权策略

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

然后修改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,这里面就是对应的路由地址了。

下面就跟之前一样,用路由地址来判断是否是又权限就行了。

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...