views:

152

answers:

1

I'm porting our Web authentication/authorization middleware for use in containers implementing the new servlet 3.0 API (Glassfish V3 in this case).

The middleware pulls cookies from the HttpServletRequest filtering on cookies with names of the form "DACS:FEDERATION::JURISDICTION:username". This works fine in the version 2.5 servlet API but is broken in 3.0.

The cookie names in 3.0 are being truncated at the first ":" in the name. I understand that the servlet 3.0 implementation defaults to RFC 2109 cookies which are more restrictive about cookie names than the old Netscape spec (":" is among the characters not allowed in RFC 2109 cookie names).

Digging into the servlet 3.0 source code, it appears that the use of RFC2109 names can be disabled by setting a System property "org.glassfish.web.rfc2109.cookie_names_enforced" to false. I've tried this to no avail. But besides that, the code that uses checks cookie names is in the constructor for Cookie, and it would appear that the truncation is occurring elsewhere.

So - finally - the question. Have others bumped into such issues in the servlet 3.0 API and have you found a work around?

A: 

Well, if all else fails, go back to basics...

The HttpServletRequest object contains a complete valid version 0 cookiename, so the request.getCookies() method can be by-passed.

For example, assuming we are using HttpClient 4 in our middleware (DacsCookie extends BasicClientCookie):

public static List<DacsCookie> getDacsCookies(Federation federation, Enumeration cookieHeaders) {
    String federationName = federation.getFederationName();
    String federationDomain = federation.getFederationDomain();
    List<DacsCookie> dacsCookies = new ArrayList<DacsCookie>();
    while (cookieHeaders.hasMoreElements()) {
        String cookieHeader = (String) cookieHeaders.nextElement();
        Pattern name = Pattern.compile("(DACS:[:\\w]+)=([-\\w]+)");
        Matcher m = name.matcher(cookieHeader);
        while (m.find()) {
            String cookieName = m.group(1);
            String cookieValue = m.group(2);
            DacsCookieName dacsCookieName = DacsCookieName.valueOf(cookieName);
            if (dacsCookieName != null && federationName.equals(dacsCookieName.getFederationPart())) {
                Jurisdiction jurisdiction = federation.getJurisdictionByName(dacsCookieName.getJurisdictionPart());
                dacsCookies.add(new DacsCookie(federationDomain, cookieName, cookieValue, jurisdiction.isSecure()));
            }
        }
    }
    return dacsCookies;
}

public static Enumeration getCookieHeaders(HttpServletRequest request) {
    return request.getHeaders("cookie");
}

I'm still interested to know if others have bumped into this problem either in Glassfish V3 or other containers.

idplmal