Task Description:
You are doing a java project under Tomcat. And they decided to organize the sections of their site in the form of subdomains.
For example, on the website
www.domen.xx make sections:
mail.domen.xx ,
user.domen.xx , etc. At some point in development, you will be surprised to find out that a user session, contrary to expectations, exists strictly within the same domain. That is, the user is authorized on the main page (
www.domen.xx ), passing mail (
mail.domen.xx ), loses authorization.
The point is that the session is attached to the client through a cookie called
JSESSIONID and with an empty domain. And when the domain is not specified, the browser uses the full current domain. That is, the session is not tied to “domen.xx”, but to “www.domen.xx”. For reasons unknown to me, there are no settings in Tomkat that allow you to control this behavior.
')
How to treat:
First, a little more about the session. Session is obtained by calling the request.getSession () method. Inside the method, the JSESSIONID cookie is read and the corresponding session is obtained from the “repository”. If there is no session, it is created and a cookie is written to the response header with the new JSESSIONID value. Here we appear! All you need is to add the desired domain value (
domen.xx ) to the
cookie .
Tomcat provides the valve mechanism (Valve). In fact, valve is a java-class that is called before each request is processed. And as the reader guesses, it is this mechanism that will be used in the implementation. We need to create a Valve class that will handle the session before processing each request. And to replace the cookie if the session has just been created.
Implementation:
Valve class:
package my.tomcat;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import org.apache.catalina.Globals;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
import org.apache.tomcat.util.http.ServerCookie;
public class SubdomainSessionValve extends ValveBase {
/** */
private static final String DOMAIN = "domain.xx" ;
@Override
public String getInfo() {
return "my.tomcat.SubdomainSessionValve/1.0a" ;
}
@Override
public void invoke(Request req, Response res)
throws IOException, ServletException {
fixSessionIdCookie(req);
getNext().invoke(req, res);
}
private void fixSessionIdCookie(Request request) {
if (getJsessionCookie(request.getCookies()) != null )
return ;
request.getSession();
Cookie cookie = getJsessionCookie(request.getResponse().getCookies());
if (cookie == null )
return ;
cookie.setDomain(DOMAIN);
StringBuffer sb = new StringBuffer();
ServerCookie.appendCookieValue(sb,
cookie.getVersion(), cookie.getName(), cookie.getValue(),
cookie.getPath(), cookie.getDomain(), cookie.getComment(),
cookie.getMaxAge(), cookie.getSecure());
request.getResponse().setHeader( "Set-Cookie" , sb.toString());
}
Cookie getJsessionCookie(Cookie[] cc) {
for ( int i = 0; cc != null && i < cc.length; i++) {
if (Globals.SESSION_COOKIE_NAME.equals(cc[i].getName()))
return cc[i];
}
return null ;
}
}
* This source code was highlighted with Source Code Highlighter .
It remains to put the jar with this class in $ {TOMCAT_HOME} / server / lib and register in server.xml:
<Valve className = "my.tomcat.SubdomainSessionValve" />
Or when starting the server from the application:
org.apache.catalina.Context context;
....... //
context.getPipeline().addValve( new my.tomcat.SubdomainSessionValve());
* This source code was highlighted with Source Code Highlighter .
Thanks for attention.
Good luck!