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