Files
Atomx/Atomx.Admin/Atomx.Admin.Client/Components/AuthorizePermissionView.razor
2025-12-04 19:07:04 +08:00

121 lines
3.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@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;
}
}
}