使用自定义异常处理程序使身份验证有效

时间:2019-03-01 07:55:46

标签: c# asp.net-core-2.0 asp.net-core-webapi

我正在寻找有关如何在ErrorController内处理401请求的方法,同时仍然具有[Authorize]属性。

配置了一个自定义的异常处理控制器:

public void Configure(IApplicationBuilder app)
{
    //..
    app.UseStatusCodePagesWithReExecute("/error/{0}");
    app.UseExceptionHandler("/error/500");
    //..
}

然后从外部组件加载控制器。它在内部进行一些日志记录和其他处理(为简单起见,删除了逻辑):

public class ErrorController : Controller
{
    [Route("error/{errCode}")]
    [HttpGet]
    public IActionResult Get(int errCode)
    {
        if (errCode == StatusCodes.Status500InternalServerError) 
        {
            return StatusCode(StatusCodes.Status500InternalServerError, null);
        }
        else if (errCode == StatusCodes.Status401Unauthorized)
        {
            return StatusCode(StatusCodes.Status401Unauthorized);
        }
        else
        {
            return BadRequest(null);
        }
    }
}

现在,我正在尝试为具有[Authorize]属性的其他控制器添加身份验证逻辑。为此,我进行了所有必要的配置并创建了自定义AuthenticationHandler。它检查令牌是否存在于HTTP标头中,然后接受还是拒绝身份验证。

        services.AddAuthentication("BasicAuthentication")
            .AddScheme<BasicAuthenticationOptions, BasicAuthenticationHandler>("BasicAuthentication", null);

public class BasicAuthenticationHandler : AuthenticationHandler<BasicAuthenticationOptions>
{
    public BasicAuthenticationHandler(
        IOptionsMonitor<BasicAuthenticationOptions> options,
        ILoggerFactory logger,
        UrlEncoder encoder,
        ISystemClock clock
        )
        : base(options, logger, encoder, clock)
    {
    }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        if (!Request.Headers.ContainsKey("Authorization"))
        {
            return AuthenticateResult.Fail("Missing Authorization Header");
        }

        var claims = new[] {
            new Claim(ClaimTypes.NameIdentifier, Response.Headers["Authorization"]),
            new Claim(ClaimTypes.Name, "test"),
        };
        var identity = new ClaimsIdentity(claims, Scheme.Name);
        var principal = new ClaimsPrincipal(identity);
        var ticket = new AuthenticationTicket(principal, Scheme.Name);

        return AuthenticateResult.Success(ticket);
    }
}

代码被简化以节省一些空间。

所以我当前的问题是-现在我无法将[Authorize]属性添加到错误控制器。因为当我添加它时-我无法在其中处理401请求。

另一方面-如果我不添加它-则该控制器可公开用于未经授权的访问。我正在寻找有关如何在ErrorController内处理401请求的方法,同时仍然具有[Authorize]属性。

我想到的

1个想法是-仅从WebAPI服务本身内部使ErrorController可调用。有没有一种方法可以限制从公众对ErrorController的访问,从而可以进行内部调用而不能进行外部请求?

正在寻找建议。

0 个答案:

没有答案