.NET Core JWT詳解

JWT(Json Web Token)是一種跨域的身份驗證解決方案,它可以在網路上安全地傳輸數據,用於在API之間進行身份驗證和授權。在.NET Core中,可以使用Microsoft.AspNetCore.Authentication.JwtBearer包來輕鬆地添加JWT身份驗證。本文將對.NET Core中的JWT進行詳細介紹,涵蓋以下主題:

一、安裝和配置JWT

在.NET Core中使用JWT需要安裝Microsoft.AspNetCore.Authentication.JwtBearer包。在項目中通過nuget包管理器或命令行中運行以下命令來安裝:

Install-Package Microsoft.AspNetCore.Authentication.JwtBearer

安裝後,在Startup.cs文件中的ConfigureServices方法中添加以下代碼:

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = Configuration["Jwt:Issuer"],
        ValidAudience = Configuration["Jwt:Audience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"]))
    };
});

該配置代碼將使.NET Core應用程序支持JWT身份驗證。首先,AddAuthentication方法設置JwtBearerDefaults身份驗證方案,這意味著授權策略將使用JWTBearerAuthenticationOptions類中的設置,JwtBearerDefaults身份驗證方案提供默認的jwt身份驗證選項。然後JwtBearer身份驗證選項分配了一個新的TokenValidationParameters實例,該實例定義了JWT識別配置的設置。例如,Validators被設置為true以執行身份驗證,ValidIssuer和ValidAudience設置為數據流需要進行身份驗證和簽名才能接受的發行方和受眾設置。最後,IssuerSigningKey被設置為應用的加密密鑰。

二、生成Token

生成JWT token對身份驗證和授權的有效性很重要,因為它使用戶可以訪問其資源和許可權。在.NET Core中,可以使用以下代碼生成JWT token:

public string GenerateToken(User user)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(Configuration["Jwt:SecretKey"]);

    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new Claim[]
        {
            new Claim(ClaimTypes.Name, user.Username),
            new Claim(ClaimTypes.Email, user.Email)
        }),
        Expires = DateTime.UtcNow.AddDays(7),
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
            SecurityAlgorithms.HmacSha256Signature)
    };

    var token = tokenHandler.CreateToken(tokenDescriptor);
    return tokenHandler.WriteToken(token);
}

上面的代碼將生成一個包含數據 and claims的JWT token。通過句柄類JwtSecurityTokenHandler將數據進行序列化操作,生成一個包含所有有效數據的JWT token。密鑰key的值是加密token內容的密鑰,Expires配置JWT tokens的有效截止日期,SymmetricSecurityKey將密鑰和SHA-256簽名演算法用於生成簽名。

三、使用JWT

在進行身份驗證時,首先需要從傳入的請求中提取JWT token,如下所示:

var authHeader = context.HttpContext.Request.Headers["Authorization"].FirstOrDefault();
var token = authHeader?.Split(" ").Last();

一旦獲取token後,需要進行身份驗證。使用以下代碼進行驗證:

var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(Configuration["Jwt:SecretKey"]);
try
{
    var tokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(key),
        ValidateIssuer = true,
        ValidIssuer = Configuration["Jwt:Issuer"],
        ValidateAudience = true,
        ValidAudience = Configuration["Jwt:Audience"],
        ValidateLifetime = true,
    };
    SecurityToken validatedToken;
    var claimsPrincipal = tokenHandler.ValidateToken(token, tokenValidationParameters, out validatedToken);
    context.HttpContext.User = claimsPrincipal;
}
catch(Exception e)
{
    Console.WriteLine(e.Message);
}

在上面的代碼中,我們使用了ValidateToken方法來驗證token的有效性。TokenValidationParameters對象定義了一些可能用於配置來自哪些發行者和受眾驗證令牌的屬性,令牌是否過期,簽名是否有效等。如果令牌驗證成功,將進行授權並返回用戶(ClaimsPrincipal對象),失敗將提示異常。

四、Token刷新

由於JWT tokens具有有效期的限制,為了避免過期問題,需要定期刷新accessToken。通過使用以下代碼來輕鬆處理JWT tokens的期限:

