Oracle Cloud Hangout Cafe Season4 #4「マイクロサービスの認証・認可とJWT」(2021年7月7日開催)

2023年2月17日(金)
川村 修平
連載第2回の今回は、2021年7月7日に開催された「Oracle Cloud Hangout Cafe Season4 #4『マイクロサービスの認証・認可と JWT』」の発表内容に基づいて紹介していきます。

MP-JWTに含まれる標準的なクレーム(Payload)

ペイロードに含まれる標準クレームは、下表のようになっています(*: 必須項目)。

claim name description
* iss Issue Identifier: ID Token の発行者
* iat Issuer At: JWT の発行時刻
* exp Expiration Time: ID Token の有効期限
* upn User Principal Name: End-User の識別子(Human Readable)
sub Subject Identifier: End-User の識別子
jti JWT ID: JWT の識別子
aud Audience: ID Token の発行対象で、OAuth 2.0 の client_id を含む必要がある
groups End-User に割り当てられているグループ名のリスト

標準的なIDトークンとの差分としてはupn、groupsが挙げられますが、それぞれ必須というわけではなく、別のクレームを用いたり、カスタムマッパーを作成することで代用できます。

MP-JWT検証の要件

次に、MP-JWTの検証に必要な要件を記載します。

  1. JOSE alg ヘッダーが含まれていること
    • 暗号化された MP-JWT を期待する場合には、さらに JOSE enc ヘッダーが含まれていること
  2. iss クレームが含み、期待通りの iss であること
  3. iat、exp クレームを含み、そこから計算される有効期限が有効であること
  4. upn、preferred_username、sub のうち少なくとも 1 つのクレームを含み、期待通りであること

MP-JWTを用いてJakarta RESTful Web ServicesアプリケーションでRBACをする

MP-JWTを用いて、Jakarta RESTful Web Services(以下、Jakarta REST)アプリケーションでRBACをするために必要な設定周りを記載します。

まずは、jakarta.ws.rs.core.Applicationを拡張したクラスに@LoginConfig(authMethod="MP-JWT")というアノテーションが必要です。具体的には以下のように実装します。

import org.eclipse.microprofile.annotation.LoginConfig;
import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;

@LoginConfig(authMethod = "MP-JWT", realmName = "TCK-MP-JWT")
@ApplicationPath("/")
public class TCKApplication extends Application {

}

また、アプリケーションの設定ファイル(application.yaml/microprofile-config.properties)に、IssuerやJWTの検証に用いる公開鍵の所在を定義します。

# configure JWT handling
mp.jwt.verify.issuer: https://server.example.com
mp.jwt.verify.publickey.location: publicKey.pem

アプリケーション内でMP-JWTを使うには以下のようにします。まずは、CDIによりJsonWebToken全体のインスタンスをインジェクションするか、個別のクレームをインジェクションするか選択します。

【MP-JWT全体をインジェクションするパターン】
@Path("/endp")
@DenyAll
@ApplicationScoped
public class RolesEndpoint {
    @Inject
    private JsonWebToken jwt;
    // ...
}
【MP-JWTの一部のクレームをインジェクションするパターン】
@ApplicationScoped
public class MyEndpoint {
    @Inject
    @Claim(value="exp", standard=Claims.iat)
    private Long timeClaim;
    // ...
}

また、jakarta.ws.rs.core.SecurityContextでも、いくつかAPIが用意されています。

// org.eclipse.microprofile.jwt.JsonWebToken のインスタンスが返却される
jakarta.ws.rs.core.SecurityContext.getUserPrincipal()

// 渡した文字列が MP-JWT groups に含まれるかどうかを確認する
jakarta.ws.rs.core.SecurityContext.isUserInRole(String role)

次に、Jakarta RESTのエンドポイントに対して、RBAC制御を行うためのアノテーションを紹介します。

jakarta.annotation.security.RolesAllowedは、エンドポイントのアクセスに必要なロールを記載します。MP-JWT groupsクレームに指定した文字列が少なくとも1つ含まれていれば、このエンドポイントの実行を認可します。

public class MyEndpoint {

    @RolesAllowed({"Admin", "Guest"})
    public String greet() { 
        return "Hello, world"; 
    }
}

また、エンドポイント全体の制御として、jakarta.annotation.security.PermitAllや jakarta.annotation.security.DenyAllといったアノテーションも存在します。

【jakarta.annotation.security.PermitAll】
// MyEndpoint に定義したすべてのエンドポイントの実行を認可します
@PermitAll
public class MyEndpoint {
  public String greet1() { return "Hello, world"; }
  public String greet2() { return "Hello, world"; }
}
【jakarta.annotation.security.DenyAll】
// MyEndpoint に定義したすべてのエンドポイントの実行を認可しません
@DenyAll
public class MyEndpoint {
  public String greet1() { return "Hello, world"; }
  public String greet2() { return "Hello, world"; }
}

実装する際には、これらのアノテーションやjakarta.ws.rs.core.SecurityContextから提供されているAPIで行うことになります。

Helidon + IDCSを用いたデモ

当日は、下図のような構成でデモを実施しました。

  • IDCS(Identity Domains)
    • Oracle が提供する IDaaS。今回はOP(OpenID Provider)として使用
    • 今回はFIDO 2 を用いたパスワードレス認証でエンドユーザーの認証を実施
  • auth
    • Helidon*2で実装された RP(Relying Party)
    • IDCS に対して、認可コードフローを用いて ID/アクセス トークンを取得
  • event
    • MP-JWT を用いた RBAC を行うための設定と実装がされたアプリケーションで、Helidon で実装されている
    • 提供しているエンドポイントと各エンドポイントの実行に必要な Role は図中下部の表に記載
  • Oracle Container Engine for Kubernetes
    • auth/event のアプリケーションの実行環境として、Oracle Cloud Infrastructure が提供するマネージド Kubernetes サービスである OKE を使用

*2:Eclipse MicroProfile に準拠した Java のアプリケーションフレームワーク

当日のデモについては、動画リンクから参照ください。

おわりに

最後に、今回解説した技術仕様に関して、簡単にまとめておきます。

  • Eclipse MicroProfile - JWT Propagation
    • マイクロサービスのエンドポイント(Jakarta REST)に対して、RBAC を行うために OIDC の ID トークンに追加するクレーム(upn、groups)を定義
  • OAuth 2.0
    • 認可のプロトコル
    • ユーザーの認証が目的なら独自実装(OAuth 認証)等はせずに OpenID Connect を使う
  • OpenID Connect 1.0
    • 認可 + 認証連携(ID トークン) + Profile API
    • OAuth で使われる JWT なアクセストークンと ID トークンの違いを理解する
日本オラクル株式会社

Oracle Groundbreaker Advocate
Cloud Solution Engineer

日本オラクルに入社後、ソリューション・アーキテクトとしてクラウドでのアプリケーション開発、クラウドネイティブ技術、ストリーム処理、全文検索、AI 等に関する技術支援や案件支援に従事。現在、クラウドネイティブ技術に関連するコミュニティの運営にも参加中。

Community:
Oracle Cloud Hangout Cafe メンバー (#ochacafe)
CloudNative Days - Observability チーム

連載バックナンバー

仮想化/コンテナ技術解説
第6回

Oracle Cloud Hangout Cafe Season6 #1「Service Mesh がっつり入門!」(2022年9月7日開催)

2023/6/22
連載第6回の今回は、2022年9月7日に開催された「Oracle Cloud Hangout Cafe Season6 #1『Service Mesh がっつり入門!』」の発表内容に基づいて紹介していきます。
仮想化/コンテナ技術解説
第5回

Oracle Cloud Hangout Cafe Season5 #5「実験! カオスエンジニアリング」(2022年5月11日開催)

2023/5/18
連載第5回の今回は、2022年5月11日に開催された「Oracle Cloud Hangout Cafe Season5 #5『実験! カオスエンジニアリング』」の発表内容に基づいて紹介していきます。
仮想化/コンテナ技術解説
第4回

Oracle Cloud Hangout Cafe Season5 #3「Kubernetes のセキュリティ」(2022年3月9日開催)

2023/4/18
連載第4回の今回は、2022年3月9日に開催された「Oracle Cloud Hangout Cafe Season5 #3『Kubernetes のセキュリティ』」の発表内容に基づいて紹介していきます。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています