struts下的多台web服务器登陆处理

单台web app 做登陆很简单,放到session里就可以。但稍微大的应用都是apache下挂着多台tomcat的,tomcat1的session 到tomcat2下就不管用了。tomcat间的session复制也比较费性能,我们尽量要保持web层的无状态。

上一篇apache_tomcat负载均衡配置完成后,我基于此业余做了基于struts的多台应用登陆/自动登陆处理,源码在附件中。

原理:
1、登陆后把信息用户名及密码加密放入cooekis(如果选择自动登陆),同时把User 对象放入session。下上文中通过session.getAttribute("User")来判断是否登陆
2、在访问时会有两个拦截器来处理
a.loginInterceptor
   从cookies中取得加密过的username和password,验证是否正确,将Uesr放入session
b.authInterceptor
   对需要登陆才能有的操作加入验证处理,如果没登陆将跳转到登陆页,登陆完成后跳转要操作的页面。

代码实现:

1、LoginInterceptor

/**
*
* 从cookies中恢复登陆
*
* @author 锅巴
* @version 1.0 2010-6-29
*/
public class LoginInterceptor implements Interceptor {  
   
    public final static String CRYPTO_PWD = "865azo@44536_t";
      
    private UserDAO userDAO;
 
 
    public String intercept(ActionInvocation arg0) throws Exception {
       
       
      
        printCookies();
       
        process(arg0);
    
        return arg0.invoke();
    }

   

    private void process(ActionInvocation arg0) throws Exception {
        Map session = arg0.getInvocationContext().getSession();
       
        if(session != null && session.get(Statics.USER_SESSION_KEY) != null){
            System.out.println("========== user is have in session ");
            return ;
        }
           
       
        HttpServletRequest request = ServletActionContext.getRequest();
        Cookie[] cookies = request.getCookies();
       
        if(cookies == null)
            return;
       
       
        for (Cookie cookie : cookies) {
            if (Statics.COOKIE_REMEMBERME_KEY.equals(cookie.getName())
                    && !StringUtils.isEmpty(cookie.getValue())) {
                String[] split = cookie.getValue().split("-");
                String userName = DESCrypto.decrypt(split[0],CRYPTO_PWD);
                String password = DESCrypto.decrypt(split[1],CRYPTO_PWD);
                try {
                    User user = userDAO.attemptLogin(userName, password);
                    session.put(Statics.USER_SESSION_KEY, user);
                } catch (UserNotFoundException e) {
                    
                }
            }
        }
    }  
   
   
    private void printCookies(){
        System.out.println("========= printCookies statrt ========");
        Cookie[] cookies = ServletActionContext.getRequest().getCookies();
        if(cookies != null){
            for(Cookie cook : cookies){
                System.out.println(cook.getName() + " : " + cook.getValue() + " : " + cook.getMaxAge() );
            }
        }
      
        System.out.println("========= printCookies end ========");
    }
   
 
      
   

    public UserDAO getUserDAO() {
        return userDAO;
    }

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    public void destroy() {
        // TODO Auto-generated method stub
       
    }

    public void init() {
        // TODO Auto-generated method stub
       
    }
}

2、AuthInterceptor

/**
* 必须验证要登陆的拦截器
* @author 锅巴
* @version 1.0 2010-6-29
*/
public class AuthInterceptor implements Interceptor{

    private final static String ACTH_ERROR_TO_URL = "forwardLogin";
  
    private static Log log = LogFactory.getLog(AuthInterceptor.class);
   
   
    public void destroy() {
        // TODO Auto-generated method stub
       
    }

    public void init() {
        // TODO Auto-generated method stub
       
    }

    public String intercept(ActionInvocation arg0) throws Exception {
        // TODO Auto-generated method stub
       Map session = arg0.getInvocationContext().getSession();
       if(session == null || session.get(Statics.USER_SESSION_KEY) == null){
           return getAuthErrorReturn(arg0);
       }
       
       return arg0.invoke();
    }
   
    private String getAuthErrorReturn(ActionInvocation arg0){
     
        HttpServletRequest request  =  ServletActionContext.getRequest();  
       
      
        String urlValue = request.getRequestURL().toString();
        if (request.getQueryString() != null)
            urlValue += "?" + request.getQueryString();
        request.setAttribute(Statics.AUTH_LOGIN_GO, urlValue);
        log.debug("urlValue:" + urlValue);
        return ACTH_ERROR_TO_URL;
    }
   

  
   
}

3、Login 登陆action

/**
*
* 描述
*
* @author 锅巴
* @version 1.0 2010-7-5
*/
public class LoginAction extends ActionSupport implements SessionAware,CookiesAware,ServletResponseAware,ServletRequestAware{

    private Map session;
   
    private Map cookie;
   
    private HttpServletResponse response;
   
    private UserDAO userDAO;
   
    private String username;
   
    private String password;
   
    private String goUrl;
   
    private HttpServletRequest request;
   
    private boolean rememberMe;
   
   
   
    public boolean isRememberMe() {
        return rememberMe;
    }



    public void setRememberMe(boolean rememberMe) {
        this.rememberMe = rememberMe;
    }



    @Override
    public void setServletRequest(HttpServletRequest arg0) {
        // TODO Auto-generated method stub
        this.request = arg0;
    }



    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

   
   
    public String getGoUrl() {
        return goUrl;
    }



    public void setGoUrl(String goUrl) {
        this.goUrl = goUrl;
    }



    public String getUsername() {
        return username;
    }



    public void setUsername(String username) {
        this.username = username;
    }



    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public void setServletResponse(HttpServletResponse arg0) {
        // TODO Auto-generated method stub
        this.response = arg0;
    }

    @Override
    public void setSession(Map arg0) {
        // TODO Auto-generated method stub
        this.session = arg0;
    }

    @Override
    public void setCookiesMap(Map arg0) {
        // TODO Auto-generated method stub
        this.cookie = arg0;
    }

    @Override
    public String execute() throws Exception {
        // TODO Auto-generated method stub
        return SUCCESS;
    }
   
   
   
    public String postLogin() throws Exception {
        User user = null;
        try{
            user = userDAO.attemptLogin(username, password);
        }catch(UserNotFoundException ex){
            addActionError("登陆失败!");
            return INPUT;
        }
       
        processCookie(user);
       
        return SUCCESS;
    }



    private void processCookie(User user) throws Exception {
        session.put(Statics.USER_SESSION_KEY, user);
       
        //cookie value 不能有==这种情况,不能ie会拒绝该cookies
        Cookie cookie = new Cookie(Statics.COOKIE_REMEMBERME_KEY, DESCrypto.desCrypto(username.getBytes(), LoginInterceptor.CRYPTO_PWD)+ "-" + DESCrypto.desCrypto(password.getBytes(), LoginInterceptor.CRYPTO_PWD));
        if (rememberMe){
            cookie.setMaxAge(60 * 60 * 24 * 14);
        }else{
            cookie.setMaxAge(0);
        }
        cookie.setPath("/");
        cookie.setDomain("t.com");
        response.addCookie(cookie);
    }

   
}

4、LoginOut 退出action

/**
*
* 描述
*
* @author 锅巴
* @version 1.0 2010-7-5
*/
public class LoginOutAction extends ActionSupport implements ServletResponseAware,ServletRequestAware{

    private HttpServletResponse response;
   
    private HttpServletRequest request;
   
   

    @Override
    public void setServletResponse(HttpServletResponse arg0) {
        // TODO Auto-generated method stub
        this.response=arg0;
    }

   
   
    @Override
    public void setServletRequest(HttpServletRequest arg0) {
        // TODO Auto-generated method stub
        this.request = arg0;
    }



    @Override
    public String execute() throws Exception {
        // TODO Auto-generated method stub
       
       
       
        Cookie[] cookies = request.getCookies();  
        if (cookies!=null) {  
            for (Cookie cookie : cookies) {  
                if (Statics.COOKIE_REMEMBERME_KEY.equals(cookie  
                        .getName())) {
                    //清除cookie时要与增加时步骤一致 如path,domain
                    cookie.setPath("/");
                    cookie.setDomain("t.com");
                    cookie.setValue("");  
                    cookie.setMaxAge(0);  
                    response.addCookie(cookie);
                }  
            }  
        }  

        HttpSession session = request.getSession(false);  
        if (session!=null)  
            session.removeAttribute(Statics.USER_SESSION_KEY);  
       
   
        System.out.println("============== login out ================");
        return SUCCESS;
    }

   
}

5、struts.xml配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

<package name="default" namespace="/" extends="struts-default">

<interceptors>  
            <interceptor name="loginInterceptor" class="com.my.interceptor.LoginInterceptor"></interceptor>
            <interceptor name="authInterceptor" class="com.my.interceptor.AuthInterceptor"></interceptor>  
           
         
            <!-- 默认拦截器堆栈 -->
            <interceptor-stack name="loginDefaultStack">
            <interceptor-ref name="loginInterceptor"></interceptor-ref>    
                <interceptor-ref name="authInterceptor"></interceptor-ref>  
                <interceptor-ref name="defaultStack"></interceptor-ref>  
            </interceptor-stack>
           
            <!-- 需要登陆验证的拦截器堆栈 -->
            <interceptor-stack name="autowireDefault">
            <interceptor-ref name="loginInterceptor"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>  
            </interceptor-stack>
              
        </interceptors>
       
        <default-interceptor-ref name="autowireDefault"></default-interceptor-ref>
       
        <global-results>
        <!-- 验证未通过跳转全局result -->  
            <result name="forwardLogin" type="chain">
            <param name="actionName">forwardLogin</param>
           <param name="namespace">/common</param>
    </result>  
        </global-results>

</package>

<include file="struts-conf/common.struts.xml"></include>
</struts>

6、common.struts.xml 配置
  <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

<package name="common" namespace="/common" extends="default">

<!--  跳转登录 -->
<action name="forwardLogin" class="com.my.action.JumpLoginAction">
<result name="success" type="redirect">
/common/login.html?goUrl=${goUrl}
</result>
</action>

<!-- 登陆页面 -->
<action name="login" class="com.my.action.LoginAction">
<result name="success" type="dispatcher">
/common/login.jsp
</result>
</action>

<!-- 退出 -->
<action name="loginOut" class="com.my.action.LoginOutAction">
<result name="success" type="dispatcher">
/common/login_out.jsp
</result>
</action>

<!-- 登陆post操作 -->
<action name="postLogin" class="com.my.action.LoginAction" method="postLogin">
<result name="success" type="redirect">
${goUrl}
</result>
<result name="input" type="dispatcher">
/common/login.jsp
</result>
<interceptor-ref name="autowireDefault" />
<interceptor-ref name="validationWorkflowStack" />
</action>

<!-- 需要登陆验证的页面 -->
<action name="home" class="com.my.action.HomeAction">
<result name="success" type="dispatcher">
/index.jsp
</result>
<interceptor-ref name="loginDefaultStack" />
</action>

</package>
</struts>

注意事项:

1、LoginAction-postLogin-validation.xml ,可以按action 方法名来验证。
2、cookies 中不能含有"==",否则IE会写不进去。
3、写cookies与清cookies的操作要完全一致,否则清不了。
   如:              
   写cookies
    //cookie value 不能有==这种情况,不能ie会拒绝该cookies
    Cookie cookie = new Cookie(Statics.COOKIE_REMEMBERME_KEY, DESCrypto.desCrypto(username.getBytes(), LoginInterceptor.CRYPTO_PWD)+ "-" + DESCrypto.desCrypto(password.getBytes(), LoginInterceptor.CRYPTO_PWD));
        if (rememberMe){
            cookie.setMaxAge(60 * 60 * 24 * 14);
        }else{
            cookie.setMaxAge(0);
        }
        cookie.setPath("/");
        cookie.setDomain("t.com");
        response.addCookie(cookie);

    清cookies
                    cookie.setPath("/");
                    cookie.setDomain("t.com");
                    cookie.setValue("");  
                    cookie.setMaxAge(0);  
                    response.addCookie(cookie); 

   

 

你可能感兴趣的:(tomcat,应用服务器,Web,struts,IE)