在C#中正确使用JwtTokens

14

我正在使用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的issuer更改为"x",它就会失败...


请查看 https://github.com/fvilers/WebApiOwinIdentityOAuthJwtSample 以获取正确的实现。 - Fabian Vilers
1
@FabianVilers 实现还不完整,验证过程中出现了问题,导致抛出异常。 - dariogriffo
2个回答

36

发现问题。验证参数具有默认的时钟偏移量为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); 但是没有起作用。 - PassionateProgrammer
1
我在TokenValidationParameters中设置了ClockSkew属性,没有使用配置文件,而是使用代码:var validationParameters = new TokenValidationParameters() { ... ClockSkew = new TimeSpan(0) }; - dariogriffo
4
@dariogriffo 我会使用TimeSpan.Zero来更简洁地处理,但这只是小题大作!感谢您提供的信息。我会看看它是否适用于我 :) - The Senator
@TheSenator,你说得对,感谢建议。 - dariogriffo
只是尝试和调试 :D - dariogriffo

1

这肯定能行

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

TokenValidationParameters parameters = new TokenValidationParameters()
{
  RequireExpirationTime = true,
  ValidateIssuer = false,
  ValidateAudience = false,
  ClockSkew= TimeSpan.FromSeconds(0)
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接