121 lines
3.8 KiB
Plaintext
121 lines
3.8 KiB
Plaintext
@using Microsoft.AspNetCore.Authorization
|
||
@using System.Security.Claims
|
||
@inject IPermissionService PermissionService
|
||
@inject IAuthorizationService AuthorizationService
|
||
|
||
<CascadingAuthenticationState>
|
||
<AuthorizeView Context="authContext">
|
||
<Authorized>
|
||
@if (_hasPermission)
|
||
{
|
||
@ChildContent
|
||
}
|
||
else if (!string.IsNullOrEmpty(NotAuthorizedContent))
|
||
{
|
||
@NotAuthorizedContent
|
||
}
|
||
</Authorized>
|
||
<NotAuthorized>
|
||
@if (!string.IsNullOrEmpty(NotAuthenticatedContent))
|
||
{
|
||
@NotAuthenticatedContent
|
||
}
|
||
</NotAuthorized>
|
||
</AuthorizeView>
|
||
</CascadingAuthenticationState>
|
||
|
||
@code {
|
||
[CascadingParameter] Task<AuthenticationState>? AuthenticationStateTask { get; set; }
|
||
|
||
[Parameter] public RenderFragment? ChildContent { get; set; }
|
||
[Parameter] public string? Permission { get; set; }
|
||
[Parameter] public string[]? Permissions { get; set; }
|
||
[Parameter] public bool RequireAll { get; set; }
|
||
[Parameter] public string? Policy { get; set; }
|
||
[Parameter] public string? NotAuthorizedContent { get; set; }
|
||
[Parameter] public string? NotAuthenticatedContent { get; set; }
|
||
|
||
private bool _hasPermission;
|
||
|
||
protected override async Task OnParametersSetAsync()
|
||
{
|
||
_hasPermission = false;
|
||
|
||
var authState = AuthenticationStateTask is null
|
||
? await Task.FromResult(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())))
|
||
: await AuthenticationStateTask;
|
||
|
||
var user = authState.User;
|
||
|
||
if (user?.Identity is null || !user.Identity.IsAuthenticated)
|
||
{
|
||
_hasPermission = false;
|
||
return;
|
||
}
|
||
|
||
// 优先基于声明快速判断(适用于 Server 与 WASM)
|
||
if (!string.IsNullOrEmpty(Permission))
|
||
{
|
||
if (user.Claims.Any(c => c.Type == ClaimKeys.Permission && c.Value == Permission))
|
||
{
|
||
_hasPermission = true;
|
||
return;
|
||
}
|
||
|
||
// 回退:调用后端权限服务(适用于 Server-side 权限来源于数据库)
|
||
_hasPermission = await SafeHasPermissionAsync(Permission);
|
||
return;
|
||
}
|
||
|
||
if (Permissions != null && Permissions.Length > 0)
|
||
{
|
||
var userPermissions = user.Claims.Where(c => c.Type == ClaimKeys.Permission).Select(c => c.Value).ToHashSet();
|
||
|
||
if (RequireAll)
|
||
{
|
||
if (Permissions.All(p => userPermissions.Contains(p)))
|
||
{
|
||
_hasPermission = true;
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (Permissions.Any(p => userPermissions.Contains(p)))
|
||
{
|
||
_hasPermission = true;
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 回退:调用后端权限服务
|
||
if (RequireAll)
|
||
_hasPermission = await PermissionService.HasAllPermissionsAsync(Permissions);
|
||
else
|
||
_hasPermission = await PermissionService.HasAnyPermissionAsync(Permissions);
|
||
|
||
return;
|
||
}
|
||
|
||
if (!string.IsNullOrEmpty(Policy))
|
||
{
|
||
// 使用 AuthorizationService 并传入当前用户
|
||
var result = await AuthorizationService.AuthorizeAsync(user, Policy);
|
||
_hasPermission = result.Succeeded;
|
||
return;
|
||
}
|
||
}
|
||
|
||
private async Task<bool> SafeHasPermissionAsync(string permission)
|
||
{
|
||
try
|
||
{
|
||
return await PermissionService.HasPermissionAsync(permission);
|
||
}
|
||
catch
|
||
{
|
||
// 出错时默认拒绝
|
||
return false;
|
||
}
|
||
}
|
||
} |