MicroProfile JWTによるスケーラブルでセキュアなマイクロサービス構築 -入門編(Part 2)-
富士通技術者ブログ~Javaミドルウェア~
2022年4月1日 初版
数村 憲治
MicroProfile Interoperable JWT RBAC(MP JWT)を使用し、Javaでセキュアなマイクロサービスを構築する方法について、Part 1に引き続き紹介します。Part 1では、マイクロサービスアーキテクチャーにおける認可システムの課題と、その解決策であるMP JWTの紹介、およびJWTの構成内容や作成についてみてきました。Part 2では、Jakarta RESTful Web Services アプリケーションにおいて、JWTの使用方法を紹介します。
なお、ここで紹介するプログラムの完全なソースコードは、以下で参照できます。
Restful Web Serviceアプリケーションの用意
使用するプログラムは以下のHelloアプリケーションです。
App.java
@ApplicationPath("/")
public class App extends Application {
}
Hello.java
@Path("hello")
@RequestScoped
public class Hello {
@GET
public String hello() {
return "Hello !¥n";
}
}
プログラムのビルドについては、https://github.com/fujitsu/app_blog/tree/master/mpjwt-202102/baseにmavenプロジェクトを用意していますので、参照ください。
上記プログラムを実行するために、MicroProfileの実装の一つである、Launcherを用意します。Launcherは、以下よりダウンロードし利用します。
https://github.com/fujitsu/launcher/releases/download/3.0/launcher-3.0.jar
Launcherの使い方は、ダウンロードしたlauncher-3.0.jarを任意の場所に置いて、javaコマンドの-jarオプションに指定するだけです(インストール作業は不要です)。詳細なLauncherの使用方法は、ドキュメントを参照してください。
$ java -jar launcher-3.0.jar --deploy hellojwt.war
Launcherはデフォルトで8080番ポートを使用しますので、このWebアプリケーションにアクセスするには、curlコマンドなどで以下のように実行します。
$ curl http://localhost:8080/hello
「Hello !」と表示されれば、正しく起動されています。
MP JWTを使用したロールの設定
続いて、このhelloアプリケーションに、特定のロールを持つ人からのみアクセスできるようにします。まず、MP JWTを使用するには、Applicationクラス(javax.ws.rs.core.Application)に対して、org.eclipse.microprofile.auth.LoginConfigを指定します。
例:App.java
@ApplicationPath("/")
@LoginConfig(authMethod = "MP-JWT")
public class App extends Application {
}
次に、「/hello」エンドポイントに対して、ロールを設定します。ロールは、javax.annotation.security.RolesAllowedのパラメーターに指定します。以下の例は、「キツネさんチーム」というロールを設定しています。
@Path("hello")
@RequestScoped
public class Hello {
@GET
@RolesAllowed("キツネさんチーム")
public String hello() {
return "Hello !¥n";
}
}
このMP JWTを使用したアプリケーションを起動するには、JWTの署名を検証するためのパブリックキーを、Launcher起動時に指定する必要があります。パブリックキーの指定方法には、PEM形式ファイルの場所をシステムプロパティ「mp.jwt.verify.publickey.location」に指定する方法や、JWK形式をBase64エンコードして「mp.jwt.verify.publickey」に指定する方法などがあります。MP JWTでサポートするパブリックキーのフォーマットについては、Supported Public Key Formatsを、パブリックキーの指定方法については、Signature Verification Configuration Parametersを参照ください。ここでは、Base64エンコードしたJWKを指定する方法を紹介します。
MP JWTを使用したアプリケーションの起動例
$ java -Dmp.jwt.verify.publickey=eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IllBNmpBdktWcUVXOGhxUlVnb2NWOFVtNlE3cjVkaWJVTUZzZ1pQb2hYU2c9IiwieSI6IlMwRmhqMS1IOU9pdWtmSUxrWTZJM2txWGlwZm5iRnlkU1ZpSVpaamliNFU9In0= -Dmp.jwt.verify.publickey.algorithm=ES256 -jar launcher-3.0.jar --deploy hellojwt.war
このように起動したアプリケーションに対して、先ほど同様にエンドポイントにアクセスすると、以下のように、ステータスコード401(Unauthorized)が返却されます。
$ curl -I http://localhost:8080/hello
HTTP/1.1 401 Unauthorized
Server: Launcher 3.0
WWW-Authenticate: Bearer
Content-Length: 1034
Content-Language:
Content-Type: text/html
これは、「/hello」にアクセスするために必要なロールが、JWTとしてHTTPリクエストに渡されなかったためです。正しくアクセスするためには、「キツネさんチーム」というロールを含むJWT(Part 1で例示したペイロード)を、HTTPリクエストに指定する必要があります。JWTは、HTTPリクエストの「Authorization」ヘッダーに、「Bearer」の後に指定します。
$ curl http://localhost:8080/hello -H "Authorization: Bearer eyAgInR5cCI6ICJKV1QiLCAgImFsZyI6ICJFUzI1NiIsICAia2lkIjogImtleS0xMjM0In0=.eyAgImlzcyI6ICLnmbrooYzogIUiLCAgImV4cCI6IDE2NjgxMzI2NzEsICAiaWF0IjogMTYzNjU5NjY3MSwgICJ1cG4iOiAi5a-M5aOr6YCa6Iqx5a2QIiwgICJhZGRyZXNzIjogIuadseS6rOmDvea4r-WMuuadseaWsOapiyIsICAiZ3JvdXBzIjogWyLjgq3jg4Tjg43jgZXjgpPjg4Hjg7zjg6AiLCAi44Gf44Gs44GN44GV44KT44OB44O844OgIl19.de_Wqzp0aLlgp5mvIZeW-Lr8XbF1ha0PyV9kU2K80fKUvCxrxHWIMZVStKjugewVX2hQqigVpCL6u5Vp6WwsEQ=="
「Hello !」というレスポンスが得られれば、正しくロールによる認可ができたことになります。
なお、この例で使用した、パブリックキーとJWTの作成は、以下のプログラムを使用して作成しました。
Claim(JWT内に設定されている属性)値の取得
次にJWTに指定したClaim(ペイロードに指定したJSON文字列)から、値を取り出す例を紹介します。ここでは、Part 1のペイロードの例(図1を参照)から、「upn」の値を取り出します。
図1:JWTの構成
org.eclipse.microprofile.jwt.Claimのパラメーターに「upn」を指定し、org.eclipse.microprofile.jwt.ClaimValueとして、インジェクションします。「hello」メソッド内で実施しているように、ClaimValueのgetValueメソッドで値を取り出すことができるようになります。
public class Hello {
@Inject
@Claim("upn")
private ClaimValue<String> upn;
@GET
@RolesAllowed("キツネさんチーム")
public String hello() {
return "Hello " + upn.getValue() + " !¥n";
}
}
このアプリケーションに対して、以下のHTTPリクエストを発行します。
$ curl http://localhost:8080/hello -H "Authorization: Bearer eyAgInR5cCI6ICJKV1QiLCAgImFsZyI6ICJFUzI1NiIsICAia2lkIjogImtleS0xMjM0In0=.eyAgImlzcyI6ICLnmbrooYzogIUiLCAgImV4cCI6IDE2NjgxMzI2NzEsICAiaWF0IjogMTYzNjU5NjY3MSwgICJ1cG4iOiAi5a-M5aOr6YCa6Iqx5a2QIiwgICJhZGRyZXNzIjogIuadseS6rOmDvea4r-WMuuadseaWsOapiyIsICAiZ3JvdXBzIjogWyLjgq3jg4Tjg43jgZXjgpPjg4Hjg7zjg6AiLCAi44Gf44Gs44GN44GV44KT44OB44O844OgIl19.de_Wqzp0aLlgp5mvIZeW-Lr8XbF1ha0PyV9kU2K80fKUvCxrxHWIMZVStKjugewVX2hQqigVpCL6u5Vp6WwsEQ=="
成功すると、「Hello 富士通花子 !」というレスポンスが得られます。
まとめ
今回のPart 2 では、Jakarta RESTful Web Services アプリケーションで、MP JWTを使用する方法を紹介しました。このように、MP JWTを使うことで、既存のJavaアプリケーションに大きな変更を加えることなく、認可のシステムを組み込むことができるようになります。
本コンテンツに関するお問い合わせ
お電話でのお問い合わせ

Webでのお問い合わせ

当社はセキュリティ保護の観点からSSL技術を使用しております。