Search code examples
javascalaservletscookieslift

Modifying the default JSESSIONID cookie, Scala Lift Framework


My goal is to modify the default JSESSIONID cookie (the servlet cookie) but via the scala code.

It works just fine if I directly hard code the values in web.xml like below.

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

  <context-param>
    <param-name>org.eclipse.jetty.servlet.SessionDomain</param-name>
    <param-value>.subdomain.com</param-value>
  </context-param>

  <context-param>
    <param-name>org.eclipse.jetty.servlet.SessionCookie</param-name>
    <param-value>CustomID</param-value>
  </context-param>

  ...
</web-app>

but it does not work when I try to modify it via the scala code below, it is missing some steps I suppose.

Boot.scala

package bootstrap.liftweb

...
import org.eclipse.jetty.servlet.ServletContextHandler


/**
 * A class that's instantiated early and run.  It allows the application
 * to modify lift's environment
 */
class Boot {
  def boot {

    val context = new ServletContextHandler(ServletContextHandler.SESSIONS)
    context.setInitParameter("org.eclipse.jetty.servlet.SessionCookie", "CustomID")
    context.setInitParameter("org.eclipse.jetty.servlet.SessionDomain", ".subdomain.com")

    ...
  }
}

but the JSESSIONID cookie is still not modified.

I am trying to follow the following Stack Overflow question which kinda looks similar

Set Jetty session cookie name programmatically

According to this solution it is using a SessionHandler but I believe in my case I can't use it because I believe by the time Boot.scala executes the session is already created and looks like context.setSessionHandler(...) throws an error.

ServletContextHandler.java

...
public class ServletContextHandler extends ContextHandler
{   ...
    public void setSessionHandler(SessionHandler sessionHandler)
    {
        if (isStarted())
            throw new IllegalStateException("STARTED");

        _sessionHandler = sessionHandler;
    }
    ...
}

and I am not sure how I can hook it up.

I am using Lift 2.6 and Jetty 8.


Solution

  • I fixed it up like below.

    build.sbt

    ...
    
    libraryDependencies ++= {
      ...
      Seq(
        ...
        "org.eclipse.jetty" % "jetty-webapp"        % "8.1.17.v20150415"  % "container,test,compile",
        "org.eclipse.jetty.orbit" % "javax.servlet" % "3.0.0.v201112011016" % "container,test,compile" artifacts Artifact("javax.servlet", "jar", "jar"),
        ...
    
      )
    }
    
    ...
    

    Boot.scala

    ...
    
    import javax.servlet.http.HttpServletRequest
    import net.liftweb.http.provider.servlet.HTTPRequestServlet
    import org.eclipse.jetty.server.{Request=>JettyReq}
    
    class Boot {
      def boot {
    
        def servletRequest(req: Req): Box[HttpServletRequest] = for {
          inner <- Box.asA[HTTPRequestServlet](req.request)
        } yield inner.req
    
        def setCookieDomain(req: Req) = {
    
          servletRequest(req).foreach { r =>
          {
            val sessionManager = r.asInstanceOf[JettyReq].getSessionManager
            val cookieConfig = sessionManager.getSessionCookieConfig
    
            cookieConfig.setDomain(".subdomain.com")
          }
          }
        }
    
        LiftRules.onBeginServicing.append(setCookieDomain)
    
        ...
      }
    }