pac4jでGitHubのOAuth認証を使ってみる

GitHubアカウントでログインできるWebアプリケーションを作りたいなーと思っていたのですが、Javaだとpac4jというライブラリを使うとGitHubを始め、TwitterFacebookなど様々なサービスのOAuth認証を扱うことができるようです。

github.com

SpringMVCやJAX-RSなどのフレームワークとの連携機能も提供されているようですが、今回は基本的な使い方を把握するためにpac4j-oauthというモジュールを使ってサーブレットベースで試してみました。

まずはGitHub上でアプリケーションの登録を行う必要があります。

f:id:takezoe:20170128020846p:plain

続いてプログラムの実装に移ります。pom.xmlに以下の依存関係を追加します。

<dependency>
    <groupId>org.pac4j</groupId>
    <artifactId>pac4j-oauth</artifactId>
    <version>1.9.5</version>
</dependency>

プログラムでは以下のようにしてGitHubClientを生成します。シングルトンなインスタンスとして生成しておくとよいと思います。コンストラクタの引数にはGitHubへのアプリケーション登録時に発行されたクライアントIDとクライアントシークレットを指定します。

GitHubClient client = new GitHubClient(clientId, secret);
client.setCallbackUrl("http://localhost:8080/callback");
client.setScope("repo, user");

コールバックURLは認証後にリダイレクトされるURL、スコープはアプリケーションが必要とする権限を指定します。GitHubで指定可能なスコープについてはこちらを参照してください(デフォルトはuserです)。

認証を要求するには以下のようにします。redirect()メソッドでGitHubの認証ページにリダイレクトされます。J2EContextというのはJavaEEサーブレット)用のアダプタみたいなものです。このクラスを差し替えることで別のフレームワークにも対応できる作りになっています。

J2EContext context = new J2EContext(request, response);
client.redirect(context);

f:id:takezoe:20170128021422p:plain

ユーザがこの画面でアプリケーションの認証要求を許可すると指定したコールバックURLにリダイレクトされるので、該当のURLを処理するサーブレットで以下のようなコードで認証情報を取得します。

J2EContext context = new J2EContext(request, response);
OAuthCredentials credentials = client.getCredentials(context);
GitHubProfile profile = client.getUserProfile(credentials, context);

profileからユーザ情報やAPI呼び出し用のアクセストークンなどを取得することができます。

String userName = profile.getUsername();
String email = profile.getEmail();
String accessToken = profile.getAccessToken();

こんな感じでpac4jを使うと簡単にGitHubOAuth認証を利用することができます。他のサービスの場合もGitHubClientの代わりにTwitterClientFacebookClientなどのクラスを使用するだけで同じような感じで実装することができます。また、OAuth以外にも様々な認証方式に対応したモジュールが提供されています。

特定のフレームワーク用のアドオンとしてだけではなく単独のライブラリとしても使えるようになっているのでJavaで外部サービスのアカウントを使用した認証機能が必要な場合は覚えておくといいんじゃないかと思います。