正在尝试将我的 Web API 配置为资源服务器。我的客户端登录到 Auth0 并获取持有者令牌,因此授权服务器是 Auth0 而不是我的 API。然后他们将请求与持有者令牌一起发送到我的 API。在我的 ASP.Net Web API 中,我在启动类中实现了以下 OWIN 配置,以验证 Auth0 颁发的请求 JWT 持有者令牌,如此处的说明。
统计:
public class Startup
{
public void Configuration(IAppBuilder app)
{
var auth0Options = new Auth0Options()
{
Issuer = $"https://{ConfigurationManager.AppSettings["Auth0ApiInternalDomain"]}/",
Audience = ConfigurationManager.AppSettings["Auth0ApiInternalAudience"],
ClientId = ConfigurationManager.AppSettings["Auth0ApiInternalClientID"]
};
Auth0Config.Configure(app, auth0Options);
// Configure Web API
WebApiConfig.Configure(app);
}
}
和 Auth0Config 类:
public class Auth0Config
{
public static void Configure(IAppBuilder app, Auth0Options options)
{
if (options == null)
throw new ArgumentNullException(nameof(options));
var keyResolver = new OpenIdConnectSigningKeyResolver(options.Issuer);
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
{
AuthenticationMode = AuthenticationMode.Active,
TokenValidationParameters = new TokenValidationParameters()
{
ValidAudience = options.Audience,
ValidIssuer = options.Issuer,
IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) => keyResolver.GetSigningKey(identifier),
ValidateLifetime = true,
ValidateIssuer = true,
ValidateAudience = true,
LifetimeValidator = (DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters) =>
{
if (expires.Value < DateTime.UtcNow)
{
return false;
}
return true;
}
}
});
}
}
我将 Audience、Issuer 和 CliedntId 从我的 app.config 传递给此方法。我的目的是弄清楚从客户端到我的 API 的持有者令牌是否有效(作为第一步,我需要验证到期日期(。当我为传入请求调试代码时,LifetimeValidator工作正常,并为过期的令牌返回 false。我用 [授权] 装饰了我的操作,并期望收到 401 错误,但实际响应是 200,似乎它忽略了LifetimeValidator实现。
我的操作:
[Authorize]
public IHttpActionResult Get(string id)
{
var result = _bookingService.GetBooking(id);
if (result == null) return NotFound();
return Ok(result);
}
- 我是否错过了正确处理的东西?
- 这是验证令牌过期的好方法吗?
- 是否可以仅使用 OWIN 来验证已从 Web api 应用程序颁发的请求持有者令牌?
-
原来OwinMiddleware类的调用方法在我的应用程序中被覆盖,以从令牌中查找用户名并将其注入
Request.User
。不知道为什么,但不知何故它忽略了 OWIN 令牌验证功能,并且没有检查受众、颁发者或到期时间。public static void Configure(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); app.Use<HttpUsernameInjector>(); app.UseWebApi(config); } public class HttpUsernameInjector : OwinMiddleware { public HttpUsernameInjector(OwinMiddleware next) : base(next){} public override async Task Invoke(IOwinContext context) { const string usernameClaimKey = "myUserNameClaimKey"; var bearerString = context.Request.Headers["Authorization"]; if (bearerString != null && bearerString.StartsWith("Bearer ", StringComparison.InvariantCultureIgnoreCase)) { var tokenString = bearerString.Substring(7); var token = new JwtSecurityToken(tokenString); var claims = token.Claims.ToList(); var username = claims.FirstOrDefault(x => x.Type == usernameClaimKey); if (username == null) throw new Exception("Token should have username"); // Add to HttpContext var genericPrincipal = new GenericPrincipal(new GenericIdentity(username.Value), new string[] { }); IPrincipal principal = genericPrincipal; context.Request.User = principal; } await Next.Invoke(context); } }
通过删除此类,OWIN 令牌验证工作正常!
- 根据我的研究,Web API 中最好的令牌验证方法是OWIN和IAuthenticationFilter。
- 这是可能的,因为资源服务器和授权服务器已分离。更多信息可以在这里找到
更新
在这里找到解决方案以阻止Owin中间件抑制我的令牌验证逻辑