Oauth 2.0 MVC6应用程序中的OAuth令牌过期

Oauth 2.0 MVC6应用程序中的OAuth令牌过期,oauth-2.0,asp.net-core,jwt,identityserver3,Oauth 2.0,Asp.net Core,Jwt,Identityserver3,因此,我有一个MVC6应用程序,其中包括一个身份服务器(使用ThinkTecture的IdentityServer 3)和一个MVC6 web服务应用程序 在web服务应用程序中,我在启动时使用以下代码: app.UseOAuthBearerAuthentication(options => { options.Authority = "http://localhost:6418/identity"; options.AutomaticAuthentication = tr

因此,我有一个MVC6应用程序,其中包括一个身份服务器(使用ThinkTecture的IdentityServer 3)和一个MVC6 web服务应用程序

在web服务应用程序中,我在启动时使用以下代码:

app.UseOAuthBearerAuthentication(options =>
{
    options.Authority = "http://localhost:6418/identity";
    options.AutomaticAuthentication = true;
    options.Audience = "http://localhost:6418/identity/resources";
});
然后我有一个控制器,其操作具有
Authorize
属性

我有一个JavaScript应用程序,它通过identity server进行身份验证,然后使用提供的JWT令牌访问web服务操作

这是可行的,我只能使用有效的令牌访问操作

当JWT过期时,问题就出现了。我得到的是一个详细的ASP.NET 500错误页面,它返回以下异常的异常信息:

System.IdentityModel.Tokens.SecurityTokenExpiredException IDX10223:生存期验证失败。令牌已过期

一般来说,我对OAuth和保护Web API是相当陌生的,所以我可能有点离谱,但对于过期的令牌,500错误似乎并不适合我。对于web服务客户端来说,这绝对是不友好的


这是预期的行为吗?如果不是,我需要做些什么来获得更合适的响应吗?

编辑:此错误已在ASP.NET Core RC2中修复,不再需要此答案中描述的解决方法。


注意:此解决方案在ASP.NET 5 RC1上不起作用。您可以迁移到RC2夜间构建,也可以创建一个自定义中间件,用于捕获JWT承载中间件引发的异常并返回401响应:

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, throw an exception to close the connection.
        if (context.Response.HasStarted) {
            throw;
        }

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

不幸的是,这就是JWT/OAuth2承载中间件(由MSFT管理)目前默认的工作方式,但它最终应该得到修复。您可以查看此GitHub票证以了解更多信息:

幸运的是,您可以通过使用
AuthenticationFailed
通知“轻松”解决此问题:

app.UseOAuthBearerAuthentication(options => {
    options.Notifications = new OAuthBearerAuthenticationNotifications {
        AuthenticationFailed = notification => {
            notification.HandleResponse();

            return Task.FromResult<object>(null);
        }
    };
});
app.UseAuthBeareAuthentication(选项=>{
options.Notifications=新的OAuthBeareAuthenticationNotifications{
AuthenticationFailed=通知=>{
notification.HandleResponse();
返回Task.FromResult(空);
}
};
});

我也遇到了同样的问题。希望知道在哪里捕获异常并返回401。您是否仍然看到此问题以及建议的解决方案?请精确定位,谢谢您的回答。看看这个方法,它说调用方(我假设我)必须处理完整的响应。它已经神奇地触发了401计划。有没有一种方法可以在正文中以json的形式发送消息?虽然通常不鼓励这样做,但这是可能的。您可以/应该为此使用
ApplyChallenge
通知。噢,为什么不鼓励这样做?另外,我会同时使用这两个挑战还是只使用一个?因为对于HTTP,挑战已经在头级别完成了。OAuth2承载规范为此利用了标准的
WWW-Authenticate
头(您甚至可以设置自定义错误/error\u描述/error\u uri:)。当然,没有什么可以阻止您在响应正文中返回消息,但这将是多余的,而且显然是非标准的。我明白了。那么,如何为401设置自定义错误消息?我想这并不是必需的,但如果能够发送用户未经授权的原因,那会很有帮助。不是管理员,没有登录,不是在有效的客户端上。。。