簡體   English   中英

為 Blazor 授權動態添加策略聲明

[英]Dynamically adding policy claims for Blazor authorization

我正在創建用於內部授權目的的身份驗證和授權處理程序。 我的目的是讓我的同事能夠輕松地將解決方案實施到他們自己的項目中。 我們使用 Azure AD 進行身份驗證,並使用 Azure 組進行授權。 為了做到這一點,我覺得我一直在想辦法以有效的方式添加授權策略。

現在,我通過 Blazor webassembly 托管配置中我的客戶端項目的 Program 類中官方描述的方式添加它:

            builder.Services.AddAuthorizationCore(options =>
                options.AddPolicy("PolicyName", policy =>
                {
                    policy.RequireClaim("ClaimType", "ClaimValue");
                })
            );

這很好用,但不直觀,因為任何給定的項目都可能需要幾種不同的策略

我還添加了一個自定義授權策略提供程序,如 Microsoft 的文檔中所述:

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/iauthorizationpolicyprovider?view=aspnetcore-6.0

根據他們對本文檔的描述,尤其是文檔中的前幾行,我認為這將是我正在尋找的內容。 但是,如果沒有專門手動添加每個策略,我似乎仍然無法讓它按預期工作。

如果需要,我可以展示我對授權策略提供程序的自定義實現,但它與 Github 中的文檔幾乎完全相同。

策略最常在應用程序啟動時在Startup類的ConfigureServices方法中注冊。

public void ConfigureServices(IServiceCollection services)    
{
    services.AddAuthorization(config =>
    {
        config.AddPolicy("IsDeveloper", policy => policy.RequireClaim("IsDeveloper","true"));
       });
}

IsDeveloper策略要求用戶擁有值為true的聲明IsDeveloper

您可以通過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")]

創建共享策略

為此,我們需要從 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();
}
}

在這里,我們使用AuthorizationPolicyBuilder來定義每個策略,兩者都要求用戶進行身份驗證,然后根據策略處於Admin角色或User角色。

配置服務器

Startup類的ConfigureServices中注冊策略。 在對AddAuthentication的現有調用下添加以下代碼。

services.AddAuthorization(config =>
{
    config.AddPolicy(Policies.IsAdmin, Policies.IsAdminPolicy());
    config.AddPolicy(Policies.IsUser, Policies.IsUserPolicy());
});

注冊每個策略並使用我們在Policies類中定義的常量來聲明它們的名稱,這樣可以節省使用魔法字符串。

如果我們轉到SampleDataController我們可以更新Authorize屬性以使用新的IsAdmin策略而不是舊角色。

[Authorize(Policy = Policies.IsAdmin)]
[Route("api/[controller]")]
public class SampleDataController : Controller

同樣,我們可以使用我們的名稱常量來避免魔術字符串。

配置客戶端

我們的服務器現在正在使用我們定義的新策略,剩下要做的就是交換我們的 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)]

參考這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM