struts2中使用拦截器(Interceptor)控制登录和权限

[复制链接]
查看11 | 回复7 | 2007-10-20 08:38:44 | 显示全部楼层 |阅读模式
在jsp servlet中我们通常使用Servlet Filter控制用户是否登入, 是否有权限转到某个页面。在struts2中我们应该会想到他的拦截器(Interceptor), Interceptor在struts2中起着非常重要的作用。 很多struts2中的功能都是使用Interceptor实现的。
需求:简单的登入界面,让用户输入用户名、密码、记住密码(remember me)。 如果用户选中remember me的话, 下次就不需要再登入了(使用cookie实现, 用需要点击logout取消remeber me功能)。 如果用户起始输入的地址不是登入页面的话,在用户登入之后需要转到用户输入的起始地址。
我们先看看LoginInterceptor.java
Java代码
package com.javaeye.dengyin2000.wallet.interceptor;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.StrutsStatics;
import com.javaeye.dengyin2000.wallet.dao.UserDAO;
import com.javaeye.dengyin2000.wallet.dao.UserNotFoundException;
import com.javaeye.dengyin2000.wallet.domains.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class LoginInterceptor extends AbstractInterceptor {
public static final String USER_SESSION_KEY="wallet.session.user";
public static final String COOKIE_REMEMBERME_KEY="wallet.cookie.rememberme";
public static final String GOING_TO_URL_KEY="GOING_TO";

private UserDAO userDao;
@Override
public String intercept(ActionInvocation invocation) throws Exception {

ActionContext actionContext = invocation.getInvocationContext();
HttpServletRequest request= (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);

Map session = actionContext.getSession();
if (session != null && session.get(USER_SESSION_KEY) != null){

return invocation.invoke();
}

Cookie[] cookies = request.getCookies();
if (cookies!=null) {

for (Cookie cookie : cookies) {

if (COOKIE_REMEMBERME_KEY.equals(cookie.getName())) {

String value = cookie.getValue();

if (StringUtils.isNotBlank(value)) {

String[] split = value.split("==&quot

;

String userName = split[0];

String password = split[1];

try {

User user = userDao

.attemptLogin(userName, password);

session.put(USER_SESSION_KEY, user);

} catch (UserNotFoundException e) {

setGoingToURL(session, invocation);

return "login";

}

} else {

setGoingToURL(session, invocation);

return "login";

}

return invocation.invoke();

}

}
}
setGoingToURL(session, invocation);
return "login";
}
private void setGoingToURL(Map session, ActionInvocation invocation){
String url = "";
String namespace = invocation.getProxy().getNamespace();
if (StringUtils.isNotBlank(namespace) && !namespace.equals("/&quot

){

url = url + namespace;
}
String actionName = invocation.getProxy().getActionName();
if (StringUtils.isNotBlank(actionName)){

url = url + "/" + actionName + ".action";
}
session.put(GOING_TO_URL_KEY, url);
}

public UserDAO getUserDao() {
return userDao;
}
public void setUserDao(UserDAO userDao) {
this.userDao = userDao;
}
}
package com.javaeye.dengyin2000.wallet.interceptor;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.StrutsStatics;
import com.javaeye.dengyin2000.wallet.dao.UserDAO;
import com.javaeye.dengyin2000.wallet.dao.UserNotFoundException;
import com.javaeye.dengyin2000.wallet.domains.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class LoginInterceptor extends AbstractInterceptor {

public static final String USER_SESSION_KEY="wallet.session.user";

public static final String COOKIE_REMEMBERME_KEY="wallet.cookie.rememberme";

public static final String GOING_TO_URL_KEY="GOING_TO";



private UserDAO userDao;

@Override

public String intercept(ActionInvocation invocation) throws Exception {



ActionContext actionContext = invocation.getInvocationContext();

HttpServletRequest request= (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);



Map session = actionContext.getSession();

if (session != null && session.get(USER_SESSION_KEY) != null){

return invocation.invoke();

}



Cookie[] cookies = request.getCookies();

if (cookies!=null) {

for (Cookie cookie : cookies) {

if (COOKIE_REMEMBERME_KEY.equals(cookie.getName())) {

String value = cookie.getValue();

if (StringUtils.isNotBlank(value)) {

String[] split = value.split("==&quot

;

String userName = split[0];

String password = split[1];

try {

User user = userDao

.attemptLogin(userName, password);

session.put(USER_SESSION_KEY, user);

} catch (UserNotFoundException e) {

setGoingToURL(session, invocation);

return "login";

}

} else {

setGoingToURL(session, invocation);

return "login";

}

return invocation.invoke();

}

}

}

setGoingToURL(session, invocation);

return "login";

}

private void setGoingToURL(Map session, ActionInvocation invocation){

String url = "";

String namespace = invocation.getProxy().getNamespace();

if (StringUtils.isNotBlank(namespace) && !namespace.equals("/&quot

){

url = url + namespace;

}

String actionName = invocation.getProxy().getActionName();

if (StringUtils.isNotBlank(actionName)){

url = url + "/" + actionName + ".action";

}

session.put(GOING_TO_URL_KEY, url);

}



public UserDAO getUserDao() {

return userDao;

}

public void setUserDao(UserDAO userDao) {

this.userDao = userDao;

}
}
首先判断session中有没有用户信息, 如果有的话继续, 如果没有的话,检查cookie中有没有rememberme的值,如果有的话,用==分割, 取得用户名密码进行登入。如果没有这个用户的话,记录下request的action地址然后转到登入页面。如果验证有这个用户,则继续下面的interceptor。 如果cookie中没有信息的话,则记录request的action地址然后转到登入页面。 以上就是LoginInterceptor的全部代码。
下面我们看看struts.xml
Java代码



















/login.jsp




/index.jsp





${goingToURL}

/login.jsp






/login.jsp

/register.jsp




























/login.jsp





/index.jsp









${goingToURL}

/login.jsp









/login.jsp

/register.jsp







我们是使用的默认的interceptor stack是loginInterceptor, 如果你需要让不登入的用户也能访问的话,你需要配置你的action使用defaultStack。 我们这里的login, register使用的就是defaultStack。 这里要注意的是success的result是我们用LoginInterceptor设过来的值。 这样我们就能够转到用户输入的起始页面。 下面我们再来看看login.jsp 和 loginAction
Java代码





Wallet-Login


Login








[url=]Register[/url]







Wallet-Login

Login





[url=]Register[/url]


Java代码
package com.javaeye.dengyin2000.wallet.actions;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.interceptor.CookiesAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import com.javaeye.dengyin2000.wallet.dao.UserDAO;
import com.javaeye.dengyin2000.wallet.dao.UserNotFoundException;
import com.javaeye.dengyin2000.wallet.domains.User;
import com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport implements ServletResponseAware, ServletRequestAware, SessionAware, CookiesAware{
private UserDAO userDao;
private String loginName;
private String password;
private boolean rememberMe;
private HttpServletResponse response;
private HttpServletRequest request;
private Map session;
private Map cookies;
private String goingToURL;
public String getGoingToURL() {
return goingToURL;
}
public void setGoingToURL(String goingToURL) {
this.goingToURL = goingToURL;
}
public boolean isRememberMe() {
return rememberMe;
}
public void setRememberMe(boolean rememberMe) {
this.rememberMe = rememberMe;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}


public String login()throws Exception{
try {

User user = userDao.attemptLogin(loginName, password);

if (rememberMe){

Cookie cookie = new Cookie(LoginInterceptor.COOKIE_REMEMBERME_KEY, user.getLoginName() + "==" + user.getPassword());

cookie.setMaxAge(60 * 60 * 24 * 14);

response.addCookie(cookie);

}

session.put(LoginInterceptor.USER_SESSION_KEY, user);

String goingToURL = (String) session.get(LoginInterceptor.GOING_TO_URL_KEY);

if (StringUtils.isNotBlank(goingToURL)){

setGoingToURL(goingToURL);

session.remove(LoginInterceptor.GOING_TO_URL_KEY);

}else{

setGoingToURL("index.action&quot

;

}

return SUCCESS;
} catch (UserNotFoundException e) {

addActionMessage("user name or password is not corrected.&quot

;

return INPUT;
}
}
public UserDAO getUserDao() {
return userDao;
}
public void setUserDao(UserDAO userDao) {
this.userDao = userDao;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public void setSession(Map session) {
this.session = session;
}
public void setCookiesMap(Map cookies) {
this.cookies = cookies;
}
}
package com.javaeye.dengyin2000.wallet.actions;
import java.util.Map;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.interceptor.CookiesAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import com.javaeye.dengyin2000.wallet.dao.UserDAO;
import com.javaeye.dengyin2000.wallet.dao.UserNotFoundException;
import com.javaeye.dengyin2000.wallet.domains.User;
import com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport implements ServletResponseAware, ServletRequestAware, SessionAware, CookiesAware{

private UserDAO userDao;

private String loginName;

private String password;

private boolean rememberMe;

private HttpServletResponse response;

private HttpServletRequest request;

private Map session;

private Map cookies;

private String goingToURL;

public String getGoingToURL() {

return goingToURL;

}

public void setGoingToURL(String goingToURL) {

this.goingToURL = goingToURL;

}

public boolean isRememberMe() {

return rememberMe;

}

public void setRememberMe(boolean rememberMe) {

this.rememberMe = rememberMe;

}

public String getLoginName() {

return loginName;

}

public void setLoginName(String loginName) {

this.loginName = loginName;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}





public String login()throws Exception{

try {

User user = userDao.attemptLogin(loginName, password);

if (rememberMe){

Cookie cookie = new Cookie(LoginInterceptor.COOKIE_REMEMBERME_KEY, user.getLoginName() + "==" + user.getPassword());

cookie.setMaxAge(60 * 60 * 24 * 14);

response.addCookie(cookie);

}

session.put(LoginInterceptor.USER_SESSION_KEY, user);

String goingToURL = (String) session.get(LoginInterceptor.GOING_TO_URL_KEY);

if (StringUtils.isNotBlank(goingToURL)){

setGoingToURL(goingToURL);

session.remove(LoginInterceptor.GOING_TO_URL_KEY);

}else{

setGoingToURL("index.action&quot

;

}

return SUCCESS;

} catch (UserNotFoundException e) {

addActionMessage("user name or password is not corrected.&quot

;

return INPUT;

}

}

public UserDAO getUserDao() {

return userDao;

}

public void setUserDao(UserDAO userDao) {

this.userDao = userDao;

}

public void setServletResponse(HttpServletResponse response) {

this.response = response;

}

public void setServletRequest(HttpServletRequest request) {

this.request = request;

}

public void setSession(Map session) {

this.session = session;

}

public void setCookiesMap(Map cookies) {

this.cookies = cookies;

}
}

差不多就是这么多代码了。 最后看看logoutAction
Java代码
package com.javaeye.dengyin2000.wallet.actions;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor;
import com.opensymphony.xwork2.ActionSupport;
public class LogoutAction extends ActionSupport implements ServletRequestAware , ServletResponseAware{
private HttpServletRequest request;
private HttpServletResponse response;
public String execute() throws Exception{
HttpSession session = request.getSession(false);
if (session!=null)

session.removeAttribute(LoginInterceptor.USER_SESSION_KEY);

Cookie[] cookies = request.getCookies();
if (cookies!=null) {

for (Cookie cookie : cookies) {

if (LoginInterceptor.COOKIE_REMEMBERME_KEY.equals(cookie

.getName())) {

cookie.setValue("&quot

;

cookie.setMaxAge(0);

response.addCookie(cookie);

return "login";

}

}
}
return "login";
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
}
package com.javaeye.dengyin2000.wallet.actions;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor;
import com.opensymphony.xwork2.ActionSupport;
public class LogoutAction extends ActionSupport implements ServletRequestAware , ServletResponseAware{

private HttpServletRequest request;

private HttpServletResponse response;

public String execute() throws Exception{

HttpSession session = request.getSession(false);

if (session!=null)

session.removeAttribute(LoginInterceptor.USER_SESSION_KEY);



Cookie[] cookies = request.getCookies();

if (cookies!=null) {

for (Cookie cookie : cookies) {

if (LoginInterceptor.COOKIE_REMEMBERME_KEY.equals(cookie

.getName())) {

cookie.setValue("&quot

;

cookie.setMaxAge(0);

response.addCookie(cookie);

return "login";

}

}

}

return "login";

}

public void setServletRequest(HttpServletRequest request) {

this.request = request;

}

public void setServletResponse(HttpServletResponse response) {

this.response = response;

}
}
这里需要注意的是需要把cookie也清理下。
applicationContext-struts.xml
Java代码






-->

















回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
我有个小小的问题想问一下,那个cookie为什么要存为
["wallet.cookie.rememberme" : "username==password"]的形式?
直接存为["username" : "password"]不是更方便吗?
服务器好像会根据域名只拿它自己写到客户端的cookie吧?
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
这个没有关系。 你想怎么存就怎么存, 只要你能拿到username 和password
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
每个文件都写了两遍...
ps:itpubbbs...未登录发言,登录,跳转后竟然显示此论坛只允许特定用户发言...bugbug
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
出于安全考虑,不应该把密码这种敏感数据保存在客户端cookie
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
非常感谢,正是我想要的
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
先看看
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
这类东西首先要明确截取器模式,至于用它实现什么都不是问题!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行