Blazor应用程序基于策略的授权
原文:https://chrissainty.com/securing-your-blazor-apps-configuring-policy-based-authorization-with-blazor/
在上一篇文章中,我展示了如何向Blazor WebAssembly(Blazor客户端)应用程序添加基于角色的授权。在这篇文章中,我将向您展示如何使用Blazor配置基于策略的授权。
基于策略的授权
ASP.NET Core基于策略的授权允许一种更加灵活的方式来创建授权规则。策略授权由三个概念组成:
- Policy - 策略有一个或者多个要求。
- Requirement - 策略用于评估当前用户主体的数据参数集合。
- Handler - 处理程序用于确定当前用户主体是否有权访问所请求的资源。
策略通常在应用程序启动时在Startup类的ConfigureService方法中注册。
services.AddAuthorization(config => {
config.AddPolicy("IsDeveloper", policy => policy.RequireClaim("IsDeveloper", "true"));
});
在上面的示例中,策略IsDeveloper要求用户需要有IsDeveloper声明,并且值为true。
与角色授权一样,您一样可以使用Authorize属性应用于策略授权。
[Route("api/[controller]")]
[ApiController]
public class SystemController
{
[Authorize(Policy = “IsDeveloper”)]
public IActionResult LoadDebugInfo()
{
// ...
}
}
Blazors指令和组件也一样可以使用策略。
@page "/debug"
@attribute [Authorize(Policy = "IsDeveloper")]
<AuthorizeView Policy="IsDeveloper">
<p>You can only see this if you satisfy the IsDeveloper policy.</p>
</AuthorizeView>
更容易管理
基于策略的授权的最大优点就是改进应用程序中的授权管理。使用基于角色的授权,如果我们有两个角色被允许访问受保护资源 - 比如admin和moderator。我们需要在每个被允许的访问的资源添加一个Authorize属性。
[Authorize(Roles = "admin,moderator")]
这在一开始看起来不是很糟糕,但是如果出现一个新的需求,第三个角色superuser,需要相同的访问权限,该怎么办呢?现在我们需要在每个被访问资源更新所有角色。通过基于策略的验证,我们可以避免这种情况。
我们可以在一个定义一个策略,然后将其应用于需要它的所有资源。当需要添加额外角色时,我们只需更新这个策略,而不需要更新各个资源。
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(config =>
{
config.AddPolicy("IsAdmin", policy => policy.RequireRole("admin", "moderator", "superuser"));
});
}
[Authorize(Policy = "IsAdmin")]
创建自定义需求
策略授权非常灵活,您可以基于角色、声明创建需求,甚至可以创建自定义需求。让我们来看看如何创建自定义需求。
通常,当您有复杂的逻辑时,会使用自定义需求。如上所述,我们需要顶一个需求和一个处理程序来使用策略授权。
我们来创建一个检查用户的电子邮件地址是否使用公司域的需求。我们需要创建授权需求类,这个类需要实现IAuthorizationRequirement接口,这只是一个空的标记接口。
public class CompanyDomainRequirement : IAuthorizationRequirement
{
public string CompanyDomain { get; } public CompanyDomainRequirement(string companyDomain)
{
CompanyDomain = companyDomain;
}
}
接下来,我们需要为我们的需求创建一个继承自AuthorizationHandler的处理程序,T就是要处理的需求。
public class CompanyDomainHandler : AuthorizationHandler<CompanyDomainRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CompanyDomainRequirement requirement)
{
if (!context.User.HasClaim(c => c.Type == ClaimTypes.Email))
{
return Task.CompletedTask;
} var emailAddress = context.User.FindFirst(c => c.Type == ClaimTypes.Email).Value; if (emailAddress.EndsWith(requirement.CompanyDomain))
{
return context.Succeed(requirement);
} return Task.CompletedTask;
}
}
在上面代码中,我们检查是否存在电子邮件声明。如果存在,那么我们检查它是否按要求中指定的域结束,如果是,则返回成功,否则就是失败。
我们只需要将我们的要求与一个策略关联起来,并将CompanyDomainHandler注册到依赖注入容器中。
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(config =>
{
config.AddPolicy("IsCompanyUser", policy =>
policy.Requirements.Add(new CompanyDomainRequirement("newco.com")));
}); services.AddSingleton<IAuthorizationHandler, CompanyDomainHandler>();
}
要了解更多关于自定义要求的详细信息,建议查看官方文档。
Blazor中使用策略
现在我们已经了解了什么是策略,让我们看看如何在应用程序中使用它们。
我们将把上一篇文章的中Blazor应用程序切换到基于策略的授权。作为这项工作的一部分,我们将看到基于策略的授权的另一个优点,即能够在共享项目中定义策略并在服务端和客户端引用它们。
创建共享策略
在share项目中创建策略之前,我们需要先从NuGet安装Microsoft.AspNetCore.Authorization这个包。
安装之后,使用以下代码创建一个名为Policies 的类。
public static class Policies
{
public const string IsAdmin = "IsAdmin";
public const string IsUser = "IsUser"; public static AuthorizationPolicy IsAdminPolicy() {
return new AuthorizationPolicyBuilder().RequireAuthenticatedUser()
.RequireRole("Admin")
.Build();
} public static AuthorizationPolicy IsUserPolicy() {
return new AuthorizationPolicyBuilder().RequireAuthenticatedUser()
.RequireRole("User")
.Build();
}
}
我们首先定义了两个常量IsAdmin和IsUser。我们将在注册策略时候使用它们。接下来是策略本身,IsAdminPolicy和IsUserPolicy。这里我使用AuthorizationPolicyBuilder来定义每个策略,这两个策略都需要用户进行身份验证,然后根据策略的不同,用户可以是Admin角色和User角色。
配置服务端
现在我们已经定义了策略,我们需要让服务端使用它们。首先,在Startup类中的ConfigureServices方法注册策略,在AddAuthentication之后添加以下代码。
services.AddAuthorization(config => {
config.AddPolicy(Policies.IsAdmin, Policies.IsAdminPolicy());
config.AddPolicy(Policies.IsUser, Policies.IsUserPolicy());
});
代码非常容易理解,我们使用Policies类中定义的常量来声明它们的名称,并注册每个策略,避免使用魔法字符串。
在WeatherForecastController则可以使用IsAdmin策略代旧的角色。
[ApiController]
[Route("[controller]")]
[Authorize(Policy = Policies.IsAdmin)]
public class WeatherForecastController : ControllerBase
同样,我们可以使用名称常量来避免魔法字符串。
配置客户端
现在服务端可以使用我们定义的新策略,接下来就是在Blazor客户端使用他们。
和服务端一样,我们也在在Startup类中的ConfigureServices方法注册策略。之前我们已经调用了AddAuthorizationCore,所以只需要更新它。
services.AddAuthorizationCore(config => {
config.AddPolicy(Policies.IsAdmin, Policies.IsAdminPolicy());
config.AddPolicy(Policies.IsUser, Policies.IsUserPolicy());
});
在Index.razor,使用策略更新AuthorizeView组件 - 一样要避免使用魔法字符串。
<AuthorizeView Policy="@Policies.IsUser">
<p>You can only see this if you satisfy the IsUser policy.</p>
</AuthorizeView> <AuthorizeView Policy="@Policies.IsAdmin">
<p>You can only see this if you satisfy the IsAdmin policy.</p>
</AuthorizeView>
最后,更新FetchData.razor的Authorize属性。
@attribute [Authorize(Policy = Policies.IsAdmin)]
就是这样!我们的应用程序现在转移到基于策略的授权。我们现在有一个更灵活的授权系统,可以使用角色、声明、自定义策略或者上述任何组合。
关于服务端Blazor
我并没有专门讨论服务端Blazor,原因很简单,我们上面所做的应该可以毫无问题的转移到服务端Blazor。
总结
在这篇文章中,我们讨论了ASP.NET Core和Blazor基于策略的授权。我们也了解了使用基于策略的授权相对于基于角色的授权的一些优点并且我们将应用程序从基于角色的验证迁移到了基于策略的验证。
最后还是代码(GITHUB)
Blazor应用程序基于策略的授权的更多相关文章
- Blazor应用程序基于角色的授权
原文:https://chrissainty.com/securing-your-blazor-apps-configuring-role-based-authorization-with-clien ...
- Security » Authorization » 基于自定义策略的授权
Custom Policy-Based Authorization¶ 基于自定义策略的授权 98 of 108 people found this helpful Underneath the cov ...
- 从零开始Blazor Server(3)--添加cookie授权
认证方式简述 Blazor Server微软官方还是推荐直接使用Cookie授权,因为本来Blazor Server就是前后端不分离的.不存在Cookie跨域等一系列问题. 只要不是使用SSO之类的统 ...
- Asp.Net Core--自定义基于策略的授权
翻译如下: 在封面下,角色授权和声明授权使用需求,需求的处理程序和预配置的策略. 这些构建块允许您在代码中表示授权评估,从而允许更丰富,可重用和容易测试的授权结构. 授权策略由一个或多个需求组成,并在 ...
- shiro认证策略,授权
有具体问题的可以参考之前的关于shiro的博文,关于shiro的博文均是一次工程的内容 ! 认证策略: 修改认证策略: applicationContext.xml <!-- 认证器 --> ...
- Identity Server 4 原理和实战(完结)_Hybrid Flow 实例, Claims, 角色授权和策略授权
4分50 建立客户端 不需要身份认证 客户端叫做HybirdClient 配置IdentityServer服务端,先把客户端添加上 把userClaims添加到token里面 然后运行服务端就可以了 ...
- Linux环境下MySQL的安装、密码策略、忘记密码后的破解及用户授权等。
mysql安装.用户密码.密码策略.授权用户等(mysql5.7版本) 1.mysql安装后相关目录与文件: 主配置文件: /etc/my.cnf 数据库目录: /var/lib/mysql/ 默认端 ...
- 基于 IdentityServer3 实现 OAuth 2.0 授权服务数据持久化
最近花了一点时间,阅读了IdentityServer的源码,大致了解项目整体的抽象思维.面向对象的重要性; 生产环境如果要使用 IdentityServer3 ,主要涉及授权服务,资源服务的部署负载的 ...
- ASP.NET Core 认证与授权[5]:初识授权
经过前面几章的姗姗学步,我们了解了在 ASP.NET Core 中是如何认证的,终于来到了授权阶段.在认证阶段我们通过用户令牌获取到用户的Claims,而授权便是对这些的Claims的验证,如:是否拥 ...
随机推荐
- Web前端基础(2):HTML(二)
1. body中的相关标签 1.1 标题标签:hn HTML提供<hn>系列标签,用于修饰标签,包含:<h1>.<h2>.<h3>.<h4> ...
- java基础(21):异常
1. 异常 什么是异常?Java代码在运行时期发生的问题就是异常. 在Java中,把异常信息封装成了一个类.当出现了问题时,就会创建异常类对象并抛出异常相关的信息(如异常出现的位置.原因等). 1.1 ...
- 在RPA中使用Python批量生成指定尺寸的缩略图!比Ps好用!
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取 htt ...
- 敏捷软件开发_设计原则<三>
敏捷软件开发_设计原则 单一职责原则(single responsibilities principle,SRP) 原理:一个类应该只有一个变化 分离职责:如果不耦合的职责那么很简单,如果两个职责耦合 ...
- 记录TortoiseGit=>https请求/ssh请求配置
ssh C:\Program Files\Git\usr\bin\ssh.exe https C:\Program Files\TortoiseGit\bin\TortoisePlink.exe
- 安装quickLook插件以及解决如何不能读取offic问题
目录 @(安装quickLook插件) quickLook插件是Mac上的快速浏览的一个功能,现在win10系统上也能安装插件,这个插件可以快速浏览txt,doc,图片,表格等文件如下图: 我认为最方 ...
- JavaScript判断是否是数字
JavaScript判断是否是数字的几种方法 isNaN() /** * 判断是否是数字 */ function isNumber(value){ if(isNaN(value)){ return f ...
- [Go] gocron源码阅读-groutine与channel应用到信号捕获
直接使用go 函数名()可以开启一个grountine,channel可以接收信息并且如果没有数据时会阻塞住channel对应的是底层数据结构的引用,复制channel和函数传参都是拷贝的引用make ...
- Pwn-pwn-200
题目地址 ttp://www.whalectf.xin/files/47a658e388a0c505fc07b6ee48a4a2e2/binary_200 32位,开启了NX和Canary保护 存在字 ...
- 【转】Restful架构详解
1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的 ...