1. ホーム
  2. c#

[解決済み] 複数のJWTベアラ認証の使用

2022-07-30 16:08:36

質問

ASP.NET Core 2で複数のJWTトークン発行元をサポートすることは可能でしょうか? 外部サービスにAPIを提供したいのですが、FirebaseとカスタムJWTトークン発行者の2つのJWTトークンのソースを使用する必要があります。ASP.NET Coreでは、Bearer authスキームのJWT認証を設定することができますが、1つのAuthorityにのみ対応しています。

  services
        .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Authority = "https://securetoken.google.com/my-firebase-project"
            options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidIssuer = "my-firebase-project"
                    ValidateAudience = true,
                    ValidAudience = "my-firebase-project"
                    ValidateLifetime = true
                };
        }

発行者やオーディエンスを複数設定することはできますが、Authorityを複数設定することはできません。

どうすればよいですか?

あなたの望みを完全に実現することができます。

services
    .AddAuthentication()
    .AddJwtBearer("Firebase", options =>
    {
        options.Authority = "https://securetoken.google.com/my-firebase-project"
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = "my-firebase-project"
            ValidateAudience = true,
            ValidAudience = "my-firebase-project"
            ValidateLifetime = true
        };
    })
    .AddJwtBearer("Custom", options =>
    {
        // Configuration for your custom
        // JWT tokens here
    });

services
    .AddAuthorization(options =>
    {
        options.DefaultPolicy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .AddAuthenticationSchemes("Firebase", "Custom")
            .Build();
    });

あなたのコードとそのコードの違いを見ていきましょう。

AddAuthentication にはパラメータがありません。

デフォルトの認証スキームを設定すると、すべてのリクエストに対して、認証ミドルウェアはデフォルトの認証スキームに関連付けられた認証ハンドラを実行しようとします。現在、2つの可能な認証スキームがあるため、それらのうちの1つを実行することに意味はありません。

の別のオーバーロードを使用します。 AddJwtBearer

すべての AddXXX メソッドには、いくつかのオーバーロードがあります。

さて、同じ認証方法を2回使用しますが、認証スキームは一意でなければならないため、2番目のオーバーロードを使用する必要があります。

デフォルトのポリシーを更新する

リクエストはもう自動的に認証されないので、デフォルトのポリシーに [Authorize] 属性をつけると、リクエストが拒否され HTTP 401 が発行されます。

認証ハンドラにリクエストを認証する機会を与えたいので、これは私たちが望むことではありません。 FirebaseCustom 認証スキームは が試した を試みる必要があります。

だからといって、いくつかのアクションをより制限的にすることを妨げるわけではありません。 [Authorize] 属性には AuthenticationSchemes プロパティがあり、どの認証スキームが有効かを上書きすることができます。

より複雑なシナリオを作成する場合は ポリシーベースの認証 . 私は、公式のドキュメントが素晴らしいと思っています。

Firebaseが発行したJWTトークンにしか利用できないアクションがあり、特定の値を持つクレームが必要だと想像してみましょう。このようにすることができます。

// Authentication code omitted for brevity

services
    .AddAuthorization(options =>
    {
        options.DefaultPolicy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .AddAuthenticationSchemes("Firebase", "Custom")
            .Build();

        options.AddPolicy("FirebaseAdministrators", new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .AddAuthenticationSchemes("Firebase")
            .RequireClaim("role", "admin")
            .Build());
    });

次に [Authorize(Policy = "FirebaseAdministrators")] を使うことができます。

最後の注意点として、もしあなたが AuthenticationFailed イベントをキャッチし、最初の AddJwtBearer ポリシーを使用している場合は IDX10501: Signature validation failed. Unable to match key... これは、システムがそれぞれの AddJwtBearer を順番にチェックするために起こります。このエラーは通常無視することができます。