Fix domain field of HTTP digest authentication

Per RFC 2617 the domain field is optional. If it is not present,
the digest token is valid on any URL on the server. When set it
must be a path prefix describing the URLs that the password would
be valid against.

When a canonical URL is known, supply that as the only domain that
is valid. When the URL is missing (e.g. because the provider is
still broken) rely on the context path of the application instead.

Change-Id: Ie1270fef4bd9bfead18fae80e6dd6d4202462d63
This commit is contained in:
Shawn O. Pearce
2012-04-04 18:56:14 -07:00
parent 34ab4294cd
commit 54a997514f

View File

@@ -105,7 +105,7 @@ class ProjectDigestFilter implements Filter {
return;
}
Response rsp = new Response((HttpServletResponse) response);
Response rsp = new Response(req, (HttpServletResponse) response);
if (verify(req, rsp)) {
chain.doFilter(req, rsp);
@@ -281,10 +281,6 @@ class ProjectDigestFilter implements Filter {
return p;
}
private String getDomain() {
return urlProvider.get() + "p/";
}
private String newNonce() {
try {
return tokens.newToken("");
@@ -295,11 +291,12 @@ class ProjectDigestFilter implements Filter {
class Response extends HttpServletResponseWrapper {
private static final String WWW_AUTHENTICATE = "WWW-Authenticate";
private final HttpServletRequest req;
Boolean stale;
Response(HttpServletResponse rsp) {
Response(HttpServletRequest req, HttpServletResponse rsp) {
super(rsp);
this.req = req;
}
private void status(int sc) {
@@ -307,7 +304,18 @@ class ProjectDigestFilter implements Filter {
StringBuilder v = new StringBuilder();
v.append("Digest");
v.append(" realm=\"" + REALM_NAME + "\"");
v.append(", domain=\"" + getDomain() + "\"");
String url = urlProvider.get();
if (url == null) {
url = req.getContextPath();
if (url != null && !url.isEmpty() && !url.endsWith("/")) {
url += "/";
}
}
if (url != null && !url.isEmpty()) {
v.append(", domain=\"" + url + "\"");
}
v.append(", qop=\"auth\"");
if (stale != null) {
v.append(", stale=" + stale);