동일한 문제가 발생하여 Cookie
세션의 도메인 부분을 덮어 쓰거나 설정하는 Tomcat Valve
을 만들었습니다. 아주 간단하고 이미 수년 동안 작동합니다. '.'세션이 새로운 경우에만 - - - - - 요청 된 호스트 이름 를 가져옵니다 - 세션 쿠키 찾을 수있는 호스트 이름을 분할을 :
public class CrossSubdomainSessionValve extends ValveBase {
public CrossSubdomainSessionValve() {
super();
info = "common-tomcat-CrossSubdomainSessionValve";
}
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
// cookie will only need to be changed, if this session is created by this request.
if (request.getSession(true).isNew()) {
Cookie sessionCookie = findSessionCookie(response.getCookies());
if (sessionCookie != null) {
String cookieDomainToSet = getCookieDomainToSet(request.getServerName());
if (cookieDomainToSet != null) {
// changing the cookie only does not help, because tomcat immediately sets
// a string representation of this cookie as MimeHeader, thus we also
// have to change this representation
replaceCookie(response.getCoyoteResponse().getMimeHeaders(), sessionCookie, cookieDomainToSet);
}
}
}
// process the next valve
getNext().invoke(request, response);
}
protected Cookie findSessionCookie(Cookie[] cookies) {
if (cookies != null)
for (Cookie cookie : cookies)
if (Globals.SESSION_COOKIE_NAME.equals(cookie.getName())) {
return cookie;
return null;
}
protected void replaceCookie(MimeHeaders headers, Cookie originalCookie, String domainToSet) {
// if the response has already been committed, our replacementstrategy will have no effect
// find the Set-Cookie header for the existing cookie and replace its value with new cookie
for (int i = 0, size = headers.size(); i < size; i++) {
if (headers.getName(i).equals("Set-Cookie")) {
MessageBytes value = headers.getValue(i);
if (value.indexOf(originalCookie.getName()) >= 0) {
if (originalCookie.getDomain() == null) {
StringBuilder builder = new StringBuilder(value.getString()).append("; Domain=").append(domainToSet);
value.setString(builder.toString());
} else {
String newDomain = value.getString().replaceAll("Domain=[A-Za-z0-9.-]*", "Domain=" + domainToSet);
value.setString(newDomain);
}
}
}
}
}
protected String getCookieDomainToSet(String cookieDomain) {
String[] parts = cookieDomain.split("\\.");
if (parts.length >= 3) {
return "." + parts[parts.length - 2] + "." + parts[parts.length - 1];
}
return null;
}
public String toString() {
return ("CrossSubdomainSessionValve[container=" + container.getName() + ']');
}
}
알고리즘은 다음과 같이 작동 코드는 다음과 같이 간다 - 그것은 (www.google.de처럼) 적어도 3 개 개의 부품이있는 경우, (.google.de하는) 을 첫 번째 부분을 제거 - 재설정 쿠키
당신의 상황에 맞는 구성에서이
같은 밸브를 적용 할 수 있습니다
<Valve className="my.package.CrossSubdomainSessionValve" httpOnlyEnabled="true" />
주의해야 할 점은 다음 코드 Valve
에서 할 수있는 세션이 이전에 생성되지 않았으며 전혀 세션을 필요로하는 경우 상관하지 않는 경우 세션 ...
희망 ... 행운을 만듭니다!
감사합니다. 시험해 보겠습니다. 'Valve '가'Context'에 정의되어 있어야할까요, 아니면'Host' 설정의 일부로 할 수 있습니까? – aroth
그냥 시도해보세요. 쉬워야합니다. –