Play! Framework による OpenID の参照

Play! Framework の OpenID 機能を使用して Google アカウントとリンクする方法について。
OpenID は認証統合やシングルサインオンのためのアーキテクチャです。こちらのサービスのアカウントを GoogleOpenID に関連付けておけば利用者はログイン作業なしでサービスを利用できます。詳しくはggrks

例として想定する動作。

  1. 画面上で [Google] のアイコンをクリック。
  2. サーバから Google の URL へ OpenID を要求する。
  3. Google からリダイレクトで認証レスポンスの呼び出し。認証に成功していれば OpenID を取得。
  4. OpenID と紐付けてこちらのサービスのアカウント情報を保存する。

ビューの作成

Google アイコンがクリックされると Auth コントローラの google() メソッドを呼び出すようなビューを作成します。

<a href="@{Auth.google()}">
<img src="@{'/public/images/google.png'}" width="32" height="32"/>Google</a>

コントローラの作成

Google アカウントは https://www.google.com/accounts/o8/id に対して OpenID.id().verify() を呼ぶだけ。認証レスポンス時にユーザ情報を取得できます。

このアクションはリンクをクリックした時と認証レスポンス時 (OpenID.isAuthenticationResponse() == true) の 2 度呼び出されます。リンククリック時には URL へ認証要求を出し、認証レスポンス時には認証結果の評価を行います。

public class Auth extends Controller {
  public static void login(){
    render();
  }
  public static void google(){
    authenticate("https://www.google.com/accounts/o8/id");
  }
  private static void authenticate(String url){
    // 認証完了のレスポンスでなければ OpenID の検証を要求する
    if(! OpenID.isAuthenticationResponse()){
      OpenID.id(url).verify();
      return;
    }
    // 認証処理の結果を評価
    UserInfo user = OpenID.getVerifiedID();
    if(user == null){
      flash.put("error", "認証に失敗しました");
      login();
      return;
    }
    // 認証完了
    session.put("userid", user.id); // 本当はこちらのアカウントと関連付け...
    redirect("Application.index");  // 適当なアクションにリダイレクト
    return;
  }
}

これだけ。超簡単。