Blazor WebAssembly .Net5 MsalAuthentication 中基于角色的授权
Role-based authorization in Blazor WebAssembly .Net5 MsalAuthentication
我的 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]
属性,我仍然看到相同的错误:
You are not authorized to access this resource
我错过了什么吗?有什么建议吗?
解决方案是修改令牌配置以使用组 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 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]
属性,我仍然看到相同的错误:
You are not authorized to access this resource
我错过了什么吗?有什么建议吗?
解决方案是修改令牌配置以使用组 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>