これはJava EE Advent Calendar 2016の17日目です。
概要
JAX-RSの参照実装であるJerseyにはOAuth 2のクライアントをサポートする拡張があります。
今回はそれを使ったサンプルを作ってみました。
ちなみに、認証サーバはSpringで作ってみました。
サンプルコードはGitHubに公開しています。
- https://github.com/backpaper0/javaeeac2016 (この記事の解説に対応しているのはqiitaブランチです)
サンプルの説明
アプリケーション自体は"Hello, <ユーザ名>!"を表示するだけの簡単なものです。
このユーザ名に当たる部分を、認証サーバで認証したユーザの名前を取得して表示します。
ユーザ情報の取得に対する許可をOAuth 2で与えています。
まず http://localhost:8080/helloworld を開こうとします。
すると、認証サーバへリダイレクトされ、ログインを促されます。
ログインすると、今度はhelloworldアプリケーションに対してユーザ情報の取得に対する許可を与えるか確認されます。
許可を与えると、helloworldアプリケーションに戻ってきて挨拶が表示されます。
コードの説明
セッションにアクセストークンが保存されていない場合、helloworldアプリケーションが認可されていないと判断して、アクセストークンを取得するための認可コードを取得するため、OAuth2CodeGrantFlow
のstart
メソッドを使用してリダイレクトURIを構築しています。
OAuth2CodeGrantFlow flow = OAuth2ClientSupport.authorizationCodeGrantFlowBuilder(
clientIdentifier, authorizationUri, accessTokenUri)
.redirectUri(redirectUri)
.client(client)
.property(Phase.ALL, OAuth2Parameters.STATE, state.getValue())
.build();
URI location = URI.create(flow.start());
認可が済むと、上記のredirectUri
メソッドで設定したURIにリダイレクトされますが、このとき認可コードがcode
という名前でクエリパラメータとして付いてきます。
リクエストURIをパーズしてcode
を得たら、OAuth2CodeGrantFlow
のfinish
メソッドに渡してアクセストークンを取得します。
OAuth2CodeGrantFlow flow = OAuth2ClientSupport.authorizationCodeGrantFlowBuilder(
clientIdentifier, authorizationUri, accessTokenUri)
.redirectUri(redirectUri)
.client(client)
.property(Phase.ALL, OAuth2Parameters.STATE, state.getValue())
.build();
String state = queryParameters.getFirst("state");
TokenResult tokenResult = flow.finish(code, state);
ユーザー情報を取得する際は、アクセストークンをAuthorization
ヘッダに埋め込みますが、これを勝手にやってくれるFeature
を生成するのがOAuth2ClientSupport
のfeature
メソッドです。
このFeature
をClient
に登録しておきます。
public Client client() {
return ClientBuilder.newBuilder()
.register(HttpAuthenticationFeature.basic(clientId, clientSecret))
.register(OAuth2ClientSupport.feature(accessToken.getValue()))
.build();
}
まとめ
Jerseyのoauth2-client
を使えば、OAuth 2を利用したクライアントアプリケーションを作ることができました。
とはいえ、サンプルコードを見てもらうと分かるように、それなりに作りこむ必要がありました(私のoauth2-client
習熟不足かもしれませんが)。
さらに、とりあえず動く形にしてみたぐらいなので、実装する上でもっと考慮しないといけないことはあると思います。
このように、もうちょい簡単に作れたらいいのになー、と贅沢な不満はありますが、動くサンプルは作れたので満足しました。
以上⛄️