设为首页 收藏本站
查看: 235|回复: 0

[经验分享] Tomcat实现多域名之间session共享

[复制链接]

尚未签到

发表于 2017-1-27 13:26:10 | 显示全部楼层 |阅读模式
最近启用二级域名后,面临一个主域名与二级域名之间 session 不能共享的问题,带来的麻烦就是用户在主域名登陆,但由于二级域名 session 不能共享 ,因此无法进行登陆的操作,对一些功能有一些影响。
问题的原因如下
Tomcat 下,不同的二级域名,Session 默认是不共享的,因为 Cookie 名称为 JSESSIONID 的 Cookie 根域是默认是没设置的,访问不同的二级域名,其 Cookie 就重新生成,而 session 就是根据这个 Cookie 来生成的,所以在不同的二级域名下生成的 Session 也不一样。
找到了其原因,就可根据这个原因对 Tomcat 在生成 Session 时进行相应的修改。
快速解决方案1
在项目的/MET-INF/ 目录下创建一个 context.xml 文件,内容为:


1 2

<?xml version="1.0" encoding="UTF-8"?> 
<Context useHttpOnly="true" sessionCookiePath="/"sessionCookieDomain=".XXXX.com" />



Done!
快速解决方案2:修改 Tomcat 的 server.xml 文件,内容为:


1

<Context path="" docBase="ROOT" reloadable="false"
 useHttpOnly="true"sessionCookiePath="/" sessionCookieDomain=".XXXX.com" />




Done!
以上两种方案的详细讲解见:http://tomcat.apache.org/tomcat-6.0-doc/config/context.html

快速解决方案3
:生成一个叫做 crossSubdomainSessionValve.jar 的文件,用的时候放在 Tomcat lib 目录下,然后修改 Tomcat server.xml 文件:


1

<Valve className="me.seanchang.CrossSubdomainSessionValve" />





原理:取代由 Tomcat 域产生的会话 cookie ,允许该会话 cookie 跨子域共享。
代码:

 
package me.seanchang; import java.io.IOException; import java.util.logging.Level; importjava.util.logging.Logger; import javax.servlet.ServletException; importjavax.servlet.http.Cookie; import org.apache.catalina.Globals; importorg.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; importorg.apache.catalina.valves.ValveBase; import org.apache.tomcat.util.buf.MessageBytes; importorg.apache.tomcat.util.http.MimeHeaders; import org.apache.tomcat.util.http.ServerCookie; publicclass CrossSubdomainSessionValve extends ValveBase { private static Logger log =Logger.getLogger("CrossSubdomainSessionValve"); public CrossSubdomainSessionValve() { super();info = "me.seanchang.CrossSubdomainSessionValve/1.0"; } @Override public void invoke(Requestrequest, Response response) throws IOException, ServletException { // this will cause Request.doGetSession to create the session cookie if // necessary request.getSession(true); // replace any Tomcat-generated session cookies with our own Cookie[] cookies =response.getCookies(); if (cookies != null) { for (int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; log.info("CrossSubdomainSessionValve: Cookie name is " + cookie.getName());if (Globals.SESSION_COOKIE_NAME.equals(cookie.getName())) replaceCookie(request, response, cookie); } } // process the next valve getNext().invoke(request, response); } protected voidreplaceCookie(Request request, Response response, Cookie cookie) { // copy the existing session cookie, but use a different domain Cookie newCookie = new Cookie(cookie.getName(), cookie.getValue()); if(cookie.getPath() != null) newCookie.setPath(cookie.getPath());newCookie.setDomain(getCookieDomain(request)); newCookie.setMaxAge(cookie.getMaxAge());newCookie.setVersion(cookie.getVersion()); if (cookie.getComment() != null)newCookie.setComment(cookie.getComment()); newCookie.setSecure(cookie.getSecure()); // if the response has already been committed, our replacement strategy // will have no effect MimeHeaders headers = new MimeHeaders(); if (response.isCommitted()) log.info("CrossSubdomainSessionValve: response was already committed!"); // find the Set-Cookie header for the existing cookie and replace its // value with new cookie headers = response.getCoyoteResponse().getMimeHeaders(); for(int i = 0, size = headers.size(); i < size; i++) { if (headers.getName(i).equals("Set-Cookie")){ MessageBytes value = headers.getValue(i); if (value.indexOf(cookie.getName()) >= 0) {StringBuffer buffer = new StringBuffer(); ServerCookie .appendCookieValue(buffer, newCookie.getVersion(), newCookie.getName(), newCookie.getValue(), newCookie.getPath(), newCookie.getDomain(), newCookie.getComment(), newCookie.getMaxAge(), newCookie.getSecure(),true); log.info("CrossSubdomainSessionValve: old Set-Cookie value: " + value.toString());log.info("CrossSubdomainSessionValve: new Set-Cookie value: " + buffer);value.setString(buffer.toString()); } } } } protected String getCookieDomain(Request request) {String cookieDomain = request.getServerName(); String[] parts = cookieDomain.split("\\."); if(parts.length >= 2) cookieDomain = parts[parts.length - 2] + "." + parts[parts.length - 1];return "." + cookieDomain; } public String toString() turn ("CrossSubdomainSessionValve[container="+ container.getName() + ']'); } }



将以上代码导出一个jar文件,放入 $CATALINA_HOME/lib 中,修改 $CATALINA_HOME/conf/server.xml 文件,加入


1

<Valve className="me.seanchang.CrossSubdomainSessionValve" />



重启 Tomcat ,Done !

 

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-334132-1-1.html 上篇帖子: JBOSS和tomcat各自特点和优势 下篇帖子: 关于ClassLoader In Tomcat 的研究
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表