在我的asp.net核心Web API中,我想确保用户实际存在并且在调用某些操作时未停用。我们使用JwtBearer身份验证工作得很好。我们的问题是只使用Microsoft.AspNetCore.Authorization.AuthorizeAttribute
无关紧要,如果用户在发出令牌后被删除或停用(只要它自己的令牌有效)。
在我的Startup.cs
我配置了解决此问题的政策:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = AuthenticationHandler.TokenValidationParameters;
});
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder(
JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build();
options.AddPolicy(nameof(ExistingUserRequirement),
policy => policy.Requirements.Add(new ExistingUserRequirement()));
});
services.AddTransient<IAuthorizationHandler, ExistingUserHandler>();
如果用户存在且处于活动状态,我会查询DataContext。
什么有效:
如果我在动作上配置Authorization
属性,一切正常:
[HttpPost]
[Authorize(Policy = nameof(ExistingUserRequirement))]
public JsonResult Post([FromBody]CreateStoryViewModel viewModel) { ...}
我可以使用HttpContextAccessor.HttpContext.User.Identity.Name
访问请求用户身份。
不起作用:如果我在BaseController
上配置属性,ExistingUserHandler
启动时似乎缺少身份上下文:
[Authorize(Policy = nameof(ExistingUserRequirement))]
public abstract class BaseController : Controller { ... }
现在Identity.Name始终返回NULL
:
public class ExistingUserHandler : AuthorizationHandler<ExistingUserRequirement>
{
private IHttpContextAccessor HttpContextAccessor { get; }
private SaycleContext SaycleContext { get; }
public ExistingUserHandler(IHttpContextAccessor httpContextAccessor, SaycleContext saycleContext)
{
HttpContextAccessor = httpContextAccessor;
SaycleContext = saycleContext;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext authorizationContext, ExistingUserRequirement requirement)
{
var exists = false;
if (Guid.TryParse(HttpContextAccessor.HttpContext.User.Identity.Name, out var currentUserId))
{
exists = SaycleContext.Users.Any(u => Equals(u.Id, currentUserId));
}
if (!exists)
{
throw new NonExistingUserException();
}
authorizationContext.Succeed(requirement);
return Task.CompletedTask;
}
}
我错过了什么吗?为什么不能使用我父Authorize
上的BaseController
属性解析身份上下文?