UseJwtBearerAuthentication在令牌到期时返回HTTP 500

时间:2016-04-14 17:21:49

标签: asp.net-mvc asp.net-core jwt identityserver3

我正在使用像这样的UseJwtBearerAuthentication

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    SomeViewController *someVC = segue.destinationViewController; // no warning
    // ...
}

在visual studio的诊断窗口中,我看到了以下两个例外:

  System.IdentityModel.Tokens.dll中的

System.IdentityModel.Tokens.SecurityTokenExpiredException'(“IDX10223:生命周期验证失败。令牌已过期。

并在线下

  

抛出异常:Microsoft.AspNet.Authentication.dll中的“System.ArgumentNullException”(“值不能为空。”)

如何返回HTTP 401 Unauthorized?

1 个答案:

答案 0 :(得分:5)

这是一个known bug。遗憾的是,the workaround you could use in beta8不再有效in RC1

您唯一的选择是编写一个捕获异常的中间件,以防止服务器返回500响应。当然,它很丑陋,可能隐藏重要的异常,但它是唯一适用于RC1的已知解决方法。

以下是一个例子:

app.Use(next => async context =>
{
    try
    {
        await next(context);
    }

    catch
    {
        // If the headers have already been sent, you can't replace the status code.
        // In this case, re-throw the exception to close the connection.
        if (context.Response.HasStarted)
        {
            throw;
        }

        // Rethrow the exception if it was not caused by IdentityModel.
        if (!context.Items.ContainsKey("jwt-workaround"))
        {
            throw;
        }

        context.Response.StatusCode = 401;
    }
});

app.UseJwtBearerAuthentication(new JwtBearerOptions
{
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    RequireHttpsMetadata = false,

    Audience = "http://localhost:54540/",
    Authority = "http://localhost:54540/",

    Events = new JwtBearerEvents
    {
        OnAuthenticationFailed = context =>
        {
            context.HttpContext.Items["jwt-workaround"] = null;

            return Task.FromResult(0);
        }
    };
});