ASP.NET Core 2.0 Web APIでJWTトークン生成が機能していますが、後続の新しいアクセストークンが以前に生成されたものと同じ期限になる問題が発生していますもの。新しいJWTトークンのトークンが古いトークンと同じです
たとえば、ログイン資格情報を掲示し、アクセストークンを返します。アクセストークンは[承認] APIエンドポイントで期待通りに機能します。テスト目的のために、1分後に期限切れになるようにトークンを設定します。 1分後、トークンは期限切れとなり、認証されたエンドポイントは、予想どおりに401を返します。
クライアント側のアプリケーションで401を処理しています。ログインフォームが表示され、ユーザーが再度ログインします。新しいトークンが生成され、返されます。この新しいトークンは、最初に生成されたトークンと全く同じ 'ValidTo' DateTimeを持ちます。
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:情報:検証に失敗しました。それは問題ではないですので、私は(予想、有効期限が切れたとしてトークン)間違ったトークン
最初のトークンの失敗を渡して、確認トークンeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZGFtQHBytNDRiYS1 ... Do1NzM5NS8ifQ.t8DjvlGV7GZ3xucwu-1hlJRXA5owPdP9t7kfYiiJHyQ。
Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException:IDX10223:有効期間の検証に失敗しました。トークンは期限切れです。
ValidTo:'11/08/2017年夜07時23分09' 秒
現在時刻:'11/08/2017年午前19時23' 分13秒。
セカンドトークンの失敗(期待できない、前のトークンと同じValidTo)
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:情報は:トークンeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZGFtQ ... dDo1NzM5NS8ifQの検証に失敗しました。 3。
Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException:IDX10223:有効期間の検証に失敗しました。トークンは期限切れです。
ValidTo:'11/08/2017年夜07時23分09' 秒
現在時刻:'11/08/2017年19時23分34' 秒。 Startup.csで
JWTの構成トークンが作成され
services.Configure<JwtIssuerOptions>(options => {
options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
options.SigningCredentials = new SigningCredentials(SigningKey, SecurityAlgorithms.HmacSha256);
options.ValidFor = TimeSpan.FromMinutes(1);
});
services.AddAuthentication(o =>
{
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
ValidateAudience = true,
ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
ValidateIssuerSigningKey = true,
IssuerSigningKey = SigningKey,
RequireExpirationTime = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
};
});
ログインアクション:
[HttpPost]
public async Task<IActionResult> Login([FromBody]CredentialsViewModel credentials)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var identity = await GetClaimsIdentity(credentials.UserName, credentials.Password);
if (identity == null)
{
return BadRequest(Errors.AddErrorToModelState("login_failure", "Invalid username or password.", ModelState));
}
// Serialize and return the response
var response = new
{
id = identity.Claims.Single(c => c.Type == "id").Value,
auth_token = await _jwtFactory.GenerateEncodedToken(credentials.UserName, identity),
expires_in = (int)_jwtOptions.ValidFor.TotalSeconds
};
var json = JsonConvert.SerializeObject(response, _serializerSettings);
return new OkObjectResult(json);
}
トークンが生成されている
JwtFactory方法:
private readonly JwtIssuerOptions _jwtOptions;
public JwtFactory(IOptions<JwtIssuerOptions> jwtOptions)
{
_jwtOptions = jwtOptions.Value;
ThrowIfInvalidOptions(_jwtOptions);
}
public async Task<string> GenerateEncodedToken(string userName, ClaimsIdentity identity)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, userName),
new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()),
new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(_jwtOptions.IssuedAt).ToString(), ClaimValueTypes.Integer64),
identity.FindFirst("rol"),
identity.FindFirst("id")
};
// Create the JWT security token and encode it.
var jwt = new JwtSecurityToken(
issuer: _jwtOptions.Issuer,
audience: _jwtOptions.Audience,
claims: claims,
notBefore: _jwtOptions.NotBefore,
expires: _jwtOptions.Expiration,
signingCredentials: _jwtOptions.SigningCredentials);
var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
return encodedJwt;
}
私のJwtIssuerOptionsモデルでは、有効期限はIssuedAt Datetimeをとり、ValidFor時間を自動的に追加するラムダです。 IssuedAtは単にモデル宣言のDateTime.UtcNowで初期化されます。したがって、私の場合は、ValidForのみを明示的に起動時に設定する必要があります。 JwtSecurityTokenはSystem.IdentityModel.Tokens.Jwt内のクラスであり、期限切れにはDateTimeが必要ですが、Timespanではなく、私が知っているのは – adam3039
です。そのため、私はその設定値から 'datetime'を作成しています –