実装検討
- Filterを使ってログインしているかどうかを判定しアクセス制限する
- 画像やJavascriptやCSSファイルはOKにしたいので除外URIを設定できるようにする
- 除外URIは正規表現を使えるとうれしい(*ぐらいだけど・・・)
- ログイン用フォームを用意するしてそこからログインを行う
- ログインしているかどうかは確認用オブジェクトをSessionに入れて、そのオブジェクトの存在チェックで行う
- ログアウトではSessionを無効化する
ログインフィルタの作成
public class LoginFilter implements Filter {
private static final String CLASS_NAME = "LoginFilter";
private static final String USER_INFO = "USER_INFO";
private static final String EXCLUDE_PATH = "excludepath";
private static final String LOGIN_PATH = "loginpath";
private WebAppLogger logger = WebAppLogger.getInstance();
private String[] excludeArray;
private String loginPath;
public void init(FilterConfig config) throws ServletException {
logger.startLog(CLASS_NAME, "init");
//web.xmlからパラメタを読み込む
String excludePath = (String)config.getInitParameter(EXCLUDE_PATH);
loginPath= (String)config.getInitParameter(LOGIN_PATH);
//パスを分割
excludeArray = StringUtility.splitToArray(excludePath);
logger.trace(loginPath);
logger.trace(excludePath);
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
logger.startLog(CLASS_NAME, "doFilter");
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession session = (HttpSession) req.getSession();
if(session == null){
logger.trace("セッションがないのでログイン画面へ遷移");
res.sendRedirect(req.getContextPath() + loginPath);
return;
}
String target = req.getRequestURI();
logger.trace("target = " + target);
if(isExcludePath(target)){
logger.trace("除外URLなのでそのまま遷移");
chain.doFilter(req, res);
return;
}
UserInfo info = (UserInfo)session.getAttribute(USER_INFO);
logger.trace("UserInfo = " + info);
if(info == null){
logger.trace("ログインしていないのでログイン画面へ遷移");
res.sendRedirect(req.getContextPath() + loginPath);
return;
}
logger.trace("ログインしているのでそのまま遷移");
chain.doFilter(req, res);
return;
}
private boolean isExcludePath(String target) {
logger.startLog(CLASS_NAME, "isExcludePath");
//パターンとリクエストされているURLを比較して判定
for(int i = 0; i < excludeArray.length; i++){
Pattern pattern = Pattern.compile("^" + excludeArray[i]);
Matcher matcher = pattern.matcher(target);
if(matcher.matches()){
return true;
}
}
return false;
}
public void destroy() {
}
}
web.xml
excludepathには正規表現OKとする。
「/struts135/」はサンプルで作ったアプリのContextPath。これとログインページを除外に指定しないと、延々にリダイレクトが走って無限ループになっちゃう。
ディレクティブのerrorPageやStrutsのExceptionHandlerでの遷移は除外しなくてもフィルタを通らないらしい。
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>
com.daipresents.struts135.filter.LoginFilter
</filter-class>
<init-param>
<param-name>loginpath</param-name>
<param-value>/login/login.jsp</param-value>
</init-param>
<init-param>
<param-name>excludepath</param-name>
<param-value>
/struts135/,/struts135/index.jsp,/struts135/login/.*
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
ログインフォームの作成
public class LoginForm extends ActionForm implements Serializable{
private static final long serialVersionUID = -1302472848604305617L;
private String loginID;
private String password;
public String getLoginID() {
return loginID;
}
public void setLoginID(String loginID) {
this.loginID = loginID;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
ログインActionの作成
LookupDispatchActionを使ってみたけどいけてないので、普通のActionでいいと思う。
public class LoginAction extends LookupDispatchAction {
private static final String CLASS_NAME = "LoginAction";
private WebAppLogger logger = WebAppLogger.getInstance();
@Override
protected Map getKeyMethodMap() {
Map map = new HashMap();
map.put("login.login.button", "login");
map.put("menu.logout.button", "logout");
return map;
}
public ActionForward login(
ActionMapping map,
ActionForm form,
HttpServletRequest req,
HttpServletResponse res) {
logger.startLog(CLASS_NAME, "login");
LoginForm f = (LoginForm)form;
logger.trace(f.getLoginID());
logger.trace(f.getPassword());
HttpSession session = req.getSession();
if(session == null){
logger.trace("Sessionがありません");
return map.findForward("error");
}
session.setAttribute("USER_INFO", new UserInfo());
logger.trace("ログインしました");
return map.findForward("success");
}
public ActionForward logout(
ActionMapping map,
ActionForm form,
HttpServletRequest req,
HttpServletResponse res) {
logger.startLog(CLASS_NAME, "logout");
HttpSession session = req.getSession();
session.invalidate();
return map.findForward("success");
}
}
struts-config.xml
<form-beans> <form-bean name="LoginForm" type="com.daipresents.struts135.login.LoginForm" /> </form-beans> <global-forwards> <forward name="login" path="/login/login.jsp" /> <forward name="50XError" path="/WEB-INF/jsp/error/error50X.jsp" /> </global-forwards> <action-mappings> <action path="/login" type="com.daipresents.struts135.login.LoginAction" name="LoginForm" scope="request" parameter="method"> <forward name="success" path="top" /> <forward name="error" path="login" /> </action> <action path="/logout" type="com.daipresents.struts135.login.LoginAction" name="LoginForm" scope="request" parameter="method"> <forward name="success" path="login" /> <forward name="error" path="50XError" /> </action> </action-mappings>