我正在移植我们的Web身份验证/授权中间件,以便在实现新servlet 3.0 API的容器中使用(在本例中为Glassfish V3)。
中间件从名为“DACS:FEDERATION :: JURISDICTION:username”的cookie上的HttpServletRequest过滤中提取cookie。这在版本2.5 servlet API中工作正常,但在3.0中已经破解。
3.0中的cookie名称在名称的第一个“:”处被截断。据我所知,servlet 3.0实现默认使用RFC 2109 cookie,这些cookie对cookie名称的限制比旧的Netscape规范更严格(“:”是RFC 2109 cookie名称中不允许的字符之一)。
深入研究servlet 3.0源代码,似乎可以通过将System属性“org.glassfish.web.rfc2109.cookie_names_enforced”设置为false来禁用RFC2109名称。我试过这个无济于事。但除此之外,使用检查cookie名称的代码在Cookie的构造函数中,并且看起来截断正在其他地方发生。
所以 - 最后 - 问题。让其他人在servlet 3.0 API中遇到这样的问题,你找到了解决方法吗?
答案 0 :(得分:0)
好吧,如果一切都失败了,那就回到基础......
HttpServletRequest对象包含一个完整的有效版本0 cookiename,因此可以绕过request.getCookies()方法。
例如,假设我们在中间件中使用HttpClient 4(DacsCookie扩展了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");
}
我仍然有兴趣知道其他人是否在Glassfish V3或其他容器中遇到过这个问题。