【发布时间】:2020-06-09 14:08:27
【问题描述】:
我在 Asp.Net Core 中使用 Jwt Token 身份验证,为了进行身份验证,我使用内置属性[Authorize],我想要做的是让这个属性可定制,意味着我想让这个属性可配置,启用它或禁用身份验证,我可以将设置放在appsetting.json。
【问题讨论】:
标签: asp.net-core asp.net-web-api .net-core
我在 Asp.Net Core 中使用 Jwt Token 身份验证,为了进行身份验证,我使用内置属性[Authorize],我想要做的是让这个属性可定制,意味着我想让这个属性可配置,启用它或禁用身份验证,我可以将设置放在appsetting.json。
【问题讨论】:
标签: asp.net-core asp.net-web-api .net-core
根据您的描述,我建议您可以尝试使用基于策略的授权来实现您的要求。
我建议你可以编写一个自定义 Handler 来比较 appsetting.json 值和路由值。
如果 appsetting.json 值包含请求的路由值,那么你可以返回 Succeed 来避免 auth。
更多细节,您可以参考以下代码:
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);
}
}
【讨论】: