LoginSignup
1
0

AzureADB2CのJWTアクセストークン検証を行う

Last updated at Posted at 2024-03-25

大まかな流れ

  • AzureAdB2Cのopenid-configurationから関連するEndpointを取得する
  • jwks_uriの情報から公開鍵を生成する
  • JWTのアクセストークンを検証する

Endpointの取得

必要そうなのは、issuerとjwks_uri
Microosftのサンプルサイト

class OpenIdConfig
{
    public string issuer { get; set; }
    public string jwks_uri { get; set; }
}

private async Task<OpenIdConfig> GetEndPointAsync(string onfigureEndpointUrl)
{
    var result = await _httpClient.GetStringAsync(configureEndpointUrl);
    return JsonSerializer.Deserialize<OpenIdConfig>(result);
}

jwks_Uriから公開鍵の生成

Microosftのサンプルサイト

private async Task<Dictionary<string, RsaSecurityKey>> GetPublicKeyAsync(string jwksUri)
{
    //公開鍵キー情報を復元
    var jsonStr = await _httpClient.GetStringAsync(jwksUri);
    var sets = new JsonWebKeySet(jsonStr);

    //公開鍵生成(jwksUriには複数登録されているためDictionaryとする)
    var rsaProvider = new RSACryptoServiceProvider();

    var publicKeys = new Dictionary<string, RsaSecurityKey>();
    foreach (var key in sets.Keys)
    {
        rsaProvider.ImportParameters(new RSAParameters
        {
            Exponent = Base64UrlEncoder.DecodeBytes(key.E),
            Modulus = Base64UrlEncoder.DecodeBytes(key.N)
        });
        publicKeys.Add(key.Kid, new RsaSecurityKey(rsaProvider));
    }
    return publicKeys;
}

JWTのアクセストークン検証

private ClaimsPrincipal ValidToken(string token, string issuer, RsaSecurityKey publicKey)
{
    //とりあえずこれで、署名・発行者・期限の確認ができる
    var validationParams = new TokenValidationParameters
    {
        ValidIssuer = issuer,
        ValidateLifetime = true,
        IssuerSigningKey = publicKey,
    };
    var handler = new JwtSecurityTokenHandler();

    var claim = handler.ValidateToken(token, validationParams, out SecurityToken securityToken);
    return claim;
}

サンプル

※コストがかかるので、公開鍵の生成までは事前に行うこと

string accessToken = "ey~";
string config = "https://fabrikamb2c.b2clogin.com/fabrikamb2c.onmicrosoft.com/B2C_1_susi_reset_v2//v2.0/.well-known/openid-configuration";

//Endpointを取得する
var openIdConfig = await GetEndPointAsync(config);

//jwks_Uriから公開鍵の生成
var publicKeys = await GetPublicKeyAsync(openIdConfig.jwks_uri);

//JWTのアクセストークン検証
try
{
    ValidToken(accessToken, openIdConfig.issuer, publicKeys["xxxxxxxxx"]);
}
catch (SecurityTokenExpiredException)
{
    //期限切れ
}
catch(SecurityTokenInvalidSignatureException)
{
    //証明書誤り
}
catch (Exception)
{
    //その他
}

次回

JWT検証を使いやすいようにアトリビュートで実装したいと思います。
はたしてニーズはあるのか?!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0