$30 off During Our Annual Pro Sale. View Details »

MicroProfile JWTを使ってマイクロサービスをセキュアにしよう

MicroProfile JWTを使ってマイクロサービスをセキュアにしよう

2022年11月27日開催された日本Javaユーザーグループのカンファレンス「JJUG CCC 2022 Fall」で実施したセッションです。

内容
- JWTトークンを使う認証認可がはじまった経緯
- JWTトークンの内容
- MicroProfile JWTの概要
- JWTトークン送受信のコーディング例
- Quarkusの上で動くサービスから、OpenLibertyの上で動くサービスの間でJWTを使った認証認可のデモ

Hiroko Takamiya

November 28, 2022
Tweet

More Decks by Hiroko Takamiya

Other Decks in Programming

Transcript

  1. View Slide

  2. ⾼宮裕⼦(たかみや ひろこ)
    • ⽶IBM所属
    • ノースカロライナ州在住
    • アプリケーションサーバー開発部⾨
    • セキュリティチームに約10+年
    • 東京⽣まれ、東京育ち
    • JJUG初参加です
    • よろしくお願いします︕
    ⾃⼰紹介
    画像︓Wikipedia/ノースカロライナ州観光協会

    View Slide

  3. トーク概要
    MicroProfile JWTの概要を紹介
    • サービスから別のサービスへと安全にアクセスする仕組み
    § マイクロサービスのセキュリティ関連⽤語
    § なぜJWTトークンを使うか
    § JWTトークンについて
    § JWTトークンの内容、信⽤できるのはなぜ︖
    § JWT、JWS、JWE、JWKの違いは︖
    § MicroProfile JWT (mpJWT)は、マイクロサービス間の運⽤性を⾼める
    § 代表的なユースケース
    § デモ
    JWTトークン
    クライアント サービスA サービスB サービスC サービスC

    View Slide

  4. マイクロサービスのセキュリティ関連⽤語
    OAuth2
    • 認可(Authorization)のプロトコル
    • OAuth2はソーシャルネットワー
    クのログインなどに使われる
    OpenID Connect
    • OAuth2をもとに構築されたオー
    プン・スタンダード
    • OpenID Connectをサポートする
    プロバイダがユーザー認証
    (Authenticate)する
    • クライアントサービス(Relying
    Party)は、プロバイダを使って認
    証するため、⾃前でユーザーデー
    タを持たないでよい
    JWT
    • JSON Web Token
    • 情報(Claim)を運ぶトークン
    • ClaimをJSONオブジェクトで表現、
    エンコードののち、デジタル署名
    または暗号化、もしくはその両⽅
    を使って安全に送受信する

    View Slide

  5. なぜマイクロサービスの認証、認可にJWTを使うのか
    従来のアプリケーションの場合、
    • ユーザーは、いつも同じサーバー(またはクラスター)と通信
    • サーバーは、認証認可して、セッション・クッキーやトークンを作成
    • サーバーは、セキュリティのコンテクストを、クッキーやトークンと関連づけて保存
    5
    JSESSIONID
    SSO Tokenなど
    Security
    Context

    View Slide

  6. なぜマイクロサービスの認証、認可にJWTを使うのか
    マイクロサービスの場合、
    • サービスは、セキュリティ情報を保存しない
    • 同じサービスにいく保証もない
    • リクエストごとに認証、認可の情報(JWT)を送る
    6
    JWT JWT JWT

    View Slide

  7. なぜマイクロサービスの認証、認可にJWTを使うのか
    • マイクロサービスはステートレスである
    • セキュリティ コンテキストを、サーバー側の HTTP セッションに保存しない
    • マイクロサービス クライアントに関連付けられたセキュリティ コンテキストは、通
    常、JWT としてリクエスト毎に使われる
    • JWTが次のマイクロサービスに伝播、送信される
    7

    View Slide

  8. JWTの中に⼊れる情報
    8
    Propagate ID
    ユーザーのアイデンティティ
    Propagate User Entitlement
    ユーザーの属性や資格
    Transfer
    ユーザーデータ以外の
    ⾊々なデータを
    サーバー間で安全に伝達できる

    View Slide

  9. 9

    View Slide

  10. JSON Web Token (JWT)
    定義: (RFC 7519, https://tools.ietf.org/html/rfc7519より)
    • 情報(Claim)を伝達する⽅法
    • JWT内のClaimはJSONオブジェクトとしてエンコードされる
    • エンコードは、URL Safeな形式(“/”や”?”を使わずURLの⼀部として送れる)
    • エンコードされたデータは
    • JSON Web Signature (JWS) 構造のペイロードとして署名または、
    • JSON Web Encryption (JWE)構造の⽂字データとして署名・暗号化される
    10

    View Slide

  11. JWT Trust Model
    • JWTの作成時に、発⾏者が、使⽤前に、秘密鍵でJWTに署名する
    • JWTの受け取り側(マイクロサービス)は⼀致する公開鍵を使って JWTを検証する
    • 検証した情報(claim)は信頼できる
    • 各種の署名、暗号化のアルゴリズムをサポート
    • JWTは、必ずHTTPSで送る
    11

    View Slide

  12. JWT, JWS, JWE, JWKの違いは何︖
    12
    • 署名付き(Signed) JWTは、JWS (JSON Web Signature).
    • 暗号化された(Encrypted)JWTは、JWE (JSON Web Encryption).
    • 実際、オブジェクトは JWS または JWE のいずれか
    • JWT は抽象クラスのようなもので、JWS と JWE がセキュアな実装
    • JSON Web Key (JWK) は、暗号鍵を表す JSON オブジェクトです
    • この鍵は、JWE を復号化、または JWS が署名を検証するために使⽤されます (JWT 発⾏者の公
    開鍵が含まれています)
    • JWKキーセット(JSON形式で表されたキーのグループ JWKのArray)というものもある
    • 詳しくは JSON Object Signing and Encryption spec (JOSE) を参照
    • https://tools.ietf.org/html/rfc7520

    View Slide

  13. 署名済みJWT (JWS)
    署名済み JWT は JWS と呼ばれます。ドット (.) で区切られた 3 つの base64 でエンコードされた JSON オブジェク
    ト (ヘッダー、ペイロード、署名) で構成されます。
    Sample decoded JWT
    {
    "typ": "JWT",
    "alg": "RS256"
    }.
    {
    "aud": "server",
    "iss": "https://ibm.com/oidc/endpoint/OP",
    "iat": 1311281970,
    "exp": 1311283970,
    "sub": “tom tom”,
    “email": “[email protected]”,
    }.
    {JWTの署名}
    Base64 URL encoded
    ヘッダー
    Base64 URL encoded
    ペイロード
    Base64 URL encoded
    署名
    . .
    13
    このRS256は、発⾏者(Issuer)の秘密鍵
    によって署名が作成されていることを
    表します。受け取り側は発⾏者の公開
    鍵によって、署名を検証します。

    View Slide

  14. 暗号化済みJWT (JWE)
    14
    • 暗号化された JWS
    • ドット (.) で区切られた 5 つの Base64 URL エンコードされた JSONオブジェクト
    • ヘッダー、暗号化鍵、初期化ベクトル、暗号⽂、および認証タグ
    ヘッダー
    JWE Header
    暗号化鍵
    Encrypt Key
    初期化ベクトル
    Initialization
    vector
    暗号化された内容
    Encrypted JWS
    認証タグ
    Authentication tag
    . .
    . .
    複雑な仕組みです︕
    1) 発⾏者が JWS とランダムな⼀時キーを作成
    2) 発⾏者は、受信者の公開鍵を使⽤して⼀時的な鍵を暗号化し、「暗号化鍵」と
    して JWE に保存します (* 受信者の公開鍵へのアクセスが必要です*)
    3) 受信者は独⾃の秘密鍵を使⽤して暗号化鍵を復号化します
    4) 受信者は暗号⽂を復号化して JWS を取得します

    View Slide

  15. JWTトークンの中⾝をみてみる
    https://jwt.io/#debugger-io にトークンを張り付けてみる

    View Slide

  16. JWTトークンを⼊⼿するには
    • JWT は、サーバー間通信で、信頼のおけるサーバーが発⾏できる。こ
    の場合、呼ばれた側のサーバーは、呼び出し側サーバーによって保証
    されたトークンを信頼する
    • セキュリティ リバース プロキシ サーバーもJWTを発⾏できる。この
    リバースプロキシサーバーは、ログイン後の JWT 作成をサポートする
    • JWT は、信頼できる OpenID Connect プロバイダー (OP) によっても
    発⾏できる (例: Identity Managers, Ping, Azure, Keycloak)
    16

    View Slide

  17. 17

    View Slide

  18. MicroProfile JWT (MP-JWT)
    マイクロサービスにおいて、セキュリティ トークンとして JWT を使⽤する際の相互運⽤性を促進する仕様
    仕様の詳細は下記のリリースノートを参照ください
    https://microprofile.io/project/eclipse/microprofile-jwt-auth/spec/src/main/asciidoc/release-notes.asciidoc
    18
    バージョン 内容
    MP-JWT 1.0 相互運⽤可能な JWT トークン形式を定義
    トークン アクセス API を定義
    MP-JWT 1.1 MicroProfile Config を使⽤するポータブル JWT 構成を定義
    JSON Web Key (JWK) のサポート
    MP-JWT 1.2 JWT を Cookie に含めることができます
    署名のアルゴリズム追加
    MP-JWT 2.0 JakartaEE対応

    View Slide

  19. MicroProfile JWTに必要な情報
    19
    相互運⽤のために、必要な情報を定義. 太字は必須、太字でないものは推奨
    {//ヘッダー
    “typ”: “JWT”, //トークンのタイプ
    “alg”: “RS256”, // 署名のアルゴリズム
    }
    {{//Claim
    “iss”: “https://server.example.com”, //発⾏者(Issuer)
    “aud”: “s6BhdRkqt3”, //トークンが対象とする受信者(audience)
    “jti”: “a-123”, //トークンのID(Identifier)
    “exp”: 1311281970, //トークンの期限(Expiration)
    “iat”: 1311280970, //トークン発⾏時(IssuedAt)
    “sub”: “24400320”, //ユーザーのSubject (java.security.Subject)
    "upn": “JJU[email protected]", //ユーザーPrincipal (java.security.Principal)
    “groups”: [“red-group”, “green-group”], //ユーザーが所属するグループ(認可に使われる)
    “custom-value”: “Javaユーザーグループ” //アプリに必要な情報があればClaimにして送ることができる
    }
    { //署名
    }
    (https://github.com/eclipse/microprofile-jwt-auth/pull/191 for MP-JWT1.2より)

    View Slide

  20. MicroProfile JWTのAPI
    20
    JWTトークンにアクセスするためのInterfaceやClaimの名前などの定義
    https://download.eclipse.org/microprofile/microprofile-jwt-auth-2.0/apidocs/

    View Slide

  21. 関連するMicroProfile Config
    21
    下記の構成は、MicroProfile Configの中のMP-JWT関連のもの
    https://github.com/eclipse/microprofile-jwt-auth/blob/master/spec/src/main/asciidoc/configuration.asciidoc
    mp.jwt.token.header
    mp.jwt.token.cookie
    mp.jwt.verify.audiences
    mp.jwt.decrypt.key.location
    mp.jwt.verify.publickey.algorithm
    mp.jwt.verify.publickey
    mp.jwt.verify.publickey.location
    mp.jwt.verify.issuer

    構成を別にまとめて、コードから参照することで、コードを変更せず、構成を変えるだけで、
    サービスがよりポータブルになります

    View Slide

  22. トークンの作り⽅は︖(start.microprofile.io)
    import io.vertx.ext.auth.JWTOptions;
    import io.vertx.ext.auth.PubSecKeyOptions;
    import io.vertx.ext.auth.jwt.JWTAuth;
    import io.vertx.ext.auth.jwt.JWTAuthOptions;

    private static String generateJWT(String key) {
    JWTAuth provider = JWTAuth.create(null, new JWTAuthOptions()
    .addPubSecKey(new PubSecKeyOptions()
    .setAlgorithm("RS256")
    .setSecretKey(key)
    ));
    MPJWTToken token = new MPJWTToken();
    token.setAud("targetService");
    token.setIss("https://server.example.com"); // Must match configuration values
    token.setUpn("Jessie");
    token.addAdditionalClaims("custom-value", "Jessie specific value");
    token.setGroups(Arrays.asList("user", "protected"));
    return provider.generateToken(new io.vertx.core.json.JsonObject().mergeIn(token.toJSONString()), new
    JWTOptions().setAlgorithm("RS256"));
    }
    22

    View Slide

  23. トークンの作り⽅は︖(Quarkus)
    import io.smallrye.jwt.build.JwtClaimsBuilder;
    public static String generateToken(String username, Set roles, Long duration, String issuer) throws
    Exception {
    String privateKeyLocation = "/privatekey.pem";
    PrivateKey privateKey = readPrivateKey(privateKeyLocation);
    JwtClaimsBuilder claimsBuilder = Jwt.claims();
    long currentTimeInSecs = currentTimeInSecs();
    Set groups = new HashSet<>();
    for (Role role : roles) groups.add(role.toString());
    claimsBuilder.issuer(issuer);
    claimsBuilder.subject(username);
    claimsBuilder.issuedAt(currentTimeInSecs);
    claimsBuilder.expiresAt(currentTimeInSecs + duration);
    claimsBuilder.groups(groups);
    return claimsBuilder.jws().signatureKeyId(privateKeyLocation).sign(privateKey);
    }
    23

    View Slide

  24. トークンの作り⽅は︖(OpenLiberty)
    import com.ibm.websphere.security.jwt.JwtBuilder;
    import com.ibm.websphere.security.jwt.Claims;
    private String buildJwt(String userName, Set roles) throws Exception {
    return JwtBuilder.create("jwtFrontEndBuilder")
    .claim(Claims.SUBJECT, userName)
    .claim("upn", userName)
    .claim("groups", roles.toArray(new String[roles.size()]))
    .claim("aud", "systemService")
    .buildJwt()
    .compact();
    https://openliberty.io/docs/latest/reference/config/jwtBuilder.html
    24

    View Slide

  25. トークンの送り⽅(1)
    サーバーがAuthorizationヘッダーにJWTトークンを⼊れて送っているコード
    WebTarget target = ClientBuilder.newClient().target(serviceB);
    Response response = target.request().header("authorization", "Bearer " + jwt).buildGet().invoke();
    25
    JWTトークンは、Authorizationヘッダーの中に、Bearerトークンとして送る
    HTTP Requestの例
    GET /endp/echo HTTP/1.1
    Host: server.example.com
    Authorization: Bearer
    レスポンス例(認証されて、相⼿サービスからGreetingが来たとき)
    HTTP/1.1 200 OK
    Hello, [email protected]

    View Slide

  26. トークンの送り⽅(2)
    JWTトークンをクッキーにするコード(レスポンスとして送付)
    String jwt = tokenProvider.generateToken(...);
    Cookie cookie = new Cookie(“Bearer”, jwt); //mp.jwt.token.cookieで構成できる
    cookie.setHttpOnly(true);
    cookie.setMaxAge(ExpirationTime);
    cookie.setSecure(true);
    response.addCookie(cookie);
    26
    サーバーが、JWTトークンを作って、Cookieにして返しているコード
    HTTP Requestの例
    GET /endp/echo HTTP/1.1
    Host: server.example.com
    Cookie: Bearer=
    JWTトークンは、リクエストの中のCookieとして送付することもできる

    View Slide

  27. MicroProfile JWT – 認証の仕⽅
    MP-JWT は認証トークンであり、ロールに直接マップできるグループ属性が含まれています。
    セキュリティ ロール名とグループ名が同じ場合、 @RolesAllowed アノテーションが使える
    @Inject
    @Claim("custom-value")
    private ClaimValue custom;
    @GET
    @RolesAllowed(“protected")
    public String getJWTBasedValue() {
    if (custom != null) {
    return "Protected Resource; Custom value : " + custom.getValue();
    }
    }
    またトークンのオブジェクトを、APIで読み込んで、Claimを検証することもある
    27

    View Slide

  28. アプリからのアクセス
    アプリケーションは、SecurityContext アノテーションから JsonWebToken にアクセスできる
    • 次の例では、UserPrincipalを org.eclipse.microprofile.jwt.JsonWebToken API のインスタンスとしてキャストして、
    アプリケーションは JsonWebToken ゲッターを介してすべてのクレームにアクセスできます
    @GET
    @Path("/getGroups")
    public Set getGroups(@Context SecurityContext sec) {
    Set<= null;
    Principal user = sec.getUserPrincipal();
    if (user instanceof JsonWebToken) {
    JsonWebToken jwt = (JsonWebToken) user;
    groups= = jwt.getGroups();
    }
    return groups;
    }
    アプリケーションは、Raw Type、ClaimValue、javax.inject.Provider、および JSON-P タイプを介して、
    org.eclipse.microprofile.jwt.JsonWebToken API を直接注⼊することもできます
    @Inject private JsonWebToken jwt;
    @Inject @Claim(standard= Claims.raw_token) private String rawToken;
    @Inject @Claim("iat") private Long dupIssuedAt;
    @Inject @Claim("sub") private ClaimValue> optSubject;
    28

    View Slide

  29. 29

    View Slide

  30. Web リソースと
    サービス
    トークンでサー
    ビスをリクエス
    トする(JWT)
    JWT クレームに基づい
    て認証決定を⾏う
    アプリケーション・サーバー
    クライアント
    アプリケー
    ション
    • クライアントアプリがJWTを作成し、JWTでサービスを呼び出す
    • HTTP client: CLI, Restful Service Client
    ユースケース: シンプルな HTTPS クライアント
    30

    View Slide

  31. フロントエンド
    Web アプリケー
    ション、またはマ
    イクロサービス
    トークンでサー
    ビスをリクエス
    トする(JWT)
    マイクロサービス
    JWT
    JWT クレームに基づ
    いて認証決定を⾏う
    アプリケーション・サー
    バー
    1. ユーザー要求は常に認証リバース プロキシを通過する (エンタープライズ アプリケーションでは⼀般的な構成)
    2. サービスは JWT を検証し、サブジェクトを作成する
    3. サービスはサブジェクトで、リクエストを承認する
    4. サービスは、JWT (オリジナルまたは⾃⼰発⾏) を他のサービスに伝搬する
    リバース
    プロキシ
    サーバー
    ユーザーの認証
    JWT の提供
    • ユーザー認証はリバース プロキシ サーバーによって実⾏され、既存の認証サービスと連携する場合があります
    • リバース プロキシ サーバーは、ユーザーに代わって JWT をセキュリティ トークンとして提供します
    リバース プロキ
    シ サーバー経由
    で Web を閲覧
    する
    ユースケース: リバース プロキシ セキュリティ サーバー
    ブラウザ/
    クライアント
    31
    JWT クレームに基づ
    いて認証決定を⾏う

    View Slide

  32. JWT を使⽤したシングル サインオン⽤の Open ID Connect
    ユースケース: Open ID Connect プロバイダー/クライアント
    ブラウザ/
    クライアント
    アプリケーションが
    サーバー付属の
    OIDC クライアント機能
    (Replying Party)
    を使⽤ OIDCプロバイダ(OP)
    マイクロサービス1
    JsonWebToken は、CDI または JAX-RS SecurityContext
    を介してアクセスできます。追加の認証に JWT を使⽤する
    か、JWT を別のサービスに伝播します
    マイクロサービス2
    propagate
    JWT
    認可サーバー︓アクセストークン(JWT)とIDトークン
    (JWT)を発⾏
    1
    2
    3
    4
    5 6
    propagate
    JWT
    リソース サーバー: バックエンド リポジトリへの認証を実
    ⾏します
    • LDAP based with username or client cert.
    • Use of SAML external identity provider
    • Use of external OIDC provider
    • Use of social medium (ie: Facebook, google)
    • Use of TAI (trust association interceptor)
    7
    1. ユーザーは アプリケーションサーバーの
    OIDC認証機能を使⽤して、使⽤するアプリ
    にログイン
    2. アプリケーションサーバーは、OIDCクライ
    アント(RP)として振舞い、ユーザーを
    OIDCプロバイダ(OP)にリダイレクトする
    3. RPは、認証コード、IDトークン、JWTアク
    セス・トークンなどをOPと交換する
    4. アプリは、別アプリ(アプリ1)にリクエス
    トを送る(JWTが伝搬される)
    5. アプリ1をホストしているサーバーがJWTを評
    価し、サブジェクトとJWTを作成
    6. アプリ1をホストしているサーバーはJWTを認
    可して、JWTを使ってアプリ2を呼び出し
    7. . アプリ2をホストしているサーバーがJWTを
    評価し、サブジェクトとJWTを作成
    32

    View Slide

  33. JWTトークン使⽤のシステム事例
    User
    A
    モバイルデバイス
    ピーク時には
    ⼀分あたり
    14000 リクエスト
    アクセスマネージャー
    • ログイン認証
    • JWT トークンを作成
    リクエストは契約タイプに
    よって4つのFunctionalID
    にマップされる
    User
    B
    User
    C
    User
    D
    User A
    認証キャッシュ
    User B
    User C
    User
    D
    ユーザーレジストリ
    ユーザー検証は
    • トークン期限切れ
    • キャッシュタイム
    アウト
    キャッシュでスルー
    プットを改善
    アプリケーションサーバー

    View Slide

  34. Demo

    View Slide

  35. デモのプログラム(MicroProfile starter)
    Demo
    OpenLiberty
    MP 5.0
    Demo
    Quarkus
    MP 3.2
    start.microprofile.ioから、デモプログラムをダウンロードします。
    異なるランタイム、異なるMicroProfileバージョンでのJWTの認証を実際に⾒てみます。

    View Slide

  36. デモの流れ
    ブラウザー
    Service-a
    localhost:8080
    Quarkus
    Service-b
    localhost:8180
    OpenLiberty
    JWT
    グループ値
    カスタム値
    アクセスの結果を返す
    0. Quarkus上で、Service-aを起動、OpenLiberty上で、Service-bを起動する
    1. ブラウザーから、デモ⽤のサンプル起動⽤アプリを開く http://localhost:8080/
    2. アプリからService-aのエンドポイントにアクセスする http://localhost:8080/data/secured/test
    3. Service-aのエンドポイントで、JWTトークンを作成、セキュアなService-bのエンドポイントにリクエスト送信
    http://localhost:8180/data/protected
    4. Service-bは、JWTトークンを評価して、アクセス権限がある時のみ、トークンのカスタム値をService-aに返す
    5. Service-aは、結果をブラウザに表⽰
    アクセスの結果を返す

    View Slide

  37. MicroProfileのStarterデモは、service-aとservice-bで構成
    Quarkusのservice-aをdevモードでスタート
    > cd service-a
    > mvn compile quarkus:dev
    ブラウザからservice-aにアクセスするURL
    http://0.0.0.0:8080 (localhost)
    service-aはポート8080で動く
    Service-aをQuarkusでスタート

    View Slide

  38. Service-bをOpenLibertyでスタート
    OpenLibertyのservice-bをdevモードでスタート
    > cd service-b
    > mvn liberty:dev
    ブラウザからservice-bにアクセスするURL
    http://172.25.154.129:8180 (これもlocalhost)
    service-bはポート8180で動く
    Startup messages…

    View Slide

  39. デモのノート
    • デモで使⽤したMicroProfileのStarterのサンプルは、簡単に動いて勉強に
    お勧めです︕
    • 違うランタイム間で動かすときは、ポートを変える必要があるかもしれません
    • Quarkusのサービスbは、ポート8180動いていました
    • OpenLibertyのサービスbは、ポート9080をListenしていました
    • OpenLibertyの構成を、9080から8180をListenするように変えました
    • コードと構成はGithubにあります
    https://github.com/una-tapa/MicroProfileDemo
    OpenLibertyのserver.xml
    httpPort=“8180”
    httpsPort="9444"/>

    View Slide

  40. 今回のトークのまとめ
    • クラウド環境で、マイクロサービスをセキュアに動かすには、JWT
    トークンを使う
    • マイクロサービスは、ステートレスなので、セキュリティのコンテ
    クストは、リクエストのたびに、毎回JWTトークンを送る
    • MP-JWTは、マイクロサービス同⼠の相互運⽤のための仕様
    • 認証されたユーザーはUserPrincipalで表され、認可はGroupで⾏われる
    • MP-JWTには、JWTトークンを簡単に使える仕組みが⽤意されている

    View Slide

  41. 41

    View Slide

  42. @Path("/client-test1")
    public class ClientTestDefault {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String ping() {
    Client client = ClientBuilder.newBuilder().build();
    WebTarget webTarget = client
    .target("http://localhost:9081/endpoint");
    String output = webTarget.request().get(String.class);
    client.close();
    return output;
    }
    }
    左のコードは、JakartaのRestfulクライアントか
    らサーバーにリクエストを送るコードです。サン
    プルにも同様のコードがありました。
    ClientBuilderで、送信先のWebTargetを作成して
    リクエストを送っています。
    Jakarta RESTful クライアントのパフォーマンス改善

    View Slide

  43. @Path("/client-test2")
    public class ClientTestCached {
    private static WebTarget cachedWebTarget =
    ClientBuilder.newBuilder().build()
    .target("http://localhost:9081/endpoint");
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String ping() {
    return cachedWebTarget.request().get(String.class);
    }
    }
    パフォーマンス裏技 記事(⽇本語)
    https://community.ibm.com/community/user/wasdevops/blogs/kaori-
    asada/2022/08/17/microservices?CommunityKey=d6c93aa2-6e10-48da-96dc-3831da8ee185
    前のページと、コードがよく似ていますが、
    WebTarget をstaticで作ると、再利⽤でき、ク
    ライアントを閉じる必要がありません。
    これだけの違いで、JakartaのRESTfulクライア
    ントのスループットが3倍になったそうです。
    Jakarta RESTful クライアントのパフォーマンス改善

    View Slide

  44. ありがとうございました︕
    ご感想、フィードバックなどお待ちしています
    E-mail: [email protected]
    Twitter: @htakamiy

    View Slide