Я аутентифицирую клиента через токен JWT.Прежде всего, клиент отправляет запрос методу A с его учетными данными.Если клиент действителен, токен JWT отправляется клиенту.Этот токен действителен всего 2 минуты.Клиент должен отправить этот токен и некоторые другие данные методу B для завершения процесса.Теперь в дизайне произошли изменения.Я должен добавить другой метод для отмены / подтверждения.Клиент должен вызвать этот новый метод для завершения транзакции.Но для вызова этого нового метода клиент должен использовать токен JWT.Интересно, может ли клиент использовать токен JWT, который используется в методе B, если он не истек.ИЛИ есть ли способ повторно использовать один и тот же токен?Это возможно?Или каков предпочтительный или лучший метод в этой ситуации?
Я использую asp.net web api2 и создаю токен JWT следующим образом, и он работает нормально.
Вот обработчик:
internal class TokenValidationHandler : DelegatingHandler
{
private static bool TryRetrieveToken(HttpRequestMessage request, out string token)
{
token = null;
IEnumerable<string> authzHeaders;
if (!request.Headers.TryGetValues("Authorization", out authzHeaders) || authzHeaders.Count() > 1)
{
return false;
}
var bearerToken = authzHeaders.ElementAt(0);
token = bearerToken.StartsWith("Bearer ") ? bearerToken.Substring(7) : bearerToken;
return true;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpStatusCode statusCode;
string token;
//determine whether a jwt exists or not
if (!TryRetrieveToken(request, out token))
{
statusCode = HttpStatusCode.Unauthorized;
//allow requests with no token - whether a action method needs an authentication can be set with the claimsauthorization attribute
return base.SendAsync(request, cancellationToken);
}
try
{
const string sec = "zdRhpFvSSjdG9n7";
var now = DateTime.UtcNow;
var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
SecurityToken securityToken;
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
TokenValidationParameters validationParameters = new TokenValidationParameters()
{
ValidAudience = "http://111.111.111.111:1907/api/v3/token",
ValidIssuer = "http://111.111.111.111:1907/api/v3/token",
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
LifetimeValidator = this.LifetimeValidator,
IssuerSigningKey = securityKey
};
//extract and assign the user of the jwt
Thread.CurrentPrincipal = handler.ValidateToken(token, validationParameters, out securityToken);
HttpContext.Current.User = handler.ValidateToken(token, validationParameters, out securityToken);
return base.SendAsync(request, cancellationToken);
}
catch (SecurityTokenValidationException e)
{
statusCode = HttpStatusCode.Unauthorized;
}
catch (Exception ex)
{
statusCode = HttpStatusCode.InternalServerError;
}
return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(statusCode) { });
}
public bool LifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
{
if (expires != null)
{
if (DateTime.UtcNow < expires) return true;
}
return false;
}
}
Вот создание токена в контроллере:
public static string createToken(string username)
{
//Set issued at date
DateTime issuedAt = DateTime.UtcNow;
//set the time when it expires
DateTime expires = DateTime.UtcNow.AddMinutes(2);
var tokenHandler = new JwtSecurityTokenHandler();
//create a identity and add claims to the user which we want to log in
ClaimsIdentity claimsIdentity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, username)
});
const string sec = "zdRhpFvSSjdG9n7";
var now = DateTime.UtcNow;
var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
var signingCredentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(securityKey, Microsoft.IdentityModel.Tokens.SecurityAlgorithms.HmacSha256Signature);
//create the jwt
var token =
(JwtSecurityToken)
tokenHandler.CreateJwtSecurityToken(issuer: "http://111.111.111.111:1907/api/v3/token", audience: "http://111.111.111.111:1907/api/v3/token",
subject: claimsIdentity, notBefore: issuedAt, expires: expires, signingCredentials: signingCredentials);
var tokenString = tokenHandler.WriteToken(token);
return tokenString;
}
Как реализовать механизм обновления токена в моем коде?Не могли бы вы помочь?мне нужно обновить токен в моем scneario?
Вот мой сценарий:
В моей базе данных есть таблица пользователей, которая имеет идентификатор пользователя, имя пользователя, хэш,соль и пароль.
Клиент отправляет запрос методу A с предоставленным им идентификатором пользователя и паролем
Проверяется идентификатор пользователя и парольесли он действителен, токен доступа создан и отправлен в ответ.
Клиент отправляет запрос методу B для завершения процесса с данным токеном доступа.
Теперь в игру вступает другой метод (cancel-confim).
Для непосредственного вызова этого нового метода токен доступа не должен быть истек, верно?
Если срок действия маркера доступа истек, клиент должен сделать новый запрос на токен доступа, и, если клиент действителен, предоставляется новый токен доступа.Поскольку сервер resouce и aut одинаковые, я думаю, что мне не нужен механизм обновления токенов, верно?Я не видел никакой пользы от маркера обновления в моем сенарио.
Пожалуйста, поделитесь своими идеями?