使用 AspNet.Security.OpenIdConnect.Server (ASP.NET vNext) 的自定义生命周期验证
Custom Lifetime Validation With AspNet.Security.OpenIdConnect.Server (ASP.NET vNext)
我正在使用 Visual Studio 2015 Enterprise Update 1 和 ASP.NET vNext rc1-update1 来发布和使用 JWT 令牌,如 所述。
在我们的实现中,我们希望控制令牌生命周期验证。
我们尝试了几种方法,所有方法都有不良副作用。例如,在一次尝试中,我们接管了 Configure 方法中的 TokenValidationParameters.TokenValidationParameters.LifetimeValidator 事件:
app.UseJwtBearerAuthentication
(
options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
LifetimeValidator = (DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters) =>
{
// Pretend to do custom validation
return false;
}
};
}
);
该事件导致验证失败,正如我们所希望的那样,但客户端收到一个 500 错误,而我们希望 return 一个 400 系列错误和一个小负载。
在另一次尝试中,我们尝试了 TokenValidationParameters.Events 的各种实现,例如检查 ValidatedToken 事件中的声明,但发现我们无法阻止中间件调用控制器操作,除非抛出异常,这让我们返回到 500 错误问题。
所以我的问题是:
使用 OIDC 接管生命周期验证的最佳实践是什么?
我们能否强制 OIDC 不在令牌中包含某些生命周期声明,例如 "nbf",因为我们无论如何都不需要它们?
编辑:此错误已在 ASP.NET Core RC2 中修复。不再需要此答案中描述的解决方法。
这是一个known bug. Sadly, no longer works in RC1。
您唯一的选择是编写一个捕获异常的中间件,以防止服务器返回 500 响应。当然,它很丑陋并且可能会隐藏重要的异常,但它是唯一已知的适用于 RC1 的解决方法。
举个例子(一定要在JWT承载中间件之前注册):
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;
}
});
我正在使用 Visual Studio 2015 Enterprise Update 1 和 ASP.NET vNext rc1-update1 来发布和使用 JWT 令牌,如
在我们的实现中,我们希望控制令牌生命周期验证。
我们尝试了几种方法,所有方法都有不良副作用。例如,在一次尝试中,我们接管了 Configure 方法中的 TokenValidationParameters.TokenValidationParameters.LifetimeValidator 事件:
app.UseJwtBearerAuthentication
(
options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
LifetimeValidator = (DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters) =>
{
// Pretend to do custom validation
return false;
}
};
}
);
该事件导致验证失败,正如我们所希望的那样,但客户端收到一个 500 错误,而我们希望 return 一个 400 系列错误和一个小负载。
在另一次尝试中,我们尝试了 TokenValidationParameters.Events 的各种实现,例如检查 ValidatedToken 事件中的声明,但发现我们无法阻止中间件调用控制器操作,除非抛出异常,这让我们返回到 500 错误问题。
所以我的问题是:
使用 OIDC 接管生命周期验证的最佳实践是什么?
我们能否强制 OIDC 不在令牌中包含某些生命周期声明,例如 "nbf",因为我们无论如何都不需要它们?
编辑:此错误已在 ASP.NET Core RC2 中修复。不再需要此答案中描述的解决方法。
这是一个known bug. Sadly,
您唯一的选择是编写一个捕获异常的中间件,以防止服务器返回 500 响应。当然,它很丑陋并且可能会隐藏重要的异常,但它是唯一已知的适用于 RC1 的解决方法。
举个例子(一定要在JWT承载中间件之前注册):
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;
}
});