asp.net-core - asp.net核心中的可自定义授权属性
问题描述
我在 Asp.Net Core 中使用 Jwt Token 身份验证,为了进行身份验证,我正在使用内置属性[Authorize]
,我想做的是使该属性可自定义,这意味着我想让该属性可配置,以启用或禁用身份验证,我可以将设置放在appsetting.json
.
解决方案
根据您的描述,我建议您可以尝试使用基于策略的授权来实现您的要求。
我建议您可以编写一个自定义处理程序来比较 appsetting.json 值和路由值。
如果 appsetting.json 值包含请求路由值,那么您可以返回成功以避免身份验证。
更多细节,您可以参考以下代码:
Appseting.json(DisableAuthController 值)
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
},
"DisableAuthController": "home,default,account"
}
}
创建一个名为:UserResourceHandler 的新类
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Localization.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace FormAuthCore
{
public class UserResourceHandler : AuthorizationHandler<UserResourceRequirement>
{
private readonly IConfiguration Configuration;
private readonly IHttpContextAccessor _httpContextAccessor;
public UserResourceHandler(IConfiguration configuration, IHttpContextAccessor httpContextAccessor)
{
Configuration = configuration;
_httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
}
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext authHandlerContext, UserResourceRequirement requirement)
{
var re = Configuration.GetSection("DisableAuthController").Value;
var context = _httpContextAccessor.HttpContext.GetRouteData();
var area = (context.Values["area"] as string)?.ToLower();
var controller = (context.Values["controller"] as string)?.ToLower();
var action = (context.Values["action"] as string)?.ToLower();
if (re.Contains(controller))
{
authHandlerContext.Succeed(requirement);
}
}
}
}
创建一个 UserResourceRequirement 类
using Microsoft.AspNetCore.Authorization;
namespace FormAuthCore
{
public class UserResourceRequirement : IAuthorizationRequirement { }
}
将以下代码添加到 Startup.cs ConfigureServices 方法中:
services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
services.AddAuthorization(options =>
{
options.AddPolicy("UserResource", policy => policy.Requirements.Add(new UserResourceRequirement()));
});
services.AddScoped<IAuthorizationHandler, UserResourceHandler>();
为控制器启用基于策略的授权:
[Authorize(Policy = "UserResource")]
public class HomeController : Controller
更新:
我在startup.cs中添加了token1 jwt token auth
services.AddAuthentication("Token1")
.AddJwtBearer("Token1", options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidIssuer = "abc",
ValidateAudience = true,
ValidAudience = "abc",
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
};
options.Events = new JwtBearerEvents()
{
OnMessageReceived = context =>
{
var Token = context.Request.Headers["UserCred1"].ToString();
context.Token = Token;
return Task.CompletedTask;
},
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("UserResource", policy => policy.Requirements.Add(new UserResourceRequirement()));
});
services.AddScoped<IAuthorizationHandler, UserResourceHandler>();
然后我可以_httpContextAccessor.HttpContext.AuthenticateAsync("Token1").Result
用来检查令牌是否有效。
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext authHandlerContext, UserResourceRequirement requirement)
{
var re = Configuration.GetSection("DisableAuthController").Value;
var context = _httpContextAccessor.HttpContext.GetRouteData();
var re2 = _httpContextAccessor.HttpContext.AuthenticateAsync("Token1").Result;
var area = (context.Values["area"] as string)?.ToLower();
var controller = (context.Values["controller"] as string)?.ToLower();
var action = (context.Values["action"] as string)?.ToLower();
if (re.Contains(controller) || re2.Succeeded)
{
authHandlerContext.Succeed(requirement);
}
}
推荐阅读
- python - 在 Python 中使用 Pandas 处理嵌套的 JSON 数据
- ruby - 普通 Ruby:仅为 DateTime 实例设置时区
- javascript - javascript函数不显示html表
- sql - 仅当目标表中不存在该行时,如何将一个表中的行复制到另一个表中
- c++ - C++:有没有办法区分用户输入是否以厘米为单位?
- flutter - 如何使填充与颤动中的行对齐
- javascript - 我正在尝试使用 json 参数发送请求
- excel - 尝试将数据从一个工作簿复制到 Excel 中的另一个工作簿
- php - php回显json mysql列的空白数据表
- c# - 如何使变量只能在 C# 中设置一次?