【发布时间】:2018-05-02 01:09:28
【问题描述】:
我正在开发 mob 应用后端,并且正在使用 JWT。我的问题是它提前到期,我想我设置了 365 天。我在VS2015中使用asp.net core mvc v1。
这是我的 JWT 身份验证配置。该方法是从 Startup 类中调用的。
private void ConfigureAuth(IApplicationBuilder app)
{
secretKey = Guid.NewGuid().ToString();
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));
app.UseSimpleTokenProvider(new TokenProviderOptions
{
Path = "/api/token",
Audience = Audience,
Issuer = Issuer,
SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),
IdentityResolver = GetIdentity,
});
var tokenValidationParameters = new TokenValidationParameters
{
// The signing key must match!
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
// Validate the JWT Issuer (iss) claim
ValidateIssuer = true,
ValidIssuer = Issuer,
// Validate the JWT Audience (aud) claim
ValidateAudience = true,
ValidAudience = Audience,
// Validate the token expiry
ValidateLifetime = true,
// If you want to allow a certain amount of clock drift, set that here:
ClockSkew = TimeSpan.Zero
};
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = tokenValidationParameters
});
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AutomaticAuthenticate = true,
AutomaticChallenge = true,
AuthenticationScheme = "Cookie",
CookieName = "access_token",
TicketDataFormat = new CustomJwtDataFormat(SecurityAlgorithms.HmacSha256, tokenValidationParameters),
Events = new CustomCookieAuthenticationEvents()
});
}
private Task<ClaimsIdentity> GetIdentity(string email)
{
ServiceMessage<UserEntity> request = _userService.FindByEmailAsync(email).Result;
if (request != null && request.Success && request.ResultObject != null)
{
return Task.FromResult(CreateClaimsIdentity(request.ResultObject, "Token"));
}
// Credentials are invalid, or account doesn't exist
return Task.FromResult<ClaimsIdentity>(null);
}
private ClaimsIdentity CreateClaimsIdentity(UserEntity user, string authenticationType)
{
List<Claim> claimCollection = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, user.Email, ClaimValueTypes.String),
new Claim(ClaimTypes.Role, user.Role, ClaimValueTypes.String),
new Claim(ClaimTypes.Name, user.Email.Split('@')[0], ClaimValueTypes.String),
new Claim(ClaimTypes.Expiration, TimeSpan.FromDays(365).ToString(), ClaimValueTypes.DaytimeDuration)
};
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claimCollection, authenticationType);
return claimsIdentity;
}
在我的令牌提供程序中间件中,我像这样生成 JWT:
DateTime now = DateTime.Now;
// Specifically add the jti (nonce), iat (issued timestamp), and sub (subject/user) claims.
// You can add other claims here, if you want:
Claim[] claims = new Claim[]
{
new Claim(ClaimTypes.Name,validation.ResultObject.Email,ClaimValueTypes.String),
new Claim(JwtRegisteredClaimNames.Email, validation.ResultObject.Email),
new Claim(JwtRegisteredClaimNames.Aud, Audience),
new Claim(JwtRegisteredClaimNames.Iss, issuer),
new Claim(JwtRegisteredClaimNames.Typ, validation.ResultObject.Role),
new Claim(JwtRegisteredClaimNames.Jti, await _options.NonceGenerator()),
new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(now).ToString(), ClaimValueTypes.Integer64),
new Claim(ClaimTypes.Role, "user")
};
// Create the JWT and write it to a string
JwtSecurityToken jwt = new JwtSecurityToken
(
issuer: _options.Issuer,
audience: _options.Audience,
claims: claims,
notBefore: now,
expires: now.Add(_options.Expiration),
signingCredentials: _options.SigningCredentials
);
string encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);
var response = new
{
access_token = encodedJwt,
expires_in = (int)_options.Expiration.TotalSeconds
};
// Serialize and return the response
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonConvert.SerializeObject(response, _serializerSettings));
_options 是下一个类:
public class TokenProviderOptions
{
/// <summary>
/// The relative request path to listen on.
/// </summary>
/// <remarks>The default path is <c>/token</c>.</remarks>
public string Path { get; set; } = "api/token";
/// <summary>
/// The Issuer (iss) claim for generated tokens.
/// </summary>
public string Issuer { get; set; }
/// <summary>
/// The Audience (aud) claim for the generated tokens.
/// </summary>
public string Audience { get; set; }
/// <summary>
/// The expiration time for the generated tokens.
/// </summary>
/// <remarks>The default is five minutes (300 seconds).</remarks>
public TimeSpan Expiration { get; set; } = TimeSpan.FromDays(360);
/// <summary>
/// The signing key to use when generating tokens.
/// </summary>
public SigningCredentials SigningCredentials { get; set; }
/// <summary>
/// Resolves a user identity given a username and password.
/// </summary>
public Func<string, Task<ClaimsIdentity>> IdentityResolver { get; set; }
/// <summary>
/// Generates a random value (nonce) for each generated token.
/// </summary>
/// <remarks>The default nonce is a random GUID.</remarks>
public Func<Task<string>> NonceGenerator { get; set; } = new Func<Task<string>>(() => Task.FromResult(Guid.NewGuid().ToString()));
一段时间后我收到错误消息,但仍然不知道出了什么问题。 错误信息是:
WWW-Authenticate:Bearer error="invalid_token", error_description="The 签名无效”
如果您需要,我可以提供更多代码。 谢谢
【问题讨论】:
-
DateTime.Add将TimeSpan作为参数。在您的情况下,_options.Expiration等于什么? -
R.Richards:我为您更新了问题,以向您展示 _option 是什么。它是一个设置为 365 天的 TimeSpan。
标签: c# asp.net asp.net-core-mvc jwt