shop/CoreCms.Net.Auth/Policys/PermissionForAdminHandler.cs
2025-10-11 11:19:23 +08:00

211 lines
8.7 KiB
C#
Raw Permalink 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.

/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2021/1/31 21:45:10
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.IServices;
using CoreCms.Net.Utility.Extensions;
using CoreCms.Net.Utility.Helper;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace CoreCms.Net.Auth.Policys
{
/// <summary>
/// 权限授权处理器
/// </summary>
public class PermissionForAdminHandler : AuthorizationHandler<PermissionRequirement>
{
/// <summary>
/// 验证方案提供对象
/// </summary>
public IAuthenticationSchemeProvider Schemes { get; set; }
private readonly ISysRoleMenuServices _sysRoleMenuServices;
private readonly IHttpContextAccessor _accessor;
/// <summary>
/// 构造函数注入
/// </summary>
/// <param name="schemes"></param>
/// <param name="navigationRepository"></param>
/// <param name="accessor"></param>
public PermissionForAdminHandler(IAuthenticationSchemeProvider schemes
, ISysRoleMenuServices sysRoleMenuServices
, IHttpContextAccessor accessor)
{
_accessor = accessor;
Schemes = schemes;
_sysRoleMenuServices = sysRoleMenuServices;
}
// 重写异步处理程序
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
var httpContext = _accessor.HttpContext;
if (!requirement.Permissions.Any())
{
var data = await _sysRoleMenuServices.RoleModuleMaps();
var list = new List<PermissionItem>();
if (Permissions.IsUseIds4)
{
list = (from item in data
orderby item.id
select new PermissionItem
{
Url = item.menu?.component,
RouteUrl = item.menu?.path,
Authority = item.menu?.authority,
Role = item.role?.id.ObjectToString(),
}).ToList();
}
else
{
list = (from item in data
orderby item.id
select new PermissionItem
{
Url = item.menu?.component,
RouteUrl = item.menu?.path,
Authority = item.menu?.authority,
Role = item.role?.roleCode,
}).ToList();
}
requirement.Permissions = list;
}
//请求Url
if (httpContext != null)
{
//
var questUrl = httpContext.Request.Path.Value.ToLower();
//判断请求是否停止
var handlers = httpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())
{
if (await handlers.GetHandlerAsync(httpContext, scheme.Name) is IAuthenticationRequestHandler handler && await handler.HandleRequestAsync())
{
context.Fail();
return;
}
}
//判断请求是否拥有凭据,即有没有登录
var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();
if (defaultAuthenticate != null)
{
var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);
//result?.Principal不为空即登录成功
if (result?.Principal != null)
{
httpContext.User = result.Principal;
// 获取当前用户的角色信息
var currentUserRoles = new List<string>();
// ids4和jwt切换
// ids4
if (Permissions.IsUseIds4)
{
currentUserRoles = (from item in httpContext.User.Claims
where item.Type == "role"
select item.Value).ToList();
}
else
{
// jwt
currentUserRoles = (from item in httpContext.User.Claims
where item.Type == requirement.ClaimType
select item.Value).ToList();
}
var isMatchRole = false;
var permisssionRoles = requirement.Permissions.Where(w => currentUserRoles.Contains(w.Role));
foreach (var item in permisssionRoles)
{
try
{
//权限中是否存在请求的url
if (Regex.Match(questUrl, item.Url.ObjectToString().ToLower()).Value == questUrl)
{
isMatchRole = true;
break;
}
}
catch (Exception)
{
// ignored
}
}
//验证权限
if (currentUserRoles.Count <= 0 || !isMatchRole)
{
context.Fail();
return;
}
var isExp = false;
// ids4和jwt切换
// ids4
if (Permissions.IsUseIds4)
{
isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) != null && DateHelper.StampToDateTime(httpContext.User.Claims.SingleOrDefault(s => s.Type == "exp")?.Value) >= DateTime.Now;
}
else
{
// jwt
isExp = (httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) != null && DateTime.Parse(httpContext.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Expiration)?.Value) >= DateTime.Now;
}
if (isExp)
{
context.Succeed(requirement);
}
else
{
context.Fail();
return;
}
return;
}
else
{
context.Fail();
return;
}
}
else
{
context.Fail();
return;
}
//判断没有登录时是否访问登录的url,并且是Post请求并且是form表单提交类型否则为失败
//if (!questUrl.Equals(requirement.LoginPath.ToLower(), StringComparison.Ordinal) && (!httpContext.Request.Method.Equals("POST") || !httpContext.Request.HasJsonContentType()))
//{
// context.Fail();
// return;
//}
}
context.Succeed(requirement);
}
}
}