關於 JWT,相信很多讀者應該都有聽說過,主要可以拿來做 SSO,它的簡介就不再多談,這邊主要聚焦在 ASP.NET Core 該如何使用。

在新增 ASP.NET Core 專案後,新增套件Microsoft.AspNetCore.Authentication.JwtBearer,這樣就能使用 JWT 的功能。

public class JwtHelpers
{
    private readonly IConfiguration Configuration;

    public JwtHelpers(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public string GenerateToken(string userName, int expireMinutes = 30)
    {
        //string issuer = Configuration.GetValue<string>("JwtSettings:Issuer");
        //string signKey = Configuration.GetValue<string>("JwtSettings:SignKey");
        string issuer = "JwtAuthDemo";
        string signKey = "1Zl4h9703IzROikK3@uK&&OEb";

        var claims = new List<Claim>();
        claims.Add(new Claim(JwtRegisteredClaimNames.Sub, userName)); // User Name
        claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())); // JWT ID
        claims.Add(new Claim("roles", "Admin"));

        ClaimsIdentity userClaimsIdentity = new ClaimsIdentity(claims);

        // 建立一組對稱式加密的金鑰,用於 JWT 簽章之用
        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signKey));

        // HmacSha256 必須要大於 128 bits,所以 key 不能太短,至少要 16 字元以上
        var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);

        // 建立 SecurityTokenDescriptor
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Issuer = issuer,
            Subject = userClaimsIdentity,
            Expires = DateTime.Now.AddMinutes(expireMinutes),
            SigningCredentials = signingCredentials
        };

        // 產出 JWT securityToken 物件後,取得序列化後的 Token
        var tokenHandler = new JwtSecurityTokenHandler();
        SecurityToken securityToken = tokenHandler.CreateToken(tokenDescriptor);
        string serializeToken = tokenHandler.WriteToken(securityToken);

        return serializeToken;
    }
}

上述程式就是產生 JWT 物件的一連串過程,然後產生最後的 Token 字串,之後這個字串就可以用做驗證的用途。

示範如下:

public string DecodeToken(string jwtToken)
{
    //var stream = jwtToken;
    //var handler = new JwtSecurityTokenHandler();
    //var jsonToken = handler.ReadToken(stream);
    //var tokenS = jsonToken as JwtSecurityToken;
    
    var handler = new JwtSecurityTokenHandler();
    var jwtSecurityToken = handler.ReadJwtToken(jwtToken);
    var jti = jwtSecurityToken.Claims.First(claim => claim.Type == "jti").Value;

    return jti;
}

參考資料