asp.net

asp.net jwt 怎么进行令牌撤销

小樊
81
2024-11-29 00:55:33
栏目: 编程语言

在ASP.NET中,使用JWT(JSON Web Token)进行身份验证时,令牌撤销是一个重要的安全措施。以下是实现JWT令牌撤销的几种方法:

1. 使用短期Token

将JWT的过期时间设置得较短,例如几分钟或几小时。这样即使Token被泄露,攻击者也只能在有限的时间内使用它。

var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes("your_secret_key");
var tokenDescriptor = new SecurityTokenDescriptor
{
    Subject = new ClaimsIdentity(new Claim[]
    {
        new Claim(ClaimTypes.Name, "John Doe"),
        new Claim(ClaimTypes.Email, "john.doe@example.com")
    }),
    Expires = DateTime.UtcNow.AddMinutes(30),
    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);

2. 使用刷新Token

引入一个刷新Token的概念,用于在访问Token过期后获取新的访问Token。刷新Token应该存储在安全的地方,例如HttpOnly Cookie。

var refreshTokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes("your_refresh_secret_key");
var refreshTokenDescriptor = new SecurityTokenDescriptor
{
    Subject = new ClaimsIdentity(new Claim[]
    {
        new Claim(ClaimTypes.Name, "John Doe"),
        new Claim(ClaimTypes.Email, "john.doe@example.com")
    }),
    Expires = DateTime.UtcNow.AddDays(1),
    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var refreshToken = refreshTokenHandler.CreateToken(refreshTokenDescriptor);
var refreshTokenString = refreshTokenHandler.WriteToken(refreshToken);

3. 使用黑名单机制

维护一个黑名单,存储所有需要撤销的Token。每次验证Token时,首先检查该Token是否在黑名单中。

public class JwtTokenRevocationService
{
    private readonly IList<string> _revokedTokens = new List<string>();

    public void RevokeToken(string token)
    {
        _revokedTokens.Add(token);
    }

    public bool IsTokenRevoked(string token)
    {
        return _revokedTokens.Contains(token);
    }
}

在验证Token时,使用JwtTokenRevocationService检查Token是否被撤销:

public class JwtTokenValidator
{
    private readonly JwtTokenRevocationService _revocationService;

    public JwtTokenValidator(JwtTokenRevocationService revocationService)
    {
        _revocationService = revocationService;
    }

    public bool ValidateToken(string token)
    {
        if (_revocationService.IsTokenRevoked(token))
        {
            return false;
        }

        // 其他验证逻辑
        var tokenHandler = new JwtSecurityTokenHandler();
        try
        {
            var validationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key")),
                ValidateIssuer = false,
                ValidateAudience = false
            };
            var principal = tokenHandler.ValidateToken(token, validationParameters, out SecurityToken validatedToken);
            return principal != null;
        }
        catch (Exception ex)
        {
            // 处理异常
            return false;
        }
    }
}

4. 使用数据库或缓存

将需要撤销的Token存储在数据库或缓存中,以便快速查找和验证。

public class JwtTokenRevocationService
{
    private readonly IDatabaseContext _databaseContext;

    public JwtTokenRevocationService(IDatabaseContext databaseContext)
    {
        _databaseContext = databaseContext;
    }

    public void RevokeToken(string token)
    {
        _databaseContext.RevokedTokens.Add(new RevokedToken { Token = token, Expiry = DateTime.UtcNow });
        _databaseContext.SaveChanges();
    }

    public bool IsTokenRevoked(string token)
    {
        return _databaseContext.RevokedTokens.Any(rt => rt.Token == token);
    }
}

总结

以上方法各有优缺点,选择哪种方法取决于具体的应用场景和安全需求。短期Token、刷新Token和黑名单机制是比较常见的解决方案,而使用数据库或缓存则可以提供更高级别的安全性。

0
看了该问题的人还看了