ow
This commit is contained in:
commit
f05d2d215f
678 files changed
+73865
No files matched your search
@@ -0,0 +1,158 @@
|
||||
using CloudBuilder.Core.DatabaseAccessor.Entity;
|
||||
using CloudBuilder.Core.Service;
|
||||
using CloudBuilder.Security.Data;
|
||||
using CloudBuilder.Security.Entity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudBuilder.Security.Service.Authorization
|
||||
{
|
||||
public class PermissionContext
|
||||
{
|
||||
private readonly IApplicationService service;
|
||||
|
||||
public PermissionContext(IApplicationService service)
|
||||
{
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public string[] GetAllGroups()
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.UserId)) return null!;
|
||||
|
||||
var userActors = service.GetRepository<IRepository<SecurityUserActorEntity>>().DetachedEntities.Where(x => x.UserName == service.UserId);
|
||||
|
||||
var actorGroups = service.GetRepository<IRepository<SecurityActorGroupEntity>>().DetachedEntities.Where(x => userActors.Select(x => x.ActorName).Contains(x.ActorName));
|
||||
|
||||
if (!actorGroups.Any())
|
||||
{
|
||||
return null!;
|
||||
}
|
||||
|
||||
return actorGroups.Select(x => x.GroupName).ToArray();
|
||||
}
|
||||
|
||||
public SecurityUserPermissionInfo GetUserPermissionInfo()
|
||||
{
|
||||
SecurityUserPermissionInfo info = new SecurityUserPermissionInfo();
|
||||
|
||||
var userActors = service.GetRepository<IRepository<SecurityUserActorEntity>>()
|
||||
.DetachedEntities
|
||||
.Where(x => x.UserName == service.UserId);
|
||||
|
||||
// 关键修复:加上 .ToArray(),把 actorGroups 加载到本地内存,变成内存集合,不再是IQueryable延迟查询
|
||||
var actorGroups = service.GetRepository<IRepository<SecurityActorGroupEntity>>()
|
||||
.DetachedEntities
|
||||
.Where(x => userActors.Select(u => u.ActorName).Contains(x.ActorName))
|
||||
.ToArray(); // ← 这里ToArray强制立刻查询数据库,后续全部内存操作
|
||||
|
||||
info.UserGroups = actorGroups.Select(x => x.GroupName).ToArray();
|
||||
|
||||
info.Permissions = (
|
||||
from p in service.GetRepository<IRepository<SecurityGroupPermissionViewEntity>>().DetachedEntities.AsEnumerable()
|
||||
join g in actorGroups on p.GroupName equals g.GroupName
|
||||
select p
|
||||
).ToArray();
|
||||
|
||||
info.PermissionDependents =
|
||||
(
|
||||
from p in service.GetRepository<IRepository<SecurityGroupPermissionDependentViewEntity>>().DetachedEntities.AsEnumerable()
|
||||
join g in actorGroups on p.GroupName equals g.GroupName
|
||||
select p
|
||||
).ToArray();
|
||||
|
||||
info.PermissionFunctionMaps =
|
||||
(
|
||||
from m in service.GetRepository<IRepository<SecurityPermissionFunctionMapViewEntity>>().DetachedEntities.AsEnumerable()
|
||||
join p in info.Permissions on m.PermissionName equals p.PermissionName
|
||||
select m
|
||||
).ToArray();
|
||||
return info;
|
||||
}
|
||||
|
||||
public bool CanNone(string permission)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.UserId)) return false;
|
||||
|
||||
SecurityUserPermissionInfo permissionInfo = GetUserPermissionInfo();
|
||||
return permissionInfo.Permissions?.Any(x => x.PermissionName == permission) == true;
|
||||
}
|
||||
|
||||
public bool CanView(string permission)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.UserId)) return false;
|
||||
|
||||
SecurityUserPermissionInfo permissionInfo = GetUserPermissionInfo();
|
||||
return permissionInfo.Permissions?.Any(x => x.PermissionName == permission && x.ViewIndc == YesNoPolicy.YES) == true;
|
||||
}
|
||||
|
||||
public bool CanCreate(string permission)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.UserId)) return false;
|
||||
|
||||
SecurityUserPermissionInfo permissionInfo = GetUserPermissionInfo();
|
||||
return permissionInfo.Permissions?.Any(x => x.PermissionName == permission && x.CreateIndc == YesNoPolicy.YES) == true;
|
||||
}
|
||||
|
||||
public bool CanAmend(string permission)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.UserId)) return false;
|
||||
|
||||
SecurityUserPermissionInfo permissionInfo = GetUserPermissionInfo();
|
||||
return permissionInfo.Permissions?.Any(x => x.PermissionName == permission && x.AmendIndc == YesNoPolicy.YES) == true;
|
||||
}
|
||||
|
||||
public bool CanDelete(string permission)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.UserId)) return false;
|
||||
|
||||
SecurityUserPermissionInfo permissionInfo = GetUserPermissionInfo();
|
||||
return permissionInfo.Permissions?.Any(x => x.PermissionName == permission && x.DeleteIndc == YesNoPolicy.YES) == true;
|
||||
}
|
||||
|
||||
public bool CanNone(string permission, string dependent)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.UserId)) return false;
|
||||
|
||||
SecurityUserPermissionInfo permissionInfo = GetUserPermissionInfo();
|
||||
return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permission && x.DependentDetailName == dependent) == true;
|
||||
}
|
||||
|
||||
public bool CanView(string permission, string dependent)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.UserId)) return false;
|
||||
|
||||
SecurityUserPermissionInfo permissionInfo = GetUserPermissionInfo();
|
||||
return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permission && x.DependentDetailName == dependent && x.ViewIndc == YesNoPolicy.YES) == true;
|
||||
}
|
||||
|
||||
public bool CanCreate(string permission, string dependent)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.UserId)) return false;
|
||||
|
||||
SecurityUserPermissionInfo permissionInfo = GetUserPermissionInfo();
|
||||
return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permission && x.DependentDetailName == dependent && x.CreateIndc == YesNoPolicy.YES) == true;
|
||||
}
|
||||
|
||||
public bool CanAmend(string permission, string dependent)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.UserId)) return false;
|
||||
|
||||
SecurityUserPermissionInfo permissionInfo = GetUserPermissionInfo();
|
||||
return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permission && x.DependentDetailName == dependent && x.AmendIndc == YesNoPolicy.YES) == true;
|
||||
}
|
||||
|
||||
public bool CanDelete(string permission, string dependent)
|
||||
{
|
||||
if (string.IsNullOrEmpty(service.UserId)) return false;
|
||||
|
||||
SecurityUserPermissionInfo permissionInfo = GetUserPermissionInfo();
|
||||
return permissionInfo.PermissionDependents?.Any(x => x.PermissionName == permission && x.DependentDetailName == dependent && x.DeleteIndc == YesNoPolicy.YES) == true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
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 WebService service;
|
||||
private readonly IContext loginContext;
|
||||
private readonly IHttpContextAccessor httpContextAccessor;
|
||||
|
||||
public PermissionHandler(WebService service, IContext loginContext, IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
this.service = service;
|
||||
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 = service.Services.BuildServiceProvider().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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user