如何在 OWIN 中间件中捕获 SecurityTokenExpiredException?
How to capture a SecurityTokenExpiredException in OWIN middleware?
我有一个带有 OWIN 的 Web API,它使用 JwtBearerAuthenticationOptions
(.Net Framework 4.5.2) 来验证身份验证令牌。
在跟随 Rui Figueiredo 的 this excellent article 以向 API 添加刷新令牌功能时,我似乎在 OWIN 中没有 JwtBearerEvents
。例如。此代码适用于 ASP.NET 核心(在 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;
}
};
});
我似乎无法掌握如何使用 OWIN 管道实现相同的目的。我试过的是在 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()
});
}
但无济于事。在这种情况下,401 状态没有 Token-Expired header。
有人对如何在 Katana 中正确执行此操作有任何指示吗?
解决了。在 的带领下,我向我的基本控制器添加了一个自定义授权属性,即:
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");
}
}
}
并在我的 CustomJWTTokenHandler
class 中实施过期检查,如下所示:
public bool TokenHasExpired(string tokenString)
{
var token = ReadToken(tokenString);
var hasExpired = token.ValidTo < DateTime.UtcNow;
return hasExpired;
}
HTH
我有一个带有 OWIN 的 Web API,它使用 JwtBearerAuthenticationOptions
(.Net Framework 4.5.2) 来验证身份验证令牌。
在跟随 Rui Figueiredo 的 this excellent article 以向 API 添加刷新令牌功能时,我似乎在 OWIN 中没有 JwtBearerEvents
。例如。此代码适用于 ASP.NET 核心(在 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;
}
};
});
我似乎无法掌握如何使用 OWIN 管道实现相同的目的。我试过的是在 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()
});
}
但无济于事。在这种情况下,401 状态没有 Token-Expired header。
有人对如何在 Katana 中正确执行此操作有任何指示吗?
解决了。在
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");
}
}
}
并在我的 CustomJWTTokenHandler
class 中实施过期检查,如下所示:
public bool TokenHasExpired(string tokenString)
{
var token = ReadToken(tokenString);
var hasExpired = token.ValidTo < DateTime.UtcNow;
return hasExpired;
}
HTH