MicroProfile JSON Web トークンの構成

認証トークンとして MicroProfile JSON Web トークンを受け入れるように Liberty サーバーを構成することができます。

始めに

mpJwt-1.0 フィーチャーまたは mpJwt-1.1 フィーチャーを使用するには、Java™ Platform, Standard Edition (Java SE) 8 以降をインストールします。

このタスクについて

MicroProfile JSON Web Token (MP-JWT) は、RFC 6750 仕様 The OAuth 2.0 Authorization Framework: Bearer Token Usageによって定義されているマイクロサービス要求 Authorization: Bearer ヘッダー内のベアラー・トークンとして JWT を使用することを定義する仕様です。

MP-JWT 1.0
MP-JWT 1.0 は、相互運用可能なトークン・フォーマットおよびトークン・アクセス API を定義し、以下の 3 つの部分で構成されます。
  • トークンのフォーマットおよびクレーム
  • org.eclipse.microprofile.jwt.JsonWebToken インターフェース。 これは、java.security.Principal インターフェースの拡張であり、このクレーム集合を get style アクセサーを介して使用可能にします。
  • JSON Web トークンおよびクレームから、さまざまな Java EE コンテナー・アプリケーション・プログラミング・インターフェース (API) へのマッピング
MP-JWT 1.0を使用すると、MP-JWT トークンを所有するトラステッド・パーティーは、許可ヘッダーを介してトークンを送信することにより、そのトークンを使用して Liberty 内の関連リソースにアクセスできます。 次の例に示すように、トークン・ワイヤー・フォーマットは RFC 6750 仕様に準拠していなければなりません。
GET /resource/1 HTTP/1.1
Host: example.com
Authorization: Bearer <MP-JWT token>
MP-JWT 1.0 仕様と API on GitHub ( JWT RBAC for MicroProfile ) および PDF 形式 ( Eclipse MicroProfile Interoperable JWT RBAC 1.1 仕様) を参照してください。
MP-JWT 1.1
MP-JWT 1.1 は、MicroProfile Config を使用するポータブル JWT 検証構成を定義し、JSON Web Key (JWK) のサポートを必要とします。 MP-JWT-1.1 仕様を参照してください。
Liberty は、MP-JWT 1.0 と 1.1の両方に対応しています。 Liberty リソース・サーバーは、MP-JWT トークンを検証し、認証済み JSON Web トークンを作成し、CDI 注入または JAX-RS セキュリティー・コンテキストを介して JSON Web トークンおよびトークン・クレームを使用可能にします。 JWT トークンは、MP-JWT トークンとして受け入れられるためには、クレームのリストを含んでいる必要があります。 以下は、MP-JWT トークンの例です。
{
    "typ": "JWT",
    "alg": "RS256",
    "kid": "abc-1234567890"
}
{
       "iss": "https://server.example.com",
       "aud": "s6BhdRkqt3",
       "jti": "a-123",
       "exp": 1311281970,
       "iat": 1311280970,
       "sub": "24400320",
       "upn": "jdoe@server.example.com",
       "groups": ["red-group", "green-group", "admin-group", "admin"],
}

手順

  1. mpJwt-1.0 フィーチャーまたは mpJwt-1.1 フィーチャー、およびその他の必要なフィーチャーを server.xml ファイルに追加します。
    少なくとも、mpJwt-1.0 フィーチャーには jaxrs-2.0 フィーチャーが必要です。

    mpJwt-1.1 フィーチャーには、mpJwt-1.0 が含まれており、mpConfig-1.3 または最新の MicroProfile Config フィーチャーが必要です。 mpJwt-1.1 がインストールされると、mpConfig-1.3 も自動的にインストールされます。

    <featureManager>
        <feature>mpJwt-1.1</feature>
        <feature>jaxrs-2.0</feature>
        <feature>cdi-1.2</feature>
        ...
    </featureManager>
    
  2. mpJwt エレメントを構成します。 mpJwt-1.0 フィーチャーを使用している場合、このステップは必須です。

    mpJwt-1.1 フィーチャーと一緒に mpConfig-1.3 またはそれ以降の MicroProfile Config フィーチャーを使用している場合、この mpJwt 構成ステップはオプションです。 代わりに、MP-JWT 1.1 のプロパティーを使用して JWT 検証を構成することもできます。 ステップ 3 を参照してください。

    1. issuer 属性を追加します。 この属性には、Java Web トークン (JWT) 内の iss クレームと一致する値を入力します。
    2. JWT に aud クレームが含まれている場合は、 audiences 属性を追加します。 JWT 内の aud クレームの 1 つの値を含むこの属性の値を入力します。
    3. jwksUri 属性を追加します。 JSON Web キー (JWK) の URL に一致する、この属性の値を入力します。
      以下のコードは、JWK が指定された典型的な mpJwt 構成エレメントを示しています。
      <mpJwt 
           id="myMpJwt"
           jwksUri="https://example.com/api/jwk"
           issuer="https://example.com/api/v1"
           audiences="conferenceService">
      </mpJwt>
      
    4. Secure Sockets Layer (SSL) 構成の truststore ファイルに JWT 署名検証鍵を追加する場合は、 keyName 属性を追加します。
      keyName 属性は、truststore ファイル内の鍵別名を指定します。
      以下のコードで、サンプルの mpJwt 構成を示します。
      <mpJwt 
           keyName="mpJwtValidationKey"
           issuer="https://example.com/api/v1"
           audiences ="conferenceService">
      </mpJwt>
      
  3. JWT 検証用に MicroProfile Config を構成します。 mpJwt-1.1 フィーチャーを mpConfig-1.3 以降の MicroProfile Config フィーチャーと共に使用する場合は、MP-JWT 1.1 仕様の以下の 3 つのプロパティーを使用して JWT 検証を構成することができます。
    mp.jwt.verify.publickey
    MP-JWT 署名者の公開鍵の組み込み鍵素材を PKCS8 PEM または JWK(S) 形式で指定します。 見つからない場合は、mp.jwt.verify.publickey.location 値を確認します。
    mp.jwt.verify.publickey.location
    公開鍵の相対パスまたは完全 URL を指定します。 相対パスはすべて ClassLoader.getResource を使用してアーカイブ内で解決されます。 値が URL の場合、URL は new URL("...").openStream() を使用して解決されます。
    mp.jwt.verify.issuer
    MP-JWT に対して検証する、必要な iss クレーム値を指定します。
  4. Liberty サーバーが JWK エンドポイントへの SSL 接続を確立できるように、JWK エンドポイント証明書を組み込むように truststore ファイルを構成します。
    1. server.xml ファイル内の keystore エレメントで truststores を構成します。
    2. この truststore ファイルを参照するように SSL を構成します。
    3. SSL 構成をサーバーのデフォルト SSL 構成として設定するか、 mpJwt エレメントの sslRef 属性に truststore ID を指定します。
    4. JWT 発行者が JWK をサポートしておらず、JWT が X.509 証明書で署名されている場合は、 X.509 証明書を発行者から SSL 構成内の truststore ファイルにインポートします。
      詳しくは、 Liberty での SSL 通信の使用可能化を参照してください。
  5. オプション: MP-JWT 形式ではない JWT の認証サブジェクトに JWT クレームをマップするための規則を定義します。
    デフォルトでは、 プログラムは、セキュリティー・ロールのマッピングのために、upn クレームをユーザーのプリンシパル名および固有セキュリティー名として使用し、groups クレームをグループ名として使用します。 デフォルト・マッピングを変更するには、 userNameAttribute 属性を使用してユーザー・プリンシパルのクレームを選択し、 groupNameAttribute 属性を使用してグループ名のクレームを選択します。
  6. オプション: JAX-RS アプリケーションを使用して、API javax.ws.rs.core.SecurityContext.getUserPrincipal()を呼び出すことにより、 JsonWebToken getter にアクセスします。
    次の例では、ユーザー・プリンシパルが org.eclipse.microprofile.jwt.JsonWebToken API のインスタンスとしてキャストされていて、アプリケーションは JsonWebToken getter を介してすべてのクレームにアクセスできます。
    @GET
    @Path("/getGroups")
    public Set<String> getGroups(@Context SecurityContext sec) {
           Set<String> groups = null;
           Principal user = sec.getUserPrincipal();
           if (user instanceof JsonWebToken) {
                    JsonWebToken jwt = (JsonWebToken) user;
                    groups= = jwt.getGroups();
           }
           return groups;
    }
  7. オプション: 以下の例に示すように、JAX-RS アプリケーションを使用して、 Raw TypeClaimValuejavax.inject.Provider、および JSON-P の各タイプを介して org.eclipse.microprofile.jwt.JsonWebToken API を注入します。
    @RequestScoped
    public class JwtEndpoint {
           @Inject
           private JsonWebToken jwtPrincipal;
           @GET
           @Path("/getInjectedPrincipal")
           public String getInjectedJWT() {
              return  this.jwtPrincipal.getName();
           }
    }
  8. オプション: プログラムがプログラマチック・セキュリティーを実行し、サブジェクトから org.eclipse.microprofile.jwt.JsonWebToken API を取得できる場合は、 com.ibm.websphere.security.auth.WSSubject.getCallerPrincipal() API を使用します。
    現行のセキュリティー・コンテキストでは、サブジェクトには 2 つの java.security.Principal プリンシパルが含まれています。 1 つのプリンシパルが JSON Web トークンです。
  9. オプション: アノテーションおよび JWT のグループ・クレームを使用して JAX-RS リソースを保護します。 @RolesAllowed アノテーションで使用されるセキュリティー・ロール名を、JWT のグループ・クレーム内のグループ名にマップします。
    ロール名とグループ名が同じ場合、 application-bnd エレメントのロール・マッピング を省略することができます。 ただし、JWT がグループ情報を含む MP-JWT の場合は、 application-bnd エレメントにマップして、ロールとグルー プの関連付けを宣言します。 詳しくは、 アノテーションを使用した JAX-RS リソースの保護アクセス ID と許可、および ロール・マッピング・バインディングが提供されていない場合のアプリケーションの許可を参照してください。
  10. オプション: 構成された Liberty ユーザー・レジストリーに対して JWT からのユーザー・プリンシパル名を検査するように Liberty を構成します。

    デフォルトでは、本プログラムは、セキュリティー・サブジェクトを、ユーザー・レジストリーを必要とせずに、検証された JWT から直接作成します。 この動作を変更するには、 server.xml ファイルに mapToUserRegistry="true" 構成属性を追加します。 本プログラムは、構成されたユーザー・レジストリーに照らしてプリンシパル名を検索し、ユーザー・レジストリーからのユーザー属性に基づいてセキュリティー・サブジェクトを作成します。

  11. オプション: ログイン・メソッド名が MP-JWT であるアプリケーションにのみ mpJwt-1.0 フィーチャーを適用するように Liberty を構成します。
    デフォルトでは、mpJwt-1.0 フィーチャーが構成されている場合、すべての許可された要求では HTTP ヘッダー内に有効な JWT が含まれている必要があります。 一部のアプリケーションでのみ JWT 認証トークンを必要とするようにデフォルトの動作を変更するには、 server.xml ファイル内の <mpJwt> エレメントに ignoreApplicationAuthMethod="false" 構成属性を追加します。 次に、次の 2 つの方法のどちらかで、アプリケーションを構成します。
    • アプリケーションが、認証方式として MP-JWT ログイン・メソッドが宣言された @LoginConfig アノテーションを含みます。

      例えば、@LoginConfig(authMethod = "MP-JWT", realmName = "MP-JWT") などです。

    • アプリケーションの web.xml ファイルには、login-config エレメント内に MP-JWT 認証方式の宣言があります。

      例えば、<login-config> <auth-method>MP-JWT</auth-method> <realm-name>MP-JWT</realm-name></login-config> などです。

  12. オプション: Liberty が他の JAX-RS サービスを呼び出すときに MP-JWT を認証トークンとして自動的に伝搬するように Liberty を構成します。

    Liberty が JAX-RS 2.0 クライアントとしても機能する場合は、 authnToken="mpjwt" ステートメントを <webTarget> 構成エレメントに追加します。 その後、 Liberty JAX-RS クライアントは、JAX-RS サービス呼び出しの許可ヘッダーとして JWT を自動的に追加します。 例えば、 <webTarget uri="http://localhost:56789/protectedResourceWithMPJWT*" authnToken="mpjwt" /> エレメントを server.xml ファイルに追加すると、 http://localhost:56789/protectedResourceWithMPJWT/ サービスの呼び出し時に JWT トークンが許可ヘッダーに追加されます。

  13. オプション: 認証フィルターを構成します。

    Liberty Security mpJwt-1.1 および mpJwt-1.0 は、アプリケーション・モジュール・ログイン方式をオーバーライドするサーバー全体の認証メカニズムです。 authFilter を構成して、アプリケーション・ログイン・メソッドへの mpJwt-1.x 機能の影響を制限することができます。 mpJwt-1.x フィーチャーの対象を要求のサブセットに制限するには、authFilter を構成して、要求のセットに関するルールを定義します。 <mpJwt...> エレメント内の authFilterRef 属性を、定義済みの authFilterに設定します。 詳しくは、 認証フィルターを参照してください。

    例えば、mpJwt-1.1 フィーチャーの対象を、/foo を含んでいる要求 URL のみに制限するには、以下のように authFilter を使用します。
    1. authFilter を作成し、名前を付けます。 以下の例は、mpJwtAuthFilter という名前です。
      <authFilter id="mpJwtAuthFilter">
        <requestUrl id="myRequestUrl" urlPattern="/foo" matchType="contains"/>
      </authFilter>
    2. <mpJwt> 構成エレメントに、 authFilterの名前に設定される authFilterRef 属性を追加します。
      <mpJwt authFilterRef="mpJwtAuthFilter" ....>