我有一种方法可以对用户进行身份验证并创建具有到期时间的令牌,但是如果令牌已过期,则用户将无法使用数据。该如何处理?
这是我的方法:
[AllowAnonymous]
[HttpPost]
[Route("api/token")]
public IActionResult Post([FromBody]Personal personal)
{
string funcionID = "";
if (ModelState.IsValid)
{
var userId = GetUser(personal);
if (!userId.HasValue)
{
return Unauthorized();
}
else if (userId.Equals(2)) {
return StatusCode(404, "Vuelve a ingresar tu contraseña");
}
List<Claim> claims = new List<Claim>();
foreach (var funcion in Funcion) {
claims.Add(new Claim(ClaimTypes.Role, funcion.FuncionID.ToString()));
}
claims.Add(new Claim(JwtRegisteredClaimNames.Email, personal.CorreoE));
claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()));
var sesionExpira = new DatabaseConfig();
_configuration.GetSection("Database").Bind(sesionExpira);
var token = new JwtSecurityToken
(
issuer: _configuration["Issuer"],
audience: _configuration["Audience"],
claims: claims,
expires: DateTime.UtcNow.AddMinutes(sesionExpira.Sesion),
notBefore: DateTime.UtcNow,
signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SigningKey"])),
SecurityAlgorithms.HmacSha256)
);
var token_email = token.Claims.Where(w => w.Type == "email").Select(s => s.Value).FirstOrDefault();
var token_rol = claims.Where(x => x.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role").Select(s => s.Value).FirstOrDefault();
var nombre = _context.Personal.Where(x => x.CorreoE == personal.CorreoE).Select(x => x.Nombre).FirstOrDefault();
return Ok(new { email = personal.CorreoE, token = new JwtSecurityTokenHandler().WriteToken(token), nombre = nombre, funcion = Funcion});
}
return BadRequest();
}
首先,在返回 int 的GetUser(Personal personal)方法中,我返回一个用于创建新令牌的数字。一切正常,但是如果时间到了,我需要一些信息来刷新令牌
答案 0 :(得分:2)
您可以创建将更新令牌的中间件。如果将令牌创建逻辑移至单独的服务,则可以执行以下操作:
package com.anish.spring.springorm1.product.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.anish.spring.springorm1.product.dao.ProductDao;
import com.anish.spring.springorm1.product.entity.Product;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"com/anish/spring/springorm1/product/test/config.xml");
ProductDao bean = (ProductDao) context.getBean("productDaoImpl");
Product product = new Product();
product.setId(1);
product.setName("Iphone");
product.setDesc("Its Good");
product.setPrice(21000.0);
bean.create(product);
}
}
并在Startup.cs中注册它:
public class JwtTokenSlidingExpirationMiddleware
{
private readonly RequestDelegate next;
private readonly ITokenCreationService tokenCreationService;
public JwtTokenSlidingExpirationMiddleware(RequestDelegate next, ITokenCreationService tokenCreationService)
{
this.next = next;
this.tokenCreationService= tokenCreationService;
}
public Task Invoke(HttpContext context)
{
// Preflight check 1: did the request come with a token?
var authorization = context.Request.Headers["Authorization"].FirstOrDefault();
if (authorization == null || !authorization.ToLower().StartsWith("bearer") || string.IsNullOrWhiteSpace(authorization.Substring(6)))
{
// No token on the request
return next(context);
}
// Preflight check 2: did that token pass authentication?
var claimsPrincipal = context.Request.HttpContext.User;
if (claimsPrincipal == null || !claimsPrincipal.Identity.IsAuthenticated)
{
// Not an authorized request
return next(context);
}
// Extract the claims and put them into a new JWT
context.Response.Headers.Add("Set-Authorization", tokenCreationService.CreateToken(claimsPrincipal.Claims));
// Call the next delegate/middleware in the pipeline
return next(context);
}
}
答案 1 :(得分:1)
我使用IdentityModel中的RefreshTokenAsync方法,做了与旧应用类似的操作。
您可以在用户遭到未经授权的情况下尝试以下操作:
var identityService = await DiscoveryClient.GetAsync("http://localhost:5000");
// request token
var tokenClient = new TokenClient(identityService.TokenEndpoint, "client", "secret");
var tokenResponse = await tokenClient.RequestRefreshTokenAsync(refreshToken);
return Ok(new { success = true, tokenResponse = tokenResponse });
来源:https://github.com/IdentityModel/IdentityModel.OidcClient.Samples/issues/4
编辑:我已经编辑了原始答案,以根据规则提供更清晰,更好的答案。