wicket-auth-roles を使った認証済をチェックするのは、@AuthorizeInstantiation
で指定する役割 Role で制御して機能も Page だけでなく、
Panel やコンポーネントにも指定できて機能は優れている。
でも、そこまでの機能が不要で単純な 認証済をチェックしたアクセス制限のページを
作る場合にどうしたら良いか?
org.apache.wicket.authorization.IAuthorizationStrategy を実装した認証ストラテジーを
実装して WebApplication の init() で認証チェックが働くように仕掛ける。
認証済か否かと、セッションの期間有効期限をチェックする処理を
IAuthorizationStrategy 実装で行う。
WebSession 実装クラスで認証済を保存する。
コードは、
package org.yipuran.wicketcustom.auth; import org.apache.wicket.Component; import org.apache.wicket.RestartResponseAtInterceptPageException; import org.apache.wicket.Session; import org.apache.wicket.authorization.Action; import org.apache.wicket.authorization.IAuthorizationStrategy; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.request.component.IRequestableComponent; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.request.resource.IResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 認証 Strategy. */ public class AuthorizationStrategy implements IAuthorizationStrategy{ private Class<? extends WebPage> authenticatedPage; private Class<? extends WebPage> signinPage; Logger logger = LoggerFactory.getLogger(this.getClass()); /** * コンストラクタ. * @param authenticatedPage 認証済の基底 WebPage class * @param signinPage 認証を行う WebPage class */ public AuthorizationStrategy(Class<? extends WebPage> authenticatedPage , Class<? extends WebPage> signinPage){ this.authenticatedPage = authenticatedPage; this.signinPage = signinPage; } @Override public <T extends IRequestableComponent> boolean isInstantiationAuthorized(Class<T> component){ return true; } /** * 認証チェック. * セッションに認証済か問い合わせて認証済なら trueを返す。認証できないまたは有効期限切れは * RestartResponseAtInterceptPageException でコンストラクタで指定した signinPage に遷移する * @param component Component * @param action Action */ @Override public boolean isActionAuthorized(Component component, Action action){ if (authenticatedPage.isAssignableFrom(component.getClass())){ // セッションに認証済か問い合わせて認証済なら true if (((AuthSession)Session.get()).isAuth()){ if (((AuthSession)Session.get()).overtime()){ // セッション有効切れ throw new RestartResponseAtInterceptPageException(signinPage); } return true; }else{ throw new RestartResponseAtInterceptPageException(signinPage); } } return true; } @Override public boolean isResourceAuthorized(IResource resource, PageParameters parameters){ if (((AuthSession)Session.get()).isAuth()){ if (((AuthSession)Session.get()).overtime()){ return false; } return true; } return true; } }
WebSession のベース
package org.yipuran.wicketcustom.auth; import java.time.Duration; import java.time.LocalDateTime; import org.apache.wicket.protocol.http.WebSession; import org.apache.wicket.request.Request; /** * 認証チェック機能 WebSession. */ public class AuthSession extends WebSession{ private boolean auth = false; private LocalDateTime actionTime; private int overtimeLimit = 1800; /** * コンストラクタ. * @param request org.apache.wicket.request * @param overtimeLimit セッション有効期限 秒単位指定 */ public AuthSession(Request request, int overtimeLimit){ super(request); this.overtimeLimit = overtimeLimit; actionTime = LocalDateTime.now(); } /** * 認証済問い合わせ. * @return true=認証済 */ public boolean isAuth(){ return auth; } /** * 認証済を初期化(認証否にする). */ public void initAuth(){ auth = false; } /** * 認証済セット. setAuth() 実行の都度、有効期間の経過時間は初期化される。 * @param isAuth ログイン成功したら true をセットする */ public void setAuth(){ auth = true; actionTime = LocalDateTime.now(); } /** * 一定時間経過後の実行問い合わせ. * @return true=時間経過している。 */ public boolean overtime(){ if (Duration.between(actionTime, LocalDateTime.now()).getSeconds() > overtimeLimit){ return true; } actionTime = LocalDateTime.now(); return false; } }
AuthSession を継承して実際に管理する WebSession を用意
import org.apache.wicket.request.Request; import org.yipuran.wicketcustom.auth.AuthSession; /** * MySession */ public class MySession extends AuthSession{ private String authid; public MySession(Request request){ // ページの有効期限 10秒 super(request, 10); } /** * 認証済セット. * @param isAuth ログイン成功したら true をセットする */ public void setAuthId(String authid){ setAuth(); this.authid = authid; } public String getAuthid(){ return authid; } }
ログイン(サインイン)のページで、認証した時に以下を実行
((MySession)getSession()).setAuthId(login);
WebApplication の init() で、AuthorizationStrategy を登録
// BasePage 認証済チェック対象の基底のWebPageクラス // LoginPage 認証を行うWebPageクラス getSecuritySettings() .setAuthorizationStrategy(new AuthorizationStrategy(BasePage.class, LoginPage.class));
WebApplication でMySession を使用するように宣言
@Override public Session newSession(Request request, Response response){ return new MySession(request); }
さらに、表示したままアクション(forn送信、ページ遷移、イベント)を一定期間実行しなければ
AuthorizationStrategy の overtime がセッションの有効期間を超えたら認証ページに遷移する
ように、AjaxSelfUpdatingTimerBehavior によるタイマーを仕掛ける。
// 20秒後に AjaxSelfUpdatingTimerBehavior queue(new Label("mark", "") .add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(20))));
↑ 何もページに表示しない Label コンポーネントで充分
<div wicket:id="mark"></div>
これら、AuthorizationStrategy と AuthSession は、
既にライブラリ
GitHub - yipuran/yipuran-wicketcustom: Wicket custom Library
に入れてある。