JWT を扱うことは「安全な認証・権限管理を実務レベルで実装するための中心技術」です
読者のみなさんが Web API や業務システムを開発する際、 JWT(JSON Web Token)を安全に扱うことは必須のセキュリティ要件です。
JWT は次のような場面で使われます。
- API 認証
- シングルサインオン(SSO)
- モバイルアプリの認証
- 外部サービス連携
- 一時的なアクセス権の付与
ここでは、初心者でも理解できるように ステップバイステップで思考しながら、 実務で使える C# の JWT 生成・検証ユーティリティを丁寧に解説します。
JWT の基本構造を理解する
JWT は次の 3 つの部分で構成されています。
- Header(ヘッダー) どのアルゴリズムで署名するかを記述します。
- Payload(ペイロード) ユーザー ID や有効期限などの情報を含みます。
- Signature(署名) 改ざんされていないことを保証します。
例: xxxxx.yyyyy.zzzzz
この 3 つを Base64Url で連結したものが JWT です。
JWT を使う目的は「改ざんされない安全なトークンを作ること」
なぜ JWT が必要なのか
API トークンは「推測されない」だけでは不十分です。 攻撃者がトークンを盗んだり、書き換えたりする可能性があります。
JWT は次の特徴を持ちます。
- 改ざん防止(署名)
- 有効期限を持てる
- ペイロードに情報を埋め込める
- サーバー側で状態を持たない(ステートレス)
これらにより、API 認証を安全かつ効率的に実装できます。
C# で JWT を扱うためのライブラリを理解する
.NET では標準で JWT を扱うためのライブラリが用意されています。
- System.IdentityModel.Tokens.Jwt
- Microsoft.IdentityModel.Tokens
これらを使うことで、安全な JWT を生成・検証できます。
実務で使える JWT 生成ユーティリティ(テンプレート)
そのままコピペで使えるテンプレートです。
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
public static class JwtUtility
{
public static string GenerateJwt(string userId, string secretKey, int expireMinutes = 30)
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim("userId", userId),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var token = new JwtSecurityToken(
issuer: "your-app",
audience: "your-app",
claims: claims,
expires: DateTime.UtcNow.AddMinutes(expireMinutes),
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
public static ClaimsPrincipal ValidateJwt(string token, string secretKey)
{
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
var parameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "your-app",
ValidAudience = "your-app",
IssuerSigningKey = key
};
return new JwtSecurityTokenHandler().ValidateToken(token, parameters, out _);
}
}
C#JWT 生成の使い方(実務コード例)
string secretKey = "your-very-strong-secret-key-1234567890";
string jwt = JwtUtility.GenerateJwt("user123", secretKey);
Console.WriteLine(jwt);
C#JWT 検証の使い方(実務コード例)
var principal = JwtUtility.ValidateJwt(jwt, secretKey);
string userId = principal.FindFirst("userId")?.Value;
Console.WriteLine(userId);
C#JWT の有効期限を深掘りする
有効期限は短くするべき理由
JWT はステートレスであるため、 一度発行した JWT をサーバー側で無効化することができません。
そのため、有効期限を短くすることが重要です。
推奨値:
- 通常の API 認証:15〜30 分
- 高セキュリティ環境:5〜10 分
- リフレッシュトークン:数時間〜数日
JWT の署名アルゴリズムを理解する
HMAC(対称鍵方式)
HS256HS384HS512
特徴: 秘密鍵を共有する必要があるため、 単一サービス向け。
RSA / ECDSA(公開鍵方式)
RS256ES256
特徴: 公開鍵で検証できるため、 複数サービス間での認証に向いています。
JWT を扱う際の注意点(重要)
- 秘密鍵は絶対に漏らさない
- JWT は短期間で失効させる
- HTTPS を必ず使う
- JWT をログに出力しない
- ペイロードに機密情報を入れない
- リフレッシュトークンを併用する
これらを守らないと、攻撃者に突破されます。
実務的ベストプラクティス
- HS256 ではなく RS256 を使う(複数サービス連携時)
- 有効期限を短くする
- リフレッシュトークンを導入する
- ペイロードに最低限の情報だけを入れる
- 秘密鍵は KeyVault や環境変数で管理する
- JWT のブラックリスト機能を実装する場合は Redis を使う
まとめ:JWT は「安全な認証の中心技術」
JWT の本質は次の 3 つです。
- 改ざん防止(署名)
- ステートレスで高速
- 有効期限を持てる
これらを正しく扱うことで、 攻撃者がトークンを推測したり、改ざんしたりするのを極端に難しくできます。
読者のみなさんが業務システムを開発する際、 このユーティリティを使うだけでセキュリティレベルが大幅に向上し、 ユーザーの安全を確実に守ることができます。
