在 C# 中正确使用 JwtTokens

Posted

技术标签:

【中文标题】在 C# 中正确使用 JwtTokens【英文标题】:Correct use of JwtTokens in C# 【发布时间】:2015-06-09 08:25:09 【问题描述】:

我正在使用 JwtTokens 并且无法使它们正常工作。 我正在使用http://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/。 我知道代码是一团糟,但只是为了展示我正在尝试做的事情。 问题是我希望 JwtTokenHandler 因为生命周期而无法通过验证。

var key = "5A0AB091-3F84-4EC4-B227-0834FCD8B1B4";
var domain = "http://localhost";
var allowedAudience = "http://localhost";
var signatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256";
var digestAlgorithm = "http://www.w3.org/2001/04/xmlenc#sha256";
var issuer = "self";
var securityKey = System.Text.Encoding.Unicode.GetBytes(key);
var inMemorySymmetricSecurityKey = new InMemorySymmetricSecurityKey(securityKey);

var now = DateTime.UtcNow;
var expiry = now.AddSeconds(1);
var tokenHandler = new JwtSecurityTokenHandler();
var claimsList = new List<Claim>()

    new Claim(ClaimTypes.Name, "user"),
    new Claim(ClaimTypes.Webpage, allowedAudience),
    new Claim(ClaimTypes.Uri, domain),                
    new Claim(ClaimTypes.Expiration,expiry.Ticks.ToString())
;
var roles = new List<string>()  "admin" ;
claimsList.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role)));

var identity = new GenericIdentity("user");

var tokenDescriptor = new SecurityTokenDescriptor

    Subject = new ClaimsIdentity(identity, claimsList),
    TokenIssuerName = issuer,
    AppliesToAddress = allowedAudience,
    Lifetime = new Lifetime(now, expiry),
    SigningCredentials = new SigningCredentials(inMemorySymmetricSecurityKey, signatureAlgorithm, digestAlgorithm),
;

var token = tokenHandler.WriteToken(tokenHandler.CreateToken(tokenDescriptor));

var validationParameters = new TokenValidationParameters()

    ValidIssuer = issuer,
    ValidAudience = allowedAudience,
    IssuerSigningToken = new BinarySecretSecurityToken(securityKey)
;

Thread.Sleep(2000);
try

    SecurityToken securityToken;
    tokenHandler.ValidateToken(token, validationParameters, out securityToken);
    Console.WriteLine("OK");

catch (Exception e)

    Console.WriteLine("Error 0", e.Message);

由于我等待 2 秒,这不是假设会失败吗? 如果我将 ValidationTokenParameter 的颁发者更改为“x”,它会失败...

【问题讨论】:

查看github.com/fvilers/WebApiOwinIdentityOAuthJwtSample 以获得正确的实现。 @F***Vilers 实现不完整,问题的验证正在引发异常。 【参考方案1】:

这肯定行得通

TimeSpan.FromSeconds(0) 将 ClockSkew 时间重置为零

TokenValidationParameters parameters = new TokenValidationParameters()

  RequireExpirationTime = true,
  ValidateIssuer = false,
  ValidateAudience = false,
  ClockSkew= TimeSpan.FromSeconds(0)
;

【讨论】:

【参考方案2】:

发现问题。 验证参数的默认时钟偏差为 5 分钟

/// <summary>
/// Default for the clock skew.
/// 
/// </summary>
/// 
/// <remarks>
/// 300 seconds (5 minutes).
/// </remarks>
public static readonly TimeSpan DefaultClockSkew;

将其设置为 0 使这项工作。 仍然不明白为什么倾斜是 5 分钟,如果我将到期时间设置在某个时间点!!!

【讨论】:

@dariogriffo,@Mitklantekutli 其实你是怎么把它设置为 0 的?我试过这样 tokenHandler.Configuration.MaxClockSkew = new TimeSpan(0, 0, 0);但不工作。 我在 TokenValidationParameters 中设置了 ClockSkew 属性,我不使用配置。我使用代码 var validationParameters = new TokenValidationParameters() ... ClockSkew = new TimeSpan(0) ; @dariogriffo 我会使用 TimeSpan.Zero 来获得更简洁的方法,但这只会让人毛骨悚然!感谢您提供此信息。看看它是否适合我:) @TheSenator 你是对的,谢谢你的建议 只是尝试和调试:D

以上是关于在 C# 中正确使用 JwtTokens的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中正确使用 WPF 绘制图表

如何使用 C# 在 OSX 中正确运行 chmod?

如何正确使用 SendInput() 在 C# 中模拟鼠标输入

如何在 C# 中使用 SHA2 正确签署 SOAP 消息?

在 C# 中释放内存的正确方法是啥

使用 pnp.core 和 pnp.framework 在 C# 中访问共享点文件夹和文件的正确方法是啥?