写这个的原因

现在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

最新文章

  1. &lt;&lt;&lt; Oracle序列的创建、修改、删除基本操作
  2. 用例设计工具PICT — 输入组合覆盖
  3. SQL Server 2008 R2安装图解教程
  4. 重新想象 Windows 8.1 Store Apps (93) - 控件增强: GridView, ListView
  5. 设计模式之Builder (创建者模式)的一些个人理解(转)
  6. UVA 12730 Skyrk&#39;s Bar --期望问题
  7. D. Powerful array 莫队算法或者说块状数组 其实都是有点优化的暴力
  8. librtmp推流使用aac编码音频的html5和flash播放问题
  9. 两个STL网址 总结的很好 &amp;&amp; c++堆的网址
  10. android有点纠结的小问题
  11. 最近用的几个sql语句
  12. ASP.NET-FineUI开发实践-18
  13. 20175316 盛茂淞 实验一 Java开发环境的熟悉
  14. left join不同写法导致数据差异
  15. python操作txt文件中数据教程[1]-使用python读写txt文件
  16. centos7搭建ELK开源实时日志分析系统
  17. Grafana展示DNS解析延时
  18. 【Nodejs】nimble或async并不能保证程序串行执行,回调是回避不了的坑
  19. TCP_AIO_Server_ZC_01
  20. Python中调用设置环境变量的bat

热门文章

  1. JavaScript中if语句优化和部分语法糖小技巧推荐
  2. Spring 源码(16)Spring Bean的创建过程(7)属性填充
  3. 安装Suberversion[SVN]到CentOS(YUM)
  4. CoaXPress 时间戳 Time Stamping
  5. CCPC、Petrozavodsk Camp、OpenCup 题解汇总
  6. 论文解读(SUBLIME)《Towards Unsupervised Deep Graph Structure Learning》
  7. Keil软件下用Jlink无法识别芯片
  8. JavaScript Number -&gt; String
  9. 【摸鱼神器】UI库秒变LowCode工具——列表篇(二)维护json的小工具
  10. Lucene从入门到实战