【问题标题】:Validate JSON Web Token in .NET Core without usage of try/catch在 .NET Core 中验证 JSON Web 令牌而不使用 try/catch
【发布时间】:2019-11-14 11:57:05
【问题描述】:

我目前正在尝试按照以下answer 中建议的方式验证 JWT

这里是代码示例

try 
{
 tokenHandler.ValidateToken(token, validationParameters, out validatedToken);
} 
catch (Exception e) 
{
 log(e.ToString()); //something else happened
 throw;
}

如果没有 try/catch 子句,有没有更好的方法来实现这样的事情?对我来说,这似乎是一个非常混乱的解决方案,尤其是在将此功能连接到控制器时。

谢谢!

【问题讨论】:

  • 注意SecurityException的处理
  • @DanielA.White 这也是我目前正在捕捉的内容,为简单起见,在示例中将其省略了。只是想知道是否有更好的方法来实现这一点,因为捕获所有不同的SecurityException 变体(无效签名,过期......)似乎不是解决这个问题的最佳解决方案

标签: c# .net .net-core jwt


【解决方案1】:

Net Core 的奇妙之处在于它是内置的。您实际上不需要自己验证令牌。如果令牌无效,则会自动为您向客户端发送响应。但是,如果您确实觉得需要深入了解并手动验证 - 您可以这样做:https://www.jerriepelser.com/blog/manually-validating-rs256-jwt-dotnet/

好的,所以我从我的一个项目的内部挖出了一些代码。基本上,它让我可以连接到验证令牌时发生的事件,并将我自己的偶数处理程序分配给各个点。

我相信这就是你要找的。​​p>

将此代码添加到您的 IServiceCollection 注册中:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddCustomJwtBearer(options =>
        {
            options.TokenValidationParameters = tokenParams;
            options.Events = ConfigureJwtEvents(tokenConfiguration);
        });

并将此代码放入某个 STATIC 类中,以便您可以将其作为扩展方法调用:

public static void AddCustomJwtBearer(this AuthenticationBuilder builder, Action<JwtBearerOptions> options)
    {
        builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<JwtBearerOptions>, JwtBearerPostConfigureOptions>());
        builder.AddScheme<JwtBearerOptions, JwtBearerHandler>("Bearer", null, options);
    }


/// <summary>
/// Returns a configured <see cref="JwtBearerEvents"/>
/// </summary>
/// <param name="tokenConfiguration">Token Configuration</param>
/// <returns><see cref="JwtBearerEvents"/></returns>
private static JwtBearerEvents ConfigureJwtEvents(TokenConfiguration tokenConfiguration)
{
    var bearerEvents = new JwtBearerEvents
    {
        OnAuthenticationFailed = context =>
        {
            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
            {
                context.Response.Headers.Add("Token-Expired", "true");
            }

         return Task.CompletedTask;
        }
    };

    // Authentication Failed Method
    bearerEvents.OnAuthenticationFailed = [YOUR-EVENT-HANDLER]

    // Challenge Raised Event
    bearerEvents.OnChallenge = [YOUR-EVENT-HANDLER]

    // Message Received Event
    bearerEvents.OnMessageReceived = [YOUR-EVENT-HANDLER]

    // Token Validated Event
    bearerEvents.OnTokenValidated = [YOUR-EVENT-HANDLER]

    return bearerEvents;
}

上面写着:[YOUR-EVENT-HANDLER] ..您可以添加自己的事件处理程序方法,如果/当每个事件发生时它们将触发。

【讨论】:

  • 谢谢!这正是我现在正在做的事情,问题是ValidateToken 方法在令牌有效时返回ClaimsPrincipal,如果令牌无效则抛出SecurityTokenException,这对我来说似乎有点奇怪,因为我必须捕获异常才能得出令牌无效的结论。有什么想法可以绕过这个吗?
  • @user3024750 jwt 库是开源的。你当然可以扩展和定制它。
猜你喜欢
  • 1970-01-01
  • 2021-06-27
  • 1970-01-01
  • 2014-10-11
  • 2018-04-27
  • 2020-02-24
  • 1970-01-01
  • 1970-01-01
  • 2018-07-09
相关资源
最近更新 更多