基于信号核心和策略的授权:资源始终为空

时间:2019-01-31 20:37:04

标签: asp.net-core signalr asp.net-core-signalr asp.net-authorization

Im使用Signalr核心,并与基于角色的授权一起使用。

另一方面,我的ClientIdHandler在带有[Authorize(Policy = "ClientIdPolicy")]的测试mvc控制器中工作正常,这是要求的代码:

public class ClientIdHandler : AuthorizationHandler<ClientIdRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                   ClientIdRequirement requirement)
    {
        if (!(context.Resource is AuthorizationFilterContext resource) || resource.HttpContext == null
            || resource.HttpContext.Request == null || resource.HttpContext.Request.Headers == null) return Task.CompletedTask;

        bool success = resource.HttpContext.Request.Headers.TryGetValue("ClientId", out var clientIdValue);
        if (!success) return Task.CompletedTask;

        if (!requirement.ClientIds.Contains(clientIdValue.ToString())) return Task.CompletedTask;

        context.Succeed(requirement);
        return Task.CompletedTask;
    }
}

在mvc控制器中,基于策略的授权有效,但在信号中心中则无效,因为context.Resource始终为null

这是信号器的问题,还是我做错了什么?

1 个答案:

答案 0 :(得分:0)

here确实是信号器的问题,解决方案是使用IHttpContextAccessor

这是ClientIdHandler的新代码,它在mvc控制器和Signalr集线器中均有效:

public class ClientIdHandler : AuthorizationHandler<ClientIdRequirement>
{
    private readonly IHttpContextAccessor _contextAccessor = null;

    public ClientIdHandler(IHttpContextAccessor contextAccessor)
    {
        _contextAccessor = contextAccessor;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                   ClientIdRequirement requirement)
    {
        if (_contextAccessor.HttpContext == null
            || _contextAccessor.HttpContext.Request == null || _contextAccessor.HttpContext.Request.Headers == null) return Task.CompletedTask;

        bool success = _contextAccessor.HttpContext.Request.Headers.TryGetValue("ClientId", out var clientIdValue);
        if (!success) return Task.CompletedTask;

        if (!requirement.ClientIds.Contains(clientIdValue.ToString())) return Task.CompletedTask;

        context.Succeed(requirement);
        return Task.CompletedTask;
    }
}