114 lines
4.5 KiB
C#
114 lines
4.5 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|