自定义权限验证
自定义权限验证需要实现抽象类
public abstract class AuthorizationHandler<TRequirement> : IAuthorizationHandler where TRequirement : IAuthorizationRequirement
public abstract class AuthorizationHandler<TRequirement> : IAuthorizationHandler where TRequirement : IAuthorizationRequirement
{
protected AuthorizationHandler();
public virtual Task HandleAsync(AuthorizationHandlerContext context);
protected abstract Task HandleRequirementAsync(AuthorizationHandlerContext context, TRequirement requirement);
}
实现接口
IAuthorizationRequirement
//
// 摘要:
// Represents an authorization requirement.
public interface IAuthorizationRequirement
{
}
实现抽象类
public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
{
IMemoryCache memoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions()
{
// SizeLimit = 1000,
CompactionPercentage = 0.2,
}));
public IAuthenticationSchemeProvider Schemes;
/// <summary>
/// 构造函数注入
/// </summary>
public PermissionHandler(IAuthenticationSchemeProvider schemes)
{
Schemes = schemes;
List<PermissionItem> list = new List<PermissionItem>
{
new PermissionItem{ actionName ="Get", controllerName ="Users", Role ="User" },
new PermissionItem{ actionName ="Update", controllerName ="Users", Role ="User" },
};
memoryCache.Set<List<PermissionItem>>("permyyx", list);
}
// 重载异步处理程序
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
{
HttpContext httpContext1 = context.Resource as HttpContext;
ControllerActionDescriptor? actionDescriptor =
httpContext1.GetEndpoint().Metadata.Where(item => item is ControllerActionDescriptor)
.OfType<ControllerActionDescriptor>().FirstOrDefault();
AuthenticateResult result = await httpContext1.AuthenticateAsync(CustomerAuthenticationHandler.schemeName);
//var attributes = actionDescriptor.MethodInfo.GetCustomAttributes(inherit: true);
//bool isHaveAnonymous = attributes.Any(a => a.GetType().Name == "AllowAnonymousAttribute");
//bool isHaveAuthorize = attributes.Any(a => a.GetType().Name == "AuthorizeAttribute");
//如果没登录result.Succeeded为false
if (result.Succeeded)
{
httpContext1.User = result.Principal;
//当前访问的Controller
string controllerName = actionDescriptor.ControllerName;
//当前访问的Action
string actionName = actionDescriptor.ActionName;
string name = httpContext1.User.Claims.SingleOrDefault(s => s.Type == ClaimTypes.Name)?.Value;
string role = httpContext1.User.Claims.SingleOrDefault(s=>s.Type == ClaimTypes.Role)?.Value;
List<PermissionItem> lst = memoryCache.Get<List<PermissionItem>>("perm" + name);
if (lst.Where(w => w.controllerName == controllerName && w.actionName == actionName&&w.Role == role).Count() > 0)
{
//如果在配置的权限表里正常走
context.Succeed(requirement);
}
else
{
//不在权限配置表里 做错误提示
//如果是AJAX请求 (包含了VUE等 的ajax)
string requestType = httpContext1.Request.Headers["X-Requested-With"];//filterContext.HttpContext.Request.Headers["X-Requested-With"];
if (!string.IsNullOrEmpty(requestType) && requestType.Equals("XMLHttpRequest", StringComparison.CurrentCultureIgnoreCase))
{
//ajax 的错误返回
//filterContext.Result = new StatusCodeResult(499); //自定义错误号 ajax请求错误 可以用来错没有权限判断 也可以不写 用默认的
httpContext1.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
context.Fail();
}
else
{
//普通页面错误提示 就是跳转一个页面
//httpContext.Response.Redirect("/Home/visitDeny");//第一种方式跳转
//filterContext.Result = new RedirectToActionResult("visitDeny", "Home", null);//第二种方式跳转
httpContext1.Response.Redirect("/Home/visitDeny");//第一种方式跳转
context.Fail();
}
}
}
else
{
context.Fail();
}
}
}
权限许可验证要求
public class PermissionRequirement : IAuthorizationRequirement
{
/// <summary>
/// 无权限action
/// </summary>
public string DeniedAction { get; set; } = "/Home/visitDeny";
/// <summary>
/// 认证授权类型
/// </summary>
public string ClaimType { internal get; set; }
/// <summary>
/// 默认登录页面
/// </summary>
public string LoginPath { get; set; } = "/Home/Login";
/// <summary>
/// 过期时间
/// </summary>
public TimeSpan Expiration { get; set; }
/// <summary>
/// 构造
/// </summary>
/// <param name="deniedAction"></param>
/// <param name="claimType"></param>
/// <param name="expiration"></param>
public PermissionRequirement(string deniedAction, string claimType, TimeSpan expiration)
{
ClaimType = claimType;
DeniedAction = deniedAction;
Expiration = expiration;
}
}
许可项
public class PermissionItem
{
/// <summary>
/// 用户或角色或其他凭据名称
/// </summary>
public virtual string Role { get; set; }
/// <summary>
/// 配置的Controller名称
/// </summary>
public virtual string controllerName { get; set; }
/// <summary>
/// 配置的Action名称
/// </summary>
public virtual string actionName { get; set; }
}
注入
var permissionRequirement = new PermissionRequirement( "/Home/visitDeny",// 拒绝授权的跳转地址 ClaimTypes.Name,//基于用户名的授权 expiration: TimeSpan.FromSeconds(60 * 5)//接口的过期时间 ); builder.Services.AddAuthorization(options => { options.AddPolicy("Permission", policy => policy.Requirements.Add(permissionRequirement)); }); builder.Services.AddTransient<IAuthorizationHandler, PermissionHandler>();
浙公网安备 33010602011771号