Google App Engine for JavaでOpenIDを試してみた。

フレームワークには、slim3を使っています。(今回はあまり関係ないけど。)


ライブラリを探したところ以下の二つが見つかりました。
http://code.google.com/p/openid4java/
http://code.google.com/p/dyuproject/


openid4javaはGAE上では動かないというので、
http://groups.google.co.jp/group/google-appengine/browse_thread/thread/9e4381f41c7d942f?pli=1
試してもいません^^


今回はdyuprojectを使います。


まず、ダウンロードページから、
dyuproject-openid-1.1.6-jarjar.jarをダウンロードし(jar、jar言い過ぎです。)
war/WEB-INF/libに配置して、パスを通します。


マニュアルでは、web.xmlについて、
http://code.google.com/p/dyuproject/wiki/QuickStartOpenid
という記述になっていますが、このままですと、
mixiOpenIDで試すとニックネームが取得できませんでしたので、
オリジナルのFilterを拡張しました。


拡張Filter

public class OpenIdFilter extends OpenIdServletFilter {

    public static final String NICKNAME = "nickname";

    @Override
    public void init(FilterConfig config) throws ServletException {

        // 本来のメソッドを呼ぶ
        super.init(config);

        // nicknameを返すように指示
        RelyingParty.getInstance().addListener(
            new AxSchemaExtension().addExchange(NICKNAME));
    }


web.xml

    
        javax.servlet.jsp.jstl.fmt.localizationContext
        application
    

    
    	openidFilter
    	slim3.filter.OpenIdFilter
      	
        	forwardUri
        	/finish
      	
    
    
        hotReloadingFilter
        org.slim3.controller.HotReloadingFilter
    
    
    	openidFilter
    	/finish
        REQUEST
  	


これで、ID Providerとの通信部分は大丈夫なはずです。

最後に、認証が通ったあとは、

        // ユーザーオブジェクトの取得
        OpenIdUser user =
            (OpenIdUser) request.getAttribute(OpenIdUser.ATTR_NAME);

        // Identityの取得
        String identity = user.getIdentity();

        // nicknameの取得
        Map axschema = AxSchemaExtension.get(user);
        String nickName = axschema.get(OpenIdFilter.NICKNAME));

といった感じでデータが取り出せます。

せっかくなのでデモも公開します。
デモ
ソース

ですが!


いろいろ試してみると、不具合もあるようです。
私が気づいた不具合は

  1. ログインと同時に渡すパラメータは、認証後には情報から落ちている。(これは仕様?Filterで実装しているのがいけない?)
  2. キャンセルの時、オリジナルのOpenIdServletFilterでは174行目を通るように期待してるようですが、実際には136行目の戻りがnullなので、エラーなのか、キャンセルなのかわかりません。

といったところです。

自分で直せばいいのですが、知識とモチベーションが足りません^^
おそらくRelyingPartyクラスを直せばいいはずです。(Finalクラスですが、、、)


GAEでは、Socketが使えないとのことですが、dyuprojectでは大丈夫でした。
こまかい実装までは追っていませんが、SimpleHttpConnectorなるクラスが通信していると思います。

実用には手を加える必要があると思いますが、
ともかく、GAE/JでもOpenIDが使えることは確認できました!