Oracle hat heute den Glassfish 3.1 freigegeben – gleichzeitig als Open Source und als Oracle Glassfish Edition. Es gibt eine Menge neues, und dazu gehören auch neue Probleme.

Ich verwende Glassfish schon seit geraumer Zeit um mittels „Continuous Deployment“ für aktuell entwickelte Anwendungen eine separate Umgebung zu haben, in der ich und Kollegen testen können. Das ganze funktioniert mittels eine CI-Servers (Hudson Jenkins in diesem Fall), Maven und einem Deploy Plugin.

Auch mit Glassfish 3.1 funktionierte das Deployment prima – also hier war kein Update von Jenkins oder dem Deploy Plugin erforderlich. Auch die Anwendung startete – jedoch funktionierte nichts. Exceptions über ungültige Sessions gab es, auch Log-Einträge vom hier für Ajax eingesetzten DWR (Direct Web Remoting)

2011-02-28 18:57:13,037 [http-thread-pool-8090(2)] ERROR o.d.dwrp.Batch - A request has been denied as a potential CSRF attack.
2011-02-28 19:03:02,105 [http-thread-pool-8090(5)] ERROR o.d.dwrp.Batch - A request has been denied as a potential CSRF attack.

Dank Firebug etwas schlauem Rumraten und Probieren fand ich dann heraus: Glassfish 3.1 setzt Session Cookies per Default auf „HTTP Only“. Dazu gibt es bereits ein Ticket im Glassfish Tracker: GLASSFISH-15730

Es gibt nun mehrere Möglichkeiten für die nötige Kompatibilität mit Bestandsanwendungen zu sorgen:

Wird man die Anwendung zukünftig immer in einem Servlet 3.0 kompatiblen Container deployen, so kann man in der web.xml das Verhalten umkonfigurieren:

<web-app>
  <session-config>
    <cookie-config>
      <http-only>true</http-only>
    </cookie-config>
  </session-config>
</web-app>

Alternativ kann man bei DWR den CSRF Check deaktivieren, wovon ich jedoch abraten würde:

<servlet>
  <servlet-name>dwr-invoker</servlet-name>
  <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
  <init-param>
    <param-name>crossDomainSessionSecurity</param-name>
    <param-value>false</param-value>
  </init-param>
</servlet>

Die letzte Möglichkeit ist – in diesem Fall – auf DWR 3 umzustellen, hier wurde das Problem grundsätzlich gelöst, so dass nicht mehr per JavaScript auf den Session Cookie zugegriffen werden muss. (Siehe DWR-26) Leider gibt es von DWR 3 bisher noch kein Release, sondern lediglich vorab-Versionen.

Das Problem tritt übrigens auch mit Tomcat 7 auf, und nicht nur mit Glassfish 3.1 – ich frage mich, ob dies Verhalten am Ende sogar in der Servlet 3 Spezifikation vorgegeben ist.
Natürlich betrifft dies nicht ausschließlich DWR, sondern auch andere Anwendungen, die per JavaScript auf den Session Cookie zugreifen wollen/müssen.