Blazor WebAssembly .Net 5 Msal 身份验证中基于角色的授权

Posted

技术标签:

【中文标题】Blazor WebAssembly .Net 5 Msal 身份验证中基于角色的授权【英文标题】:Role-based authorization in Blazor WebAssembly .Net5 MsalAuthentication 【发布时间】:2021-11-25 06:00:20 【问题描述】:

我的 Blazor Web Assembly 应用已在 Azure Active Directory 中注册(仅限单租户我的组织)。

组声明已添加到令牌配置中,并具有将组作为角色声明发出的可选设置。

我能够运行应用程序并进行身份验证,但任何具有授权属性的页面定义了我的组织中的特定角色,都会显示“您无权访问此资源”。在 App.razor 中配置的未授权消息

我已确认收到角色声明,但它是角色名称的 json 数组。

我尝试创建一个自定义 AccountClaimsPrincipalFactory,在其中我反序列化角色声明值并为数组中的每个角色名称添加一个新声明,但仍然得到相同的结果。

public class CustomAccountClaimsPrincipalFactory : AccountClaimsPrincipalFactory<RemoteUserAccount>

    public CustomAccountClaimsPrincipalFactory(IAccessTokenProviderAccessor accessor)
        : base(accessor)  

    public async override ValueTask<ClaimsPrincipal> CreateUserAsync(RemoteUserAccount account, RemoteAuthenticationUserOptions options)
    
        var user = await base.CreateUserAsync(account, options);

        if (!user.Identity.IsAuthenticated)
        
            return user;
        

        if (user.Identity is not ClaimsIdentity identity)
        
            return user;
        

        var roleClaims = identity.FindAll("roles");

        if (roleClaims is null || !roleClaims.Any())
        
            return user;
        

        foreach (var roleClaim in roleClaims)
        
            try
            
                var roleNames = JsonConvert.DeserializeObject<string[]>(roleClaim.Value);

                foreach (var roleName in roleNames)
                
                    identity.AddClaim(new Claim(ClaimTypes.Role, roleName));
                
            
            catch
            
                // continue
            
        

        return user;
    

在我的 Program.cs 中

_ = builder.Services.AddMsalAuthentication(options =>
    
        Configuration.Bind("AzureAD", options.ProviderOptions.Authentication);
        options.ProviderOptions.DefaultAccessTokenScopes.Add("app-scope");
    )
    .AddAccountClaimsPrincipalFactory<CustomAccountClaimsPrincipalFactory>();

在我的页面上

@using Microsoft.AspNetCore.Authorization
@attribute [Authorize(Roles="GROUP1, GROUP2, GROUP3")]

我已确认AccountClaimsPrincipalFactory 已将每个角色添加为新声明,并且我能够查看用户的个人资料信息并从user.IsInRole("GROUP1"); 获得真实响应,但是,在任何具有[Authorize] 属性的页面上,我仍然看到同样的错误:

您无权访问此资源

我错过了什么吗?有什么建议吗?

【问题讨论】:

【参考方案1】:

解决方案是修改令牌配置以使用组 ID 而不是 sAMAcountName 添加组声明,然后在页面的 [Authorize] 属性和 AuthorizeView 组件中使用组的对象 id 值。

@using Microsoft.AspNetCore.Authorization
[Authorize(Roles="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy, zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz")]
<div>
    <p>Only user's in the "X", "Y", or "Z" role are authorized to view this page</p>
    <AuthorizeView  Roles="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz">
        <p>This content is only rendered for user's in the "X" or "Z" role</p>
    </AuthorizeView>

    <AuthorizeView  Roles="yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy">
        <p>This content is only rendered for user's in the "Y" role</p>
    </AuthorizeView>
</div>

【讨论】:

以上是关于Blazor WebAssembly .Net 5 Msal 身份验证中基于角色的授权的主要内容,如果未能解决你的问题,请参考以下文章

Blazor WebAssembly .Net 5 Msal 身份验证中基于角色的授权

Blazor - WebAssembly ASP.NET Core 托管模型

使用 .NET 5.0 的 Blazor WebAssembly 应用程序 - Google 搜索 - 正在加载...发生未处理的错误。重新加载

Blazor正式成为Microsoft官方.NET 和WebAssembly项目

2022 wasm blazor.webassembly.js 未找到 .net5 到 .net6 升级

Blazor WebAssembly 应用程序中进行 HTTP 请求