結論から言うと AbstractPlugin を継承したもので行うというのが今のところよいと考えています。
Servlet ではもっとも王道なやり方であろうフィルターは、ある URL 以下を一括で処理が行えることがメリットだと感じています。複数あれば URL をそれぞれ指定する必要がありますが Servlet 2.5 なら url-pattern も複数登録でき負担は減りそうです。
欠点としては公開用と非公開用ふたつの URL を別々にする必要があります。ある URL 以下の特定のものだけ認証をかけたくない場合つらいです。認証フィルターで URL をみて除外するコードをかくことになりそうです。
フィルターはアプリケーションが認証前提、またはある URL 以下をごっそり認証させたい場合はよいと思いますが、 URL が冗長になってしまい融通が利かないのが個人的につらいところです。
一方 Cubby は Plugin 機構を提供していてカスタマイズできます。 AbstractPlugin を継承してつくるのですが、 Plugin ではルーティングが決まったあとのアクションクラスに対して処理が行えます。認証用のアノテーションをつくってアクションのメソッドとクラスにつけられるようにしておくと、ある URL 以下の特定のパスにだけ認証をかけるといったことにも柔軟に対応ができます。
欠点はアクションの初期化直後に処理を行うので、その前のフィルターなどで認証情報を利用する場合は別途処理を書くことになります。また Action#initialize を使用している場合も、先にこちらが呼ばれますので注意が必要です。
すごく大ざっぱですが、認証処理を行うときの Action の流れは以下のようになると思います。
じゃあ Plugin ってどうつくるの?というのは [cubby-user:182] Re: Action#initialize への Interceptor 適用 に書かれています。 /src/main/resources など、クラスパスが通っている直下に /resources/META-INF/services/org.seasar.cubby.plugin.Plugin というファイルを作成後、一行おきに作成した Plugin クラス名を記述すればよいです。
net.pshared.example.plugin.AuthPlugin
package net.pshared.example.plugin;
public class AuthPlugin extends AbstractPlugin {
/**
* {@inheritDoc}
*/
@Override
public ActionResult invokeAction(ActionInvocation invocation) throws Exception {
ActionContext actionContext = invocation.getActionContext();
Class<?> actionClass = actionContext.getActionClass();
Method actionMethod = actionContext.getActionMethod();
if (認証対象処理) { // 対象のアノテーションやクラスであるか
if (認証検証) {
return new Redirect(Login.class);
}
}
return super.invokeAction(invocation);
}
}
ActionResult を返す仕組みなので認証エラー時に Redirect クラスを new します。 Class で指定できるのでリファクタリングに強いです。メソッド名もできるといいのですが、 GET のデフォルトのメソッド名を index にしておくと楽になります。
そんなわけで Cubby では Filter はごっそりかける場合、そうでない認証は Plugin でカスタマイズするのがよさげなのかなと思いました。