原文: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>

更容易管理

基于策略的授权的最大优点就是改进应用程序中的授权管理。使用基于角色的授权,如果我们有两个角色被允许访问受保护资源 - 比如adminmoderator。我们需要在每个被允许的访问的资源添加一个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();
}
}

我们首先定义了两个常量IsAdminIsUser。我们将在注册策略时候使用它们。接下来是策略本身,IsAdminPolicyIsUserPolicy。这里我使用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.razorAuthorize属性。

@attribute [Authorize(Policy = Policies.IsAdmin)]

就是这样!我们的应用程序现在转移到基于策略的授权。我们现在有一个更灵活的授权系统,可以使用角色、声明、自定义策略或者上述任何组合。

关于服务端Blazor

我并没有专门讨论服务端Blazor,原因很简单,我们上面所做的应该可以毫无问题的转移到服务端Blazor。

总结

在这篇文章中,我们讨论了ASP.NET Core和Blazor基于策略的授权。我们也了解了使用基于策略的授权相对于基于角色的授权的一些优点并且我们将应用程序从基于角色的验证迁移到了基于策略的验证。

最后还是代码(GITHUB)

Blazor应用程序基于策略的授权的更多相关文章

  1. Blazor应用程序基于角色的授权

    原文:https://chrissainty.com/securing-your-blazor-apps-configuring-role-based-authorization-with-clien ...

  2. Security » Authorization » 基于自定义策略的授权

    Custom Policy-Based Authorization¶ 基于自定义策略的授权 98 of 108 people found this helpful Underneath the cov ...

  3. 从零开始Blazor Server(3)--添加cookie授权

    认证方式简述 Blazor Server微软官方还是推荐直接使用Cookie授权,因为本来Blazor Server就是前后端不分离的.不存在Cookie跨域等一系列问题. 只要不是使用SSO之类的统 ...

  4. Asp.Net Core--自定义基于策略的授权

    翻译如下: 在封面下,角色授权和声明授权使用需求,需求的处理程序和预配置的策略. 这些构建块允许您在代码中表示授权评估,从而允许更丰富,可重用和容易测试的授权结构. 授权策略由一个或多个需求组成,并在 ...

  5. shiro认证策略,授权

    有具体问题的可以参考之前的关于shiro的博文,关于shiro的博文均是一次工程的内容 ! 认证策略: 修改认证策略: applicationContext.xml <!-- 认证器 --> ...

  6. Identity Server 4 原理和实战(完结)_Hybrid Flow 实例, Claims, 角色授权和策略授权

    4分50 建立客户端 不需要身份认证 客户端叫做HybirdClient 配置IdentityServer服务端,先把客户端添加上 把userClaims添加到token里面 然后运行服务端就可以了 ...

  7. Linux环境下MySQL的安装、密码策略、忘记密码后的破解及用户授权等。

    mysql安装.用户密码.密码策略.授权用户等(mysql5.7版本) 1.mysql安装后相关目录与文件: 主配置文件: /etc/my.cnf 数据库目录: /var/lib/mysql/ 默认端 ...

  8. 基于 IdentityServer3 实现 OAuth 2.0 授权服务数据持久化

    最近花了一点时间,阅读了IdentityServer的源码,大致了解项目整体的抽象思维.面向对象的重要性; 生产环境如果要使用 IdentityServer3 ,主要涉及授权服务,资源服务的部署负载的 ...

  9. ASP.NET Core 认证与授权[5]:初识授权

    经过前面几章的姗姗学步,我们了解了在 ASP.NET Core 中是如何认证的,终于来到了授权阶段.在认证阶段我们通过用户令牌获取到用户的Claims,而授权便是对这些的Claims的验证,如:是否拥 ...

随机推荐

  1. python数据可视化简介(一)

    目录 一:配置jupyter notebook 二:Matplotlib图像实例   数据可视化是用图形或者表格的形式进行数据显示,用图形化的手段,清晰有效地传递与沟通信息.既要保证直观易分析,又要保 ...

  2. 【OOM】解决思路

    一.什么是OOM? OOM就是outOfMemory,内存溢出!可能是每一个java人员都能遇到的问题!原因是堆中有太多的存活对象(GC-ROOT可达),占满了堆空间. 二.怎么解决? 1.拿到内存溢 ...

  3. Oracle 去重后排序

    因项目需求,需要将查询结果,去重后,在按照主键(自增列)排序,百度一番,记录下来 DEMO SELECT * FROM (SELECT ROW_NUMBER() OVER(PARTITION BY S ...

  4. Android JS打开原生应用

    设置App通过网页JS,唤醒打开本地应用. 在AndroidManifest 中,在应用启动页配置下,添加android:exported="true",设置category 添加 ...

  5. tomcat配置通过域名访问项目

    tomcat配置通过域名访问项目,是修改conf/server.xml里面的配置信息实现.具体如下: (1)修改Connector节点的port属性值 <Connector port=" ...

  6. 查询Mysql数据库所有数据库所占磁盘空间大小

    查询Mysql数据库所有数据库所占磁盘空间大小: /,),' MB') as data_size, concat(truncate(sum(index_length)//,),'MB') as ind ...

  7. [Flink]测试用的fake温度传感器

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  8. python3基础学习(1)

    python基础内容讲解主要内容: 1.使用编辑器(IDE) 2.第一个“hello world” 3.何所谓“变量” 4.python与其他主流语言输出对比 5.数据类型 6.python用作“计算 ...

  9. Matplotlib基础 可视化绘图 学习笔记

    简单的绘图 1.确定画布并画线 import matplotlib.pyplot as plt #静态绘图 fig = plt.figure() ax = fig.add_subplot(345) # ...

  10. Anaconda3使用

    1.使用conda安装各种包到指定路径下的环境, conda install --prefix=/home/xxx/PycharmProjects/project_01/env numpy 2.安装指 ...