【发布时间】:2017-10-13 05:45:00
【问题描述】:
我正在 ASP 上创建自己的自定义身份验证。部署在 Azure 上的 Net MobileService。我使用 JWT 令牌。以下是我生成新令牌的方式(claimType = email):
public static string GetSecurityToken(String email)
{
var symmetricKey = Convert.FromBase64String(signingKey);
var tokenHandler = new JwtSecurityTokenHandler();
var now = DateTime.UtcNow;
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Email, email)
}),
NotBefore = now,
Expires = now.AddYears(10),
Issuer = issuer,
Audience = audience,
IssuedAt = now,
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(symmetricKey),
SecurityAlgorithms.HmacSha256Signature),
};
var stoken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(stoken);
return token;
}
令牌被发送到客户端并存储。但是当我尝试根据其令牌授权消息时,我收到错误:
生命周期验证失败。令牌缺少过期时间。
这是我尝试验证令牌的方式:
public static ClaimsPrincipal GetPrincipal(string token)
{
try
{
var tokenHandler = new JwtSecurityTokenHandler();
var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;
if (jwtToken == null)
return null;
var symmetricKey = Convert.FromBase64String(signingKey);
Debug.WriteLine(String.Format("JWTManager > GetPrincipal > Validating Token: {0}", token));
foreach (Claim claim in jwtToken.Claims)
{
Debug.WriteLine(String.Format("JWTManager > GetPrincipal > Claims: {0}", claim.ToString()));
}
var validationParameters = new TokenValidationParameters()
{
//RequireExpirationTime = true,
//ValidateLifetime = true,
ValidateIssuer = true,
ValidateAudience = true,
IssuerSigningKey = new SymmetricSecurityKey(symmetricKey),
};
SecurityToken securityToken;
var principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);
if (principal != null)
Debug.WriteLine(String.Format("JWTManager > GetPrincipal > Principal: {0}", principal));
return principal;
}
catch (SecurityTokenException ex)
{
Debug.WriteLine(String.Format("JWTManager > GetPrincipal: {0}", ex.Message));
return null;
}
catch (Exception ex)
{
Debug.WriteLine(String.Format("JWTManager > GetPrincipal: {0}", ex.Message));
return null;
}
}
执行tokenHandler.ValidateToken时抛出异常,principal返回null。
我的假设是我可能没有正确设置 Expires 和 Issuers 属性,并且 TokenHanlder 无法验证它们。但是,当我检查 jwtToken 时,所有声明都已正确设置。
这是完整的调试输出:
JWTManager > GetPrincipal > 声明:电子邮件:testEmail@email.com
JWTManager > GetPrincipal > 声明:nbf:1494752301
JWTManager > GetPrincipal > 声明:exp:33051661101
JWTManager > GetPrincipal > 声明:iat:1494752301
JWTManager > GetPrincipal > 声明:ISS:MASKED
JWTManager > GetPrincipal > 声明:aud: MAKSED
JWTManager > GetPrincipal:IDX10225:生命周期验证失败。令牌缺少过期时间。应用:令牌类型:
【问题讨论】:
-
我认为你的EXP计算有问题,当我转换它时,结果是
Timestamp Converter 33051661101 Is equivalent to: 05/14/3017 @ 8:58am (UTC)(结果来自unixtimestamp.com/index.php)。也许验证不接受未来 1000 年的值? -
有趣。所以我现在应该切换。AddYears(10) 到别的东西。嗯……什么都想不起来。不是增加了 10 年,而是增加了 1000 年。
-
看看我的分析器:stackoverflow.com/questions/43593074/jwt-validation-fails/… 它解释了时间戳是如何定义的。
-
谢谢。它奏效了。
标签: asp.net authentication authorization jwt lifetime