简体   繁体   English

如何在OWIN中间件中捕获SecurityTokenExpiredException?

[英]How to capture a SecurityTokenExpiredException in OWIN middleware?

I have a Web API with OWIN that uses JwtBearerAuthenticationOptions (.Net Framework 4.5.2) to validate authentication tokens. 我有一个使用JwtBearerAuthenticationOptions的Web API,该Web API使用JwtBearerAuthenticationOptions (.Net Framework 4.5.2)来验证身份验证令牌。

While following this excellent article by Rui Figueiredo in order to add a Refresh Token ability to the API, it seems I don't have JwtBearerEvents in OWIN. 而下面这个优秀的文章 ,以刷新令牌的能力加入到API由瑞·菲格雷多,看来我没有JwtBearerEvents在OWIN。 Eg This code works for me in ASP.NET Core (in ConfigureServices): 例如,此代码在ASP.NET Core(在ConfigureServices中)对我有用:

services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
    x.RequireHttpsMetadata = false;
    x.SaveToken = true;
    x.TokenValidationParameters = GetDefaultValidationParameters();
    x.Events = new JwtBearerEvents
    {
        OnAuthenticationFailed = context =>
        {
            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
            {
                context.Response.Headers.Add("Token-Expired", "true");
            }
            return Task.CompletedTask;
        }
    };
});

I can't seem to grasp how to achieve the same using the OWIN pipeline. 我似乎无法掌握如何使用OWIN管道实现相同的目标。 What I've tried is inserting a middleware in ConfigureAuth: 我试过的是在ConfigureAuth中插入中间件:

private static void ConfigureAuth(IAppBuilder pApp)
{
    pApp.Use(async (context, next) =>
    {
        try
        {
            await next.Invoke();
        }
        catch (SecurityTokenExpiredException)
        {
            context.Response.Headers.Add("Token - Expired", new[] { "true" });
            throw;
        }
    });
    var issuer = "issuer";
    var audience = "all";
    var key = Encoding.ASCII.GetBytes("MySecretKey");
    pApp.UseJwtBearerAuthentication(
        new JwtBearerAuthenticationOptions
        {
            AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
            AllowedAudiences = new[] { audience },
            IssuerSecurityKeyProviders = new IIssuerSecurityKeyProvider[]
            {
                new SymmetricKeyIssuerSecurityKeyProvider(issuer, key)
            },
            TokenValidationParameters = tokenValidationParameters,
            TokenHandler = new CustomJWTTokenHandler()
        });
}

But to no avail. 但无济于事。 The 401 status comes without the Token-Expired header in this case. 在这种情况下,401状态没有Token-Expired标头。

Does anybody have any pointers on how to do this properly in Katana? 是否有人在Katana中如何正确执行此操作的任何指示?

Solved it. 解决了。 Following the lead of these answers I added a custom authorization attribute to my base controller, ie: 遵循这些 答案之后,我向基本控制器添加了一个自定义授权属性,即:

public class CustomAuthorization : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        base.HandleUnauthorizedRequest(actionContext);
        var ctx = actionContext;
        var token = ctx.Request.Headers.Authorization.Parameter;
        var handler = new CustomJWTTokenHandler();
        if (ctx.Response.StatusCode == HttpStatusCode.Unauthorized && handler.TokenHasExpired(token))
        {
            ctx.Response.Headers.Add("Token-Expired", "true");
        }
    }
}

and implemented an expiration check in my CustomJWTTokenHandler class like this: 并在我的CustomJWTTokenHandler类中实现了过期检查,如下所示:

public bool TokenHasExpired(string tokenString)
{
    var token = ReadToken(tokenString);
    var hasExpired = token.ValidTo < DateTime.UtcNow;
    return hasExpired;
}

HTH HTH

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM