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
@param signinPage
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;
}
認証チェック.
@param component
@param action
@Override
public boolean isActionAuthorized(Component component, Action action){
if (authenticatedPage.isAssignableFrom(component.getClass())){
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
@param overtimeLimit
public AuthSession(Request request, int overtimeLimit){
super(request);
this.overtimeLimit = overtimeLimit;
actionTime = LocalDateTime.now();
}
認証済問い合わせ.
@return
public boolean isAuth(){
return auth;
}
認証済を初期化(認証否にする).
public void initAuth(){
auth = false;
}
認証済セット.
@param isAuth
public void setAuth(){
auth = true;
actionTime = LocalDateTime.now();
}
一定時間経過後の実行問い合わせ.
@return
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){
super(request, 10);
}
認証済セット.
@param isAuth
public void setAuthId(String authid){
setAuth();
this.authid = authid;
}
public String getAuthid(){
return authid;
}
}
ログイン(サインイン)のページで、認証した時に以下を実行
((MySession)getSession()).setAuthId(login);
WebApplication の init() で、AuthorizationStrategy を登録
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 によるタイマーを仕掛ける。
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
に入れてある。