private async Task RefreshToken(string token, string refreshToken)
{
    var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(Configuration["Jwt:SecretKey"]);
    
    try
    {
        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = true,
            ValidIssuer = Configuration["Jwt:Issuer"],
            ValidateAudience = true,
            ValidAudience = Configuration["Jwt:Audience"],
            ValidateLifetime = false
        };
        SecurityToken validatedToken;
        var claimsPrincipal = jwtSecurityTokenHandler.ValidateToken(token, tokenValidationParameters, out validatedToken);
        if (validatedToken is JwtSecurityToken jwtSecurityToken && jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
        {
            var username = claimsPrincipal.Identity.Name;
            var user = await _userManager.FindByNameAsync(username);
            if (user == null)
            {
                return null;
            }

            var isValidated = await _userManager.CheckPasswordAsync(user, refreshToken);
            if (!isValidated)
            {
                return null;
            }

            var newToken = GenerateToken(user);
            return newToken;
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }

    return null;
}

在上面的代碼中,我們通過傳遞原始token和refreshToken驗證當前token是否過期,如果過期則通過GenerateToken方法生成新的token。與上一小節代碼的不同之處在於,這裡將ValidateLifetime設置為false,以便控制時間間隔並在過期時生成新token。

五、Token吊銷

在某些情況下,我們可能需要吊銷某個用戶的token。為了實現這個功能,我們必須通過添加一個吊銷列表,以記錄已被吊銷的token。從而驗證token時可以在吊銷列表中搜索。將吊銷列表添加到代碼中的步驟如下:

首先,需要添加一個TokenRevocationList和RefreshToken實體類。TokenRevocationList實體類包含一個Id欄位和一個Revoked欄位,而RefreshToken實體類包含一個Id和一個RefreshToken欄位。

public class TokenRevocationList
{
    public int Id { get; set; }
    public string Token { get; set; }       
    public DateTime Revoked { get; set; }
}

public class RefreshToken
{
    public int Id { get; set; }
    public string Token { get; set; }
    public DateTime Expires { get; set; }
}

然後,需要在Startup類中的ConfigureServices方法中配置DbContext,如下所示:

services.AddDbContext<YourDbContext>(options => options.UseSqlServer(Configuration["ConnectionString"]));

在進行身份驗證時,通過以下代碼添加TokenRevocationList檢查:

var tokenRevocationList = _context.TokenRevocationList.ToList();
if (tokenRevocationList.Any(x => x.Token == token))
{
    throw new SecurityTokenException("This token has been revoked");
}

最後,在註銷時將token添加到TokenRevocationList以吊銷token:

var tokenRevocationList = new TokenRevocationList
{
    Token = token,
    Revoked = DateTime.UtcNow
};

await _context.AddAsync(tokenRevocationList);
await _context.SaveChangesAsync();

結束語

本文介紹了.NET Core中使用JWT進行身份驗證的步驟。通過安裝並配置JWT包,生成token,使用token進行身份驗證,刷新token並吊銷token實現了應用程序的安全授權。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/288816.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-24 03:00
下一篇 2024-12-24 03:00

相關推薦

  • 解決.net 6.0運行閃退的方法

    如果你正在使用.net 6.0開發應用程序,可能會遇到程序閃退的情況。這篇文章將從多個方面為你解決這個問題。 一、代碼問題 代碼問題是導致.net 6.0程序閃退的主要原因之一。首…

    編程 2025-04-29
  • JWT驗證Token的實現

    本文將從以下幾個方面對JWT驗證Token進行詳細的闡述,包括:JWT概述、JWT驗證Token的意義、JWT驗證Token的過程、JWT驗證Token的代碼實現、JWT驗證Tok…

    編程 2025-04-29
  • JWT String Argument Cannot Be Null or Empty

    JWT(JSON Web Token)是一種用於進行身份驗證的標準。在使用JWT時,經常會遇到「JWT String Argument Cannot Be Null or Empt…

    編程 2025-04-27
  • 神經網路代碼詳解

    神經網路作為一種人工智慧技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網路的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網路模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁碟中。在執行sync之前,所有的文件系統更新將不會立即寫入磁碟,而是先緩存在內存…

    編程 2025-04-25
  • 詳解eclipse設置

    一、安裝與基礎設置 1、下載eclipse並進行安裝。 2、打開eclipse,選擇對應的工作空間路徑。 File -> Switch Workspace -> [選擇…

    編程 2025-04-25
  • Python安裝OS庫詳解

    一、OS簡介 OS庫是Python標準庫的一部分,它提供了跨平台的操作系統功能,使得Python可以進行文件操作、進程管理、環境變數讀取等系統級操作。 OS庫中包含了大量的文件和目…

    編程 2025-04-25
  • nginx與apache應用開發詳解

    一、概述 nginx和apache都是常見的web伺服器。nginx是一個高性能的反向代理web伺服器,將負載均衡和緩存集成在了一起,可以動靜分離。apache是一個可擴展的web…

    編程 2025-04-25
  • Linux修改文件名命令詳解

    在Linux系統中,修改文件名是一個很常見的操作。Linux提供了多種方式來修改文件名,這篇文章將介紹Linux修改文件名的詳細操作。 一、mv命令 mv命令是Linux下的常用命…

    編程 2025-04-25
  • git config user.name的詳解

    一、為什麼要使用git config user.name? git是一個非常流行的分散式版本控制系統,很多程序員都會用到它。在使用git commit提交代碼時,需要記錄commi…

    編程 2025-04-25

發表回復

登錄後才能評論