MVC6应用中的OAuth令牌到期 [英] OAuth token expiration in MVC6 app

查看:287
本文介绍了MVC6应用中的OAuth令牌到期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

app.UseOAuthBearerAuthentication(options =>
{
    options.Authority = "http://localhost:6418/identity";
    options.AutomaticAuthentication = true;
    options.Audience = "http://localhost:6418/identity/resources";
});

然后我有一个控制器,该控制器的动作具有Authorize属性.

我有一个使用身份服务器进行身份验证的JavaScript应用程序,然后使用提供的JWT令牌访问Web服务操作.

这行得通,我只能使用有效的令牌来访问操作.

JWT到期时出现问题.我得到的似乎是一个冗长的ASP.NET 500错误页面,该页面返回以下异常的异常信息:

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

对于OAuth和保护Web API而言,我通常还很陌生,所以我可能不太熟悉,但是对于过期的令牌,我似乎不适合遇到500个错误.对于Web服务客户端绝对不友好.

这是预期的行为吗?如果不是,是否需要做一些事情以获得更适当的响应?

解决方案

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


注意:此替代方法不适用于ASP.NET 5 RC1 https://github.com/aspnet/Security/issues /411

幸运的是,您可以使用AuthenticationFailed通知轻松"解决该问题:

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

            return Task.FromResult<object>(null);
        }
    };
});

So I have an MVC6 app that includes an identity server (using ThinkTecture's IdentityServer3) and an MVC6 web services application.

In the web services application I am using this code in Startup:

app.UseOAuthBearerAuthentication(options =>
{
    options.Authority = "http://localhost:6418/identity";
    options.AutomaticAuthentication = true;
    options.Audience = "http://localhost:6418/identity/resources";
});

Then I have a controller with an action that has the Authorize attribute.

I have a JavaScript application that authenticates with the identity server, and then uses the provided JWT token to access the web services action.

This works, and I can only access the action with a valid token.

The problem comes when the JWT has expired. What I'm getting is what appears to be a verbose ASP.NET 500 error page, that returns exception information for the following exception:

System.IdentityModel.Tokens.SecurityTokenExpiredException IDX10223: Lifetime validation failed. The token is expired.

I am fairly new to OAuth and securing Web APIs in general, so I may be way off base, but a 500 error doesn't seem appropriate to me for an expired token. It's definitely not friendly for a web service client.

Is this the expected behavior, and if not, is there something I need to do to get a more appropriate response?

解决方案

Edit: this bug was fixed in ASP.NET Core RC2 and the workaround described in this answer is no longer needed.


Note: this workaround won't work on ASP.NET 5 RC1, due to this other bug. You can either migrate to the RC2 nightly builds or create a custom middleware that catches the exceptions thrown by the JWT bearer middleware and returns a 401 response:

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;
    }
});


Sadly, that's how the JWT/OAuth2 bearer middleware (managed by MSFT) currently works by default, but it should be eventually fixed. You can see this GitHub ticket for more information: https://github.com/aspnet/Security/issues/411

Luckily, you can "easily" work around that by using the AuthenticationFailed notification:

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

            return Task.FromResult<object>(null);
        }
    };
});

这篇关于MVC6应用中的OAuth令牌到期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