なんじゃくにっき

プログラミングの話題中心。

GAE/J認証用T2Plugin

GAEではGoogleアカウントを用いた認証が簡単にできる。
Filterを使って書いたことはあったが、今回はT2のPlugin版。
 
 

URLPatternとDestinationURL(ログアウト後の遷移先)はweb.xmlで設定するようにした(太字になっている部分)。
 


web.xml
<?xml version="1.0"?>
<web-app id="GAETest" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
>

<context-param>
<param-name>t2.encoding</param-name>
<param-value>UTF-8</param-value>
</context-param>

<context-param>
<param-name>GAEAuthPlugin.urlpattern</param-name>
<param-value>/member.*</param-value>
</context-param>

<context-param>
<param-name>GAEAuthenticationPlugin.destinationurl</param-name>
<param-value>/index</param-value>
</context-param>

<filter>
<filter-name>t2</filter-name>
<filter-class>org.t2framework.t2.filter.T2Filter</filter-class>
<init-param>
<param-name>t2.rootpackage</param-name>
<param-value>test.page</param-value>
</init-param>
<init-param>
<param-name>t2.exclude-resources</param-name>
<param-value>css, js, png, gif, jpg</param-value>
</init-param>
<init-param>
<param-name>t2.components</param-name>
<param-value>test.plugin.GAEAuthPlugin</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>t2</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>false</el-ignored>
<page-encoding>UTF-8</page-encoding>
<scripting-invalid>false</scripting-invalid>
<include-prelude>/WEB-INF/pages/common.jsp</include-prelude>
</jsp-property-group>
</jsp-config>
</web-app>

 
web-xmlに設定したURLPatternに正規表現でマッチしたURLへのアクセスのとき、
認証されていなければログインページへリダイレクト、
認証されていればユーザー情報をセッション変数にセットする。
 

Pluginクラス
package test.plugin;

import java.util.regex.Pattern;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.t2framework.commons.meta.MethodDesc;
import org.t2framework.commons.util.Logger;
import org.t2framework.t2.action.ActionContext;
import org.t2framework.t2.contexts.Session;
import org.t2framework.t2.contexts.WebApplication;
import org.t2framework.t2.navigation.Redirect;
import org.t2framework.t2.plugin.AbstractPlugin;
import org.t2framework.t2.spi.Navigation;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

public class GAEAuthenticationPlugin extends AbstractPlugin{
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(GAEAuthenticationPlugin.class);

protected String urlpattern;
protected String destinationurl;

@Override
public void initialize(ServletContext servletContext,
WebApplication webApplication) {
urlpattern = servletContext.getInitParameter("GAEAuthenticationPlugin.urlpattern");
destinationurl = servletContext.getInitParameter("GAEAuthenticationPlugin.destinationurl");
if (destinationurl == null)
destinationurl = "/";
}

@Override
public Navigation beforeActionInvoke(ActionContext actionContext,
MethodDesc targetMethod, Object page, Object[] args) {

final HttpServletRequest request = actionContext.getRequest().getNativeResource();
final Session session = actionContext.getSession();
final String uri = request.getRequestURI();
final String url = request.getRequestURL().toString();

final UserService userService = UserServiceFactory.getUserService();
final User user = userService.getCurrentUser();

if (user == null) {
session.removeAttribute("logouturl");
session.removeAttribute("userID");
session.removeAttribute("email");
session.removeAttribute("nickname");

if (Pattern.compile(urlpattern).matcher(uri).matches()){
return Redirect.to(userService.createLoginURL(url));
} else {
return getPluginDefaultNavigation();
}
} else {
String logoutURL = userService.createLogoutURL(destinationurl);

if (!logoutURL.startsWith("http")){
Integer pos = url.indexOf(uri);
logoutURL = url.substring(0, pos) + logoutURL;
}

session.setAttribute("logouturl", logoutURL);
session.setAttribute("userID", user.getUserId());
session.setAttribute("email", user.getEmail());
session.setAttribute("nickname", user.getNickname());

return getPluginDefaultNavigation();
}
}
}

 
ローカルと本番での挙動が違うのもあってちょっとurlの取り扱いの所が怪しいかもしれない。
UserId,Email,NickNameをsession変数にセットすべきかどうか迷ったが一応書いておいた。
 
このPluginとほぼ同じことがFilterでもできるし、Filterの方はT2に依存していないので汎用性が高い。
この件はあまりPluginを使う良い例ではないなあ。
もうちょっと別のものを考えよう。