Files
Docker/CloudBuilder/CloudBuilder.Security.Service/Authorization/PermissionHandler.cs
T
2026-09-15 16:25:06 +08:00

114 lines
4.5 KiB
C#
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 CloudBuilder.Core.Application.Packs;
using CloudBuilder.Core.Authorization;
using CloudBuilder.Core.DatabaseAccessor;
using CloudBuilder.Core.DatabaseAccessor.Entity;
using CloudBuilder.Core.DependencyInjection.Request;
using CloudBuilder.Core.Policy;
using CloudBuilder.Core.Service;
using CloudBuilder.Security.Policy;
using DocumentFormat.OpenXml.Drawing.Charts;
using DocumentFormat.OpenXml.EMMA;
using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
using DocumentFormat.OpenXml.Wordprocessing;
using EnvDTE;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
namespace CloudBuilder.Security.Service.Authorization
{
public class PermissionHandler : AuthorizationHandler<PermissionRequirement>, IAuthorize
{
private readonly IServiceProvider serviceProvider;
private readonly IContext loginContext;
private readonly IHttpContextAccessor httpContextAccessor;
/// <summary>
/// 注意:这里必须注入当前请求作用域的 IServiceProvider,
/// 不能使用 WebService.Services.BuildServiceProvider() 新建容器,
/// 否则每次鉴权都会独立构建一整套服务实例(单例/作用域都会重建,且无法释放),
/// 取到的 IApplicationService 也会与当前请求的作用域不一致。
/// </summary>
public PermissionHandler(IServiceProvider serviceProvider, IContext loginContext, IHttpContextAccessor httpContextAccessor)
{
this.serviceProvider = serviceProvider;
this.loginContext = loginContext;
this.httpContextAccessor = httpContextAccessor;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
if (context.HasFailed) return Task.CompletedTask;
var httpContext = httpContextAccessor.HttpContext;
EndpointMetadataCollection collection = httpContext.GetEndpoint().Metadata;
PermissionOperateAttribute permission = null;
foreach (var item in collection)
{
if (!(item is PermissionOperateAttribute)) continue;
permission = (PermissionOperateAttribute)item;
break;
}
//没有设置权限名出错
if (permission == null)
{
context.Fail();
return Task.CompletedTask;
}
string userName = ClaimPolicy.GetClaimValue(httpContextAccessor, ClaimPolicy.CLAINM_USERID);
loginContext.Requestor = userName;
loginContext.SetToken(ClaimPolicy.GetJwtBearerToken(httpContextAccessor.HttpContext));
loginContext.SetCulture(ClaimPolicy.GetClaimValue(httpContextAccessor, ClaimPolicy.CLAINM_LOCALE) ?? CulturePolicy.ZH_CN);
IApplicationService applicationService = serviceProvider.GetRequiredService<IApplicationService>();
PermissionContext permissionContext = new PermissionContext(applicationService);
bool result = false;
switch (permission.Operate)
{
case "None":
result = permissionContext.CanNone(permission.Name);
break;
case "Find":
case "Print":
result = permissionContext.CanView(permission.Name);
break;
case "Insert":
result = permissionContext.CanCreate(permission.Name);
break;
case "Update":
result = permissionContext.CanAmend(permission.Name);
break;
case "Delete":
result = permissionContext.CanDelete(permission.Name);
break;
default:
result = permissionContext.CanNone(permission.Name, permission.Operate);
break;
}
if (result && httpContext != null)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
context.Fail();
return Task.CompletedTask;
}
}
}