OpenID RP を Google App Engine (java) で (dyuproject)
前回も書きましたが、GAE/J上ではSocketが使えない。故にopenid4javaはGAEでは使えない。
でも、dyuprojectは動くし、動かした上にコードを公開されている方もいる。
どうやらGAE/Jの URLフェッチ API を使っている模様。そりゃそれしか方法はないですよね。
私は職業プログラマでは無いので、車輪の再開発どころか、なるべくコードは書きたくないんです。
早速、dyprojectにトライしてみましょう。
dyuproject-openid-1.1.6-jarjar.jar のダウンロード
dyuprojectのDownloadsから、dyuproject-1.1.6.zipをダウンロードします。
JavaDocとか他のライブラリとかデモが不要なら、dyuproject-openid-1.1.6-jarjar.jar でもいいです。
eclipseのGAEプロジェクトへライブラリを追加する
ダウンロードしたzipファイルの、/dist に、dyuproject-openid-1.1.6-jarjar.jar はあります。
それを、eclipse の /war/WEB-INF/lib/にコピーします。
eclipseを起動して、war/WEB-INF/lib/ の下にコピーしたjarファイルを右クリックして、[ビルド・バス(B)] – [ビルド・パスに追加(A)]をクリックします。
念のため、プロジェクトの[参照ライブラリー]に追加されている事を確認します。
/WEB-INF/web.xml に追記する
QuickStartOpenid – dyuprojectのんを参考にしながら書きます。
ちょっとだけ手を加え (ログアウト用サーブレットを追加とか) ましたが、基本的に同じです。
<filter>
<filter-name>openid-filter</filter-name>
<filter-class>com.dyuproject.openid.OpenIdServletFilter</filter-class>
<init-param>
<param-name>forwardUri</param-name>
<param-value>/</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openid-filter</filter-name>
<url-pattern>/openid-login</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>openid-filter</filter-name>
<url-pattern>/openid-logout</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>openid-servlet</servlet-name>
<servlet-class>my.package.OpenIdLoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>openid-servlet</servlet-name>
<url-pattern>/openid-login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>openid-logout</servlet-name>
<servlet-class>my.package.OpenIdLogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>openid-logout</servlet-name>
<url-pattern>/openid-logout</url-pattern>
</servlet-mapping>
ログイン用サーブレットを作る
QuickStartOpenid – dyuprojectのサンプルコードにほんに少しだけ異常系を付け足しただけです。
package my.package;
import com.dyuproject.openid.RelyingParty;
import com.dyuproject.openid.ext.AxSchemaExtension;
import com.dyuproject.openid.OpenIdUser;
public class OpenIdLoginServlet extends HttpServlet {
static {
RelyingParty.getInstance()
.addListener(new AxSchemaExtension()
.addExchange("email")
.addExchange("nickname")
.addExchange("fullname")
.addExchange("gender")
.addExchange("postcode")
.addExchange("country")
.addExchange("language")
);
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
OpenIdUser user = (OpenIdUser) request.getAttribute(OpenIdUser.ATTR_NAME);
if (user != null) {
String identity = user.getIdentity();
HttpSession session = request.getSession();
session.setAttribute("identity", identity);
Map axschema = AxSchemaExtension.get(user);
if (axschema != null && axschema.size() > 0) {
session.setAttribute("email", axschema.get("email"));
session.setAttribute("nickname", axschema.get("nickname"));
} else {
session.setAttribute("email", "unknown");
session.setAttribute("nickname", identity);
}
} else {
//
}
response.sendRedirect(response.encodeRedirectURL(request.getParameter("redirect_url")));
}
}
ログアウト用サーブレットを作る
QuickStartOpenid – dyuprojectにはサンプルが無かったけど、ログインしっぱなしじゃ困るから、ログアウト用サーブレットも作ります。
package my.package;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import javax.servlet.RequestDispatcher;
public class OpenIdLogoutServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
HttpSession session = request.getSession(false);
session.invalidate();
response.sendRedirect(response.encodeRedirectURL(request.getParameter("redirect_url")));
}
}
動かす
あとはHTMLでいいので、OpenIDプロバイダのURLを引数 “openid_identifier”にセットして、サーブレットに渡すAタグなり、フォームなりを書いて実行します。
mixi OpenIDならこんな感じですね。
<a href="openid-login?openid_identifier=https://mixi.jp">mixiでログインします</a>
なんて簡単なんでしょう。
サンプルコードでは、mixi、Google、Yahoo!、openid.ne.jp は動きました。
hatena はうまくいきませんでした。なんでだろう。
nickNameが取れたのはmixiだけでした。