appengineのfederatedLoginの機能を使ったアプリケーションの場合、開発環境のログイン機能ではcom.google.appengine.api.users.User
からfederatedIdentityの値などが取得できずに不便です。実行時のUserService#isLoggedIn()
, UserService#isAdmin()
, UserService#getAuthDomain()
等はApiProxy.Environment
を自身の実装に置き換えるだけだったので簡単でしたが、federatedLoginの場合はこれらの値を触るだけでは不十分です。
ではいつものようにApiProxy#setDelegate(ApiProxy.Delegte)
でいじってやるか!というワケにもいきません。UserService#getCurrentUser()
等はRPCされないためです(以前、本家MLで「UserServiceはコストが低い」という話がありましたね。その理由はRPCしない=コストが低い、ということです。このブログでもいつだったかに書いた記憶があります。)。
んじゃどーするのか?といいますと、ApiProxy#getCurrentEnvironment()
で取得できるApiProxy#Environment<ApiProxy.Delegate>
のMap<String, Object>#getAttributes()
メソッドが返す値を操作してやるのです。
ApiProxy#Environment<ApiProxy.Delegate>
の#Map<String, Object>#getAttributes()
に以下の要素を設定してやることで、federatedLoginの機能が開発環境でも有効になります。
- com.google.appengine.api.users.UserService.is_federated_user
- com.google.appengine.api.users.UserService.user_id_key
- com.google.appengine.api.users.UserService.federated_identity
- com.google.appengine.api.users.UserService.federated_authority
com.google.appengine.api.users.UserService.is_federated_user
についてはBoolean.TRUE
を設定しておく必要があります。他はすべて文字列を設定すればよく、それぞれの値はfederatedLogin機能を使うときのアレです。
単体テスト環境では、ApiProxy#Environment<ApiProxy.Delegate>
のMap<String, Object>#getAttributes()
が返す値に上記を追加し、ApiProxy#setEnvironmentForCurrentThred()
してやれば良いです。
開発サーバ環境でも同じことをすれば良いのですが、私が使っている「専用のFilterとして実装する」という方法のサンプルコードを掲載しておきます。
「独自のApiProxy#Environment<ApiProxy.Delegate>
を常に使用する」「createLoginURL()すると、専用のフォームを表示し、そこからのPostの内容に従ってfederatedLoginUser情報を設定する」「web.xml内でinit-paramにfederatedLoginUser情報があれば、それを読み込んで起動時からログイン状態にしておく」等をやっています。
単体テスト環境では、下記のサンプルコードの内部staticクラスとして定義されているFederatedLoginEnvironment
をインスタンス化して、loginメソッドなどでfederatedLogin状態を作り出し、ApiProxy#setEnvironmentForCurrentThred()
すれば良いですね。
0 件のコメント:
コメントを投稿