Author: fmeschbe
Date: Wed Aug 11 13:35:36 2010
New Revision: 984402
URL: http://svn.apache.org/viewvc?rev=984402&view=rev
Log:
SLING-1641 Make embedded HTTP Authenticator more robust towards the client
requests
Modified:
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/HttpBasicAuthenticationHandler.java
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java
Modified:
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/HttpBasicAuthenticationHandler.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/HttpBasicAuthenticationHandler.java?rev=984402&r1=984401&r2=984402&view=diff
==============================================================================
---
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/HttpBasicAuthenticationHandler.java
(original)
+++
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/HttpBasicAuthenticationHandler.java
Wed Aug 11 13:35:36 2010
@@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory;
/**
* The <code>HttpBasicAuthenticationHandler</code> class supports plain old
HTTP
* Basic authentication. While {...@link
#extractCredentials(HttpServletRequest)}
- * always accesse the header if called and if present, the
+ * always accesses the header if called and if present, the
* {...@link #requestCredentials(HttpServletRequest, HttpServletResponse)} and
* {...@link #dropCredentials(HttpServletRequest, HttpServletResponse)} methods
* must be explicitly enabled to send back a 401/UNAUTHORIZED reply to force
the
@@ -58,16 +58,8 @@ public class HttpBasicAuthenticationHand
private final String realm;
- private final boolean forceRequestCredentials;
-
- private final boolean forceDropCredentials;
-
- public HttpBasicAuthenticationHandler(final String realm,
- final boolean forceRequestCredentials,
- final boolean forceDropCredentials) {
+ public HttpBasicAuthenticationHandler(final String realm) {
this.realm = realm;
- this.forceRequestCredentials = forceRequestCredentials;
- this.forceDropCredentials = forceDropCredentials;
}
// ----------- AuthenticationHandler interface ----------------------------
@@ -144,9 +136,8 @@ public class HttpBasicAuthenticationHand
public boolean requestCredentials(HttpServletRequest request,
HttpServletResponse response) {
- if (forceRequestCredentials || isLoginRequested(request)) {
- sendUnauthorized(response);
- return true;
+ if (isLoginRequested(request, true)) {
+ return sendUnauthorized(response);
}
return false;
@@ -164,8 +155,7 @@ public class HttpBasicAuthenticationHand
*/
public void dropCredentials(HttpServletRequest request,
HttpServletResponse response) {
- if (request.getHeader(HEADER_AUTHORIZATION) != null
- && forceDropCredentials) {
+ if (request.getHeader(HEADER_AUTHORIZATION) != null) {
sendUnauthorized(response);
}
}
@@ -174,8 +164,14 @@ public class HttpBasicAuthenticationHand
* Returns true if the {...@link #REQUEST_LOGIN_PARAMETER} parameter is
set to
* the value <code>Basic</code> thus requesting plain basic authentication.
*/
- private boolean isLoginRequested(HttpServletRequest request) {
- return
HttpServletRequest.BASIC_AUTH.equals(request.getParameter(REQUEST_LOGIN_PARAMETER));
+ private boolean isLoginRequested(HttpServletRequest request,
+ boolean optionalLoginParameter) {
+ final String reqLogin = request.getParameter(REQUEST_LOGIN_PARAMETER);
+ if (reqLogin == null) {
+ return optionalLoginParameter;
+ }
+ return "1".equals(reqLogin)
+ || HttpServletRequest.BASIC_AUTH.equals(reqLogin);
}
/**
@@ -201,7 +197,7 @@ public class HttpBasicAuthenticationHand
// presume 401/UNAUTHORIZED has not been sent
boolean authenticationForced = false;
- if (isLoginRequested(request)) {
+ if (isLoginRequested(request, false)) {
authenticationForced = sendUnauthorized(response);
@@ -228,15 +224,24 @@ public class HttpBasicAuthenticationHand
* been sent.
*/
private boolean sendUnauthorized(HttpServletResponse response) {
- response.setHeader(HEADER_WWW_AUTHENTICATE, AUTHENTICATION_SCHEME_BASIC
- + " realm=\"" + this.realm + "\"");
- try {
- response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
- response.flushBuffer();
- return true;
- } catch (IOException ioe) {
- log.error("sendUnauthorized: Failed requesting authentication",
ioe);
+ if (response.isCommitted()) {
+
+ log.error("sendUnauthorized: Cannot send 401/UNAUTHORIZED;
response is already committed");
+
+ } else {
+
+ response.setHeader(HEADER_WWW_AUTHENTICATE,
+ AUTHENTICATION_SCHEME_BASIC + " realm=\"" + this.realm + "\"");
+
+ try {
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+ response.flushBuffer();
+ return true;
+ } catch (IOException ioe) {
+ log.error("sendUnauthorized: Failed requesting authentication",
+ ioe);
+ }
}
return false;
Modified:
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java?rev=984402&r1=984401&r2=984402&view=diff
==============================================================================
---
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java
(original)
+++
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java
Wed Aug 11 13:35:36 2010
@@ -287,10 +287,7 @@ public class SlingAuthenticator implemen
// register as a service !
final String realm = OsgiUtil.toString(properties.get(PAR_REALM_NAME),
DEFAULT_REALM);
- final boolean forceRequestCredentials = true;
- final boolean forceDropCredentials = false;
- httpBasicHandler = new HttpBasicAuthenticationHandler(realm,
- forceRequestCredentials, forceDropCredentials);
+ httpBasicHandler = new HttpBasicAuthenticationHandler(realm);
}
@SuppressWarnings("unused")
@@ -377,7 +374,7 @@ public class SlingAuthenticator implemen
request.setAttribute(REQUEST_ATTRIBUTE_AUTH_INFO, authInfo);
log.debug("handleSecurity: No credentials in the request,
anonymous");
- return getAnonymousResolver(request, response, anonInfo);
+ return getAnonymousResolver(request, response);
} else {
@@ -605,7 +602,7 @@ public class SlingAuthenticator implemen
// try to connect
try {
- handleImpersonation(request, response, authInfo);
+ handleImpersonation(request, authInfo);
ResourceResolver resolver =
resourceResolverFactory.getResourceResolver(authInfo);
setSudoCookie(request, response, authInfo);
@@ -657,7 +654,7 @@ public class SlingAuthenticator implemen
/** Try to acquire an anonymous ResourceResolver */
private boolean getAnonymousResolver(final HttpServletRequest request,
- final HttpServletResponse response, AuthenticationInfo anonInfo) {
+ final HttpServletResponse response) {
// Get an anonymous session if allowed, or if we are handling
// a request for the login servlet
@@ -894,21 +891,17 @@ public class SlingAuthenticator implemen
* If the sudo parameter is empty or missing, the current cookie setting
for
* impersonation is used. Else if the parameter is <code>-</code>, the
* current cookie impersonation is removed and no impersonation will take
- * place for this request. Else the parameter is assumed to contain the
- * handle of a user page acceptable for the {...@link Session#impersonate}
- * method.
+ * place for this request. Else the parameter is assumed to contain the
name
+ * of a user to impersonate as.
*
* @param req The {...@link DeliveryHttpServletRequest} optionally
containing
* the sudo parameter.
- * @param res The {...@link DeliveryHttpServletResponse} to send the
- * impersonation cookie.
- * @param session The real {...@link Session} to optionally replace with an
- * impersonated session.
- * @see Session#impersonate for details on the user configuration
- * requirements for impersonation.
+ * @param authInfo The authentication info into which the
+ * <code>sudo.user.id</code> property is set to the impersonator
+ * user.
*/
private void handleImpersonation(HttpServletRequest req,
- HttpServletResponse res, AuthenticationInfo authInfo) {
+ AuthenticationInfo authInfo) {
String currentSudo = getSudoCookieValue(req);
/**