You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2007/11/22 14:17:04 UTC
svn commit: r597404 - in
/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core:
auth/ impl/ impl/auth/ impl/helper/
Author: fmeschbe
Date: Thu Nov 22 05:17:02 2007
New Revision: 597404
URL: http://svn.apache.org/viewvc?rev=597404&view=rev
Log:
SLING-103 Register SlingServletContext as a ServletContext service for servlets and scripts
SLING-108 Implement OSGi HttpContext.handleSecurity using the Sling Authenticator. As such the
Sling authentication mechanism is always called before even calling the main Sling servlet.
Added:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/auth/AuthenticationInfo.java
Modified:
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/auth/AuthenticationHandler.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingHttpContext.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingMainServlet.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/auth/AuthorizationHeaderAuthenticationHandler.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/auth/SlingAuthenticator.java
incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/SlingServletContext.java
Modified: incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/auth/AuthenticationHandler.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/auth/AuthenticationHandler.java?rev=597404&r1=597403&r2=597404&view=diff
==============================================================================
--- incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/auth/AuthenticationHandler.java (original)
+++ incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/auth/AuthenticationHandler.java Thu Nov 22 05:17:02 2007
@@ -18,7 +18,8 @@
*/
package org.apache.sling.core.auth;
-import javax.jcr.Credentials;
+import java.io.IOException;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -31,22 +32,7 @@
public interface AuthenticationHandler {
/**
- * Returned by {@link #authenticate} to indicate an ongoing authentication
- * transaction.
- */
- static final Credentials DOING_AUTH = new Credentials() {
- };
-
- // TODO
- // @return true this handler can authenticate the request
- boolean handles(HttpServletRequest request);
-
- /**
- * Extracts credential data from the request if at all contained. This check
- * must basically be based on the original request object with the exception
- * of the request URI, which may be gotten from the request object through
- * the {@link DeliveryHttpServletRequest#getRealRequestURI()}, which
- * returns the request URI with the context path removed.
+ * Extracts credential data from the request if at all contained.
* <p>
* The method returns any of the following values : <table>
* <tr>
@@ -54,16 +40,17 @@
* <th>description</tr>
* <tr>
* <td><code>null</code>
- * <td>no user details were contained in the request </tr>
+ * <td>no user details were contained in the request or the handler is not
+ * capable or willing to extract credentials from the request</tr>
* <tr>
* <td>{@link #DOING_AUTH}
* <td>the handler is in an ongoing authentication transaction with the
- * client. Further request handling in the DeliveryModule should not take
- * place.
+ * client. Request processing should be aborted at this stage.
* <tr>
* <tr>
- * <td><code>Credentials</code> object
- * <td>The user sent credentials.</tr>
+ * <td><code>AuthenticationInfo</code> object
+ * <td>The user sent credentials. The returned object contains the
+ * credentials as well as the type of authentication transmission employed.</tr>
* </table>
* <p>
* The method must not request credential information from the client, if
@@ -73,14 +60,14 @@
* authentication.
* @param response The response object which may be used to send the
* information on the request failure to the user.
- * @return A valid <code>Credentials</code> instance identifying the
- * request user, {@link #DOING_AUTH} if the handler is in an
+ * @return A valid <code>AuthenticationInfo</code> instance identifying
+ * the request user, {@link #DOING_AUTH} if the handler is in an
* authentication transaction with the client or null if the request
* does not contain authentication information. In case of
* {@link #DOING_AUTH}, the method must have sent a response
* indicating that fact to the client.
*/
- Credentials authenticate(HttpServletRequest request,
+ AuthenticationInfo authenticate(HttpServletRequest request,
HttpServletResponse response);
/**
@@ -95,13 +82,12 @@
*
* @param request The request object.
* @param response The response object to which to send the request.
- * @param addInfo Additional information string from the configuration. This
- * may for example be used as the realm name for HTTP header
- * authentication. TODO: handler configuration
- * @return <code>true</code> if the information could be requested or
- * <code>false</code>, if the request should fail with the
- * appropriate error status.
+ * @return <code>true</code> if the handler is able to end an
+ * authentication inquiry for the given request. <code>false</code>
+ * otherwise.
+ * @throws IOException If an error occurrs sending the authentication
+ * inquiry to the client.
*/
boolean requestAuthentication(HttpServletRequest request,
- HttpServletResponse response);
+ HttpServletResponse response) throws IOException;
}
Added: incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/auth/AuthenticationInfo.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/auth/AuthenticationInfo.java?rev=597404&view=auto
==============================================================================
--- incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/auth/AuthenticationInfo.java (added)
+++ incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/auth/AuthenticationInfo.java Thu Nov 22 05:17:02 2007
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.core.auth;
+
+import javax.jcr.Credentials;
+
+/**
+ * The <code>AuthenticationInfo</code> defines the data returned from the
+ * {@link AuthenticationHandler#authenticate(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
+ * method.
+ */
+public class AuthenticationInfo {
+
+ /**
+ * This object is returned by the
+ * {@link AuthenticationHandler#authenticate(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
+ * method to indicate an ongoing authentication transaction.
+ */
+ public static final AuthenticationInfo DOING_AUTH = new AuthenticationInfo();
+
+ /** The type of authentication */
+ private final String authType;
+
+ /** The <code>javax.jcr.Credentials</code> extracted from the request */
+ private final Credentials credentials;
+
+ /** Creates an empty instance, used for the {@link #DOING_AUTH} constants */
+ private AuthenticationInfo() {
+ authType = null;
+ credentials = null;
+ }
+
+ /**
+ * Creates an instance of this class with the given authentication type and
+ * credentials.
+ *
+ * @param authType The authentication type, must not be <code>null</code>.
+ * @param credentials The credentials, must not be <code>null</code>.
+ * @see #getAuthType()
+ * @see #getCredentials()
+ */
+ public AuthenticationInfo(String authType, Credentials credentials) {
+ this.authType = authType;
+ this.credentials = credentials;
+ }
+
+ /**
+ * Returns type of authentication provisioning.
+ * <p>
+ * If authentication is taking place through one of the standard ways, such
+ * as Basic or Digest, the return value is one of the predefined constants
+ * of the <code>HttpServletRequest</code> interface. Otherwise the value
+ * may be specific to the {@link AuthenticationHandler} implementation.
+ */
+ public String getAuthType() {
+ return authType;
+ }
+
+ /**
+ * Returns the credentials extracted from the client request to use for
+ * authentication.
+ */
+ public Credentials getCredentials() {
+ return credentials;
+ }
+
+}
Modified: incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingHttpContext.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingHttpContext.java?rev=597404&r1=597403&r2=597404&view=diff
==============================================================================
--- incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingHttpContext.java (original)
+++ incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingHttpContext.java Thu Nov 22 05:17:02 2007
@@ -18,13 +18,13 @@
*/
package org.apache.sling.core.impl;
-import java.io.InputStream;
import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.sling.commons.mime.MimeTypeService;
+import org.apache.sling.core.impl.auth.SlingAuthenticator;
import org.osgi.service.http.HttpContext;
/**
@@ -34,66 +34,44 @@
*/
public class SlingHttpContext implements HttpContext {
+ /**
+ * The name of the request attribute set by the {@link SlingAuthenticator}
+ * when authenticating the request user. Existence of this attribute in the
+ * request, provided it is a JCR Session, signals that authentication has
+ * already taken place. This may be used when including through the servlet
+ * container.
+ */
+ public static final String SESSION = "org.apache.sling.core.session";
+
+ /** The helper to map MIME types */
private MimeTypeService mimeTypeService;
- SlingHttpContext(MimeTypeService mimeTypeService) {
- this.mimeTypeService = mimeTypeService;
- }
+ /** The helper to authenticate requests */
+ private final SlingAuthenticator slingAuthenticator;
- void dispose() {
- // replace the official implementation with a dummy one to prevent NPE
- this.mimeTypeService = new MimeTypeService() {
- public String getMimeType(String name) {
- return null;
- }
-
- public String getExtension(String mimeType) {
- return null;
- }
-
- public void registerMimeType(InputStream mimeTabStream) {
- }
-
- public void registerMimeType(String mimeType, String... extensions) {
- }
- };
+ /**
+ * Creates an instance of this OSGi HttpContext implementation using the
+ * give MIME type and authentication helpers.
+ */
+ SlingHttpContext(MimeTypeService mimeTypeService,
+ SlingAuthenticator slingAuthenticator) {
+ this.mimeTypeService = mimeTypeService;
+ this.slingAuthenticator = slingAuthenticator;
}
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.http.HttpContext#getMimeType(java.lang.String)
- */
+ /** Asks the MimeTypeService for the MIME type mapping */
public String getMimeType(String name) {
return this.mimeTypeService.getMimeType(name);
}
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.http.HttpContext#getResource(java.lang.String)
- */
+ /** Always returns <code>null</code>, we have no resources here */
public URL getResource(String name) {
- // This context cannot provide any resources, so we just return nothing
return null;
}
- /*
- * (non-Javadoc)
- *
- * @see org.osgi.service.http.HttpContext#handleSecurity(javax.servlet.http.HttpServletRequest,
- * javax.servlet.http.HttpServletResponse)
- */
+ /** Asks the SlingAuthenticator to authenticate the request */
public boolean handleSecurity(HttpServletRequest request,
HttpServletResponse response) {
-
- /*
- * Currently we do not handle security in the context but in the
- * SlingServlet as an SlingAuthenticator. It might be worth it
- * considering to move the authentication from the SlingAuthenticator
- * to this context.
- */
-
- return true;
+ return slingAuthenticator.authenticate(request, response);
}
}
Modified: incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingMainServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingMainServlet.java?rev=597404&r1=597403&r2=597404&view=diff
==============================================================================
--- incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingMainServlet.java (original)
+++ incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/SlingMainServlet.java Thu Nov 22 05:17:02 2007
@@ -19,6 +19,7 @@
package org.apache.sling.core.impl;
import java.io.IOException;
+import java.net.URL;
import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.Dictionary;
@@ -64,6 +65,7 @@
import org.osgi.framework.Version;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.ComponentException;
+import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -76,8 +78,7 @@
* @scr.property name="sling.root" value="/" private="true"
* @scr.property name="service.vendor" value="The Apache Software Foundation"
* @scr.property name="service.description" value="Sling Servlet"
- * @scr.reference name="ComponentFilter"
- * interface="org.apache.sling.component.ComponentFilter"
+ * @scr.reference name="Filter" interface="javax.servlet.Filter"
* cardinality="0..n" policy="dynamic"
*/
public class SlingMainServlet extends GenericServlet {
@@ -87,15 +88,15 @@
/**
* The name of the product to report in the {@link #getServerInfo()} method
- * (value is "Apache Sling").
+ * (value is "ApacheSling").
*/
- private static String PRODUCT_NAME = "Apache Sling";
+ private static String PRODUCT_NAME = "ApacheSling";
/**
- * The name of the Declarative Services reference to the ComponentFilter
- * services (value is "ComponentFilter").
+ * The name of the Declarative Services reference to the Servlet API Filter
+ * services (value is "Filter").
*/
- private static String COMPONENT_FILTER_NAME = "ComponentFilter";
+ private static String FILTER_NAME = "Filter";
private SlingServletContext slingServletContext;
@@ -123,8 +124,6 @@
/** @scr.reference cardinality="0..1" policy="dynamic" */
private MimeTypeService mimeTypeService;
- private SlingHttpContext slingHttpContext;
-
private SlingFilterChainHelper requestFilterChain = new SlingFilterChainHelper();
private SlingFilterChainHelper innerFilterChain = new SlingFilterChainHelper();
@@ -159,8 +158,7 @@
public void service(HttpServletRequest clientRequest,
HttpServletResponse clientResponse) throws IOException {
- Session session = getSlingAuthenticator().authenticate(clientRequest,
- clientResponse);
+ Session session = (Session) clientRequest.getAttribute(SlingHttpContext.SESSION);
if (session != null) {
RequestData requestData = null;
try {
@@ -188,12 +186,8 @@
} catch (AccessControlException ace) {
// try to request authentication fail, if not possible
- if (!getSlingAuthenticator().requestAuthentication(
- clientRequest, clientResponse)) {
- getErrorHandler().handleError(
- HttpServletResponse.SC_FORBIDDEN, "Access Denied",
- clientRequest, clientResponse);
- }
+ getSlingAuthenticator().requestAuthentication(clientRequest,
+ clientResponse);
} catch (HttpStatusCodeException hsce) {
// convert the status code exception to sendError
@@ -353,14 +347,28 @@
// setup servlet request processing helpers
this.slingServiceLocator = new ServiceLocatorImpl(bundleContext);
this.slingAuthenticator = new SlingAuthenticator(bundleContext);
- this.servletResolver = new SlingServletResolver(bundleContext, slingServletContext);
+ this.servletResolver = new SlingServletResolver(bundleContext,
+ slingServletContext);
this.errorHandler = new ErrorHandler(bundleContext, slingServletContext);
// register the servlet and resources
try {
- this.slingHttpContext = new SlingHttpContext(this.mimeTypeService);
+ HttpContext httpContext = new HttpContext() {
+ public String getMimeType(String name) {
+ return mimeTypeService.getMimeType(name);
+ }
+
+ public URL getResource(String name) {
+ return null;
+ }
+
+ public boolean handleSecurity(HttpServletRequest request,
+ HttpServletResponse response) {
+ return slingAuthenticator.authenticate(request, response);
+ }
+ };
this.httpService.registerServlet(this.slingRoot, this,
- configuration, this.slingHttpContext);
+ configuration, httpContext);
log.info("{} ready to serve requests", this.getServerInfo());
@@ -397,6 +405,9 @@
protected void deactivate(ComponentContext componentContext) {
+ // first of all, we have to unregister
+ httpService.unregister(this.slingRoot);
+
destroyFilters(innerFilterChain);
destroyFilters(requestFilterChain);
@@ -417,19 +428,13 @@
slingServiceLocator = null;
}
- this.httpService.unregister(this.slingRoot);
-
- if (this.slingHttpContext != null) {
- this.slingHttpContext.dispose();
- }
-
this.slingServletContext = null;
this.osgiComponentContext = null;
log.info(this.getServerInfo() + " shut down");
}
- protected void bindComponentFilter(ServiceReference ref) {
+ protected void bindFilter(ServiceReference ref) {
synchronized (this) {
if (osgiComponentContext == null) {
if (delayedComponentFilters == null) {
@@ -442,7 +447,7 @@
}
}
- protected void unbindComponentFilter(ServiceReference ref) {
+ protected void unbindFilter(ServiceReference ref) {
// service id
Object serviceId = ref.getProperty(Constants.SERVICE_ID);
@@ -459,8 +464,7 @@
}
private void initFilter(ComponentContext osgiContext, ServiceReference ref) {
- Filter filter = (Filter) osgiContext.locateService(
- COMPONENT_FILTER_NAME, ref);
+ Filter filter = (Filter) osgiContext.locateService(FILTER_NAME, ref);
// require a name for the filter
String filterName = AbstractServiceReferenceConfig.getName(ref);
Modified: incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/auth/AuthorizationHeaderAuthenticationHandler.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/auth/AuthorizationHeaderAuthenticationHandler.java?rev=597404&r1=597403&r2=597404&view=diff
==============================================================================
--- incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/auth/AuthorizationHeaderAuthenticationHandler.java (original)
+++ incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/auth/AuthorizationHeaderAuthenticationHandler.java Thu Nov 22 05:17:02 2007
@@ -29,25 +29,26 @@
import org.apache.commons.codec.binary.Base64;
import org.apache.sling.core.auth.AuthenticationHandler;
+import org.apache.sling.core.auth.AuthenticationInfo;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
/**
- * The <code>AuthorizationHeaderAuthenticationHandler</code> class implements the
- * authorization steps based on the Authorization header of the HTTP request.
- * This authenticator should eventually support both BASIC and DIGEST
+ * The <code>AuthorizationHeaderAuthenticationHandler</code> class implements
+ * the authorization steps based on the Authorization header of the HTTP
+ * request. This authenticator should eventually support both BASIC and DIGEST
* authentication methods.
*
* @scr.component immediate="false" label="%auth.http.name"
* description="%auth.http.description"
- * @scr.property name="service.description"
- * value="HTTP Header Authentication Handler"
+ * @scr.property name="service.description" value="HTTP Header Authentication
+ * Handler"
* @scr.property name="service.vendor" value="The Apache Software Foundation"
* @scr.service
*/
-public class AuthorizationHeaderAuthenticationHandler implements AuthenticationHandler {
+public class AuthorizationHeaderAuthenticationHandler implements
+ AuthenticationHandler {
/**
* @scr.property value="Sling (Development)"
@@ -73,10 +74,6 @@
// ----------- AuthenticationHandler interface ----------------------------
- public boolean handles(HttpServletRequest request) {
- return true;
- }
-
/**
* Extracts credential data from the request if at all contained. This check
* is only based on the original request object, no URI translation has
@@ -117,7 +114,7 @@
* information. In case of DOING_AUTH, the method must have sent a
* response indicating that fact to the client.
*/
- public Credentials authenticate(HttpServletRequest request,
+ public AuthenticationInfo authenticate(HttpServletRequest request,
HttpServletResponse response) {
return this.extractAuthentication(request);
}
@@ -126,41 +123,33 @@
* Sends status <code>401</code> (Unauthorized) with a
* <code>WWW-Authenticate</code> requesting standard HTTP header
* authentication with the <code>Basic</code> scheme and the configured
- * realm name.
- * <p>
- * Returns <code>true</code> if the response could successfully be sent to
- * the client. Otherwise <code>false</code> is returned.
+ * realm name. If the response is already committed, an error message is
+ * logged but the 401 status is not sent.
*
* @param request The request object
* @param response The response object to which to send the request
- * @param addInfo Additional information string from the configuration. This
- * may for example be used as the realm name for HTTP header
- * authentication. TODO configuration
- * @return true if the information could be requested or false, if the
- * request should fail with the appropriate error status
+ * @return <code>true</code> is always returned by this handler
+ * @throws IOException if an error occurrs sending back the response.
*/
public boolean requestAuthentication(HttpServletRequest request,
- HttpServletResponse response) {
+ HttpServletResponse response) throws IOException {
// if the response is already committed, we have a problem !!
- if (response.isCommitted()) {
- log.warn("requestAuthentication: response already committed");
- return false;
- }
+ if (!response.isCommitted()) {
- response.setHeader(HEADER_WWW_AUTHENTICATE,
- AUTHENTICATION_SCHEME_BASIC + " realm=\"" + this.realm + "\"");
+ response.setHeader(HEADER_WWW_AUTHENTICATE,
+ AUTHENTICATION_SCHEME_BASIC + " realm=\"" + this.realm + "\"");
- try {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
- return true;
- } catch (IOException ioe) {
- log.info("requestAuthentication: Cannot send the error: {0}",
- ioe.toString());
+
+ } else {
+
+ log.error("requestAuthentication: Response is committed, cannot request authentication");
+
+
}
- // got a problem with sending the error
- return false;
+ return true;
}
// ---------- SCR Integration ----------------------------------------------
@@ -182,7 +171,8 @@
/**
* Extract the Base64 authentication string from the request
*/
- protected Credentials extractAuthentication(HttpServletRequest request) {
+ protected AuthenticationInfo extractAuthentication(
+ HttpServletRequest request) {
// Return immediately if the header is missing
String authHeader = request.getHeader(HEADER_AUTHORIZATION);
@@ -237,12 +227,15 @@
return null;
}
+ Credentials creds;
int colIdx = decoded.indexOf(':');
if (colIdx < 0) {
- return new SimpleCredentials(decoded, new char[0]);
+ creds = new SimpleCredentials(decoded, new char[0]);
+ } else {
+ creds = new SimpleCredentials(decoded.substring(0, colIdx),
+ decoded.substring(colIdx + 1).toCharArray());
}
- return new SimpleCredentials(decoded.substring(0, colIdx),
- decoded.substring(colIdx + 1).toCharArray());
+ return new AuthenticationInfo(HttpServletRequest.BASIC_AUTH, creds);
}
}
Modified: incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/auth/SlingAuthenticator.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/auth/SlingAuthenticator.java?rev=597404&r1=597403&r2=597404&view=diff
==============================================================================
--- incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/auth/SlingAuthenticator.java (original)
+++ incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/auth/SlingAuthenticator.java Thu Nov 22 05:17:02 2007
@@ -33,11 +33,14 @@
import javax.servlet.http.HttpServletResponse;
import org.apache.sling.core.auth.AuthenticationHandler;
+import org.apache.sling.core.auth.AuthenticationInfo;
+import org.apache.sling.core.impl.SlingHttpContext;
import org.apache.sling.jcr.api.TooManySessionsException;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ManagedService;
+import org.osgi.service.http.HttpContext;
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -197,43 +200,49 @@
* be assumed, that during this method enough response information
* has been sent to the client.
*/
- public Session authenticate(HttpServletRequest req, HttpServletResponse res) {
+ public boolean authenticate(HttpServletRequest req, HttpServletResponse res) {
- // 0. Get package for request and be anonymous if none configured
- AuthenticationHandler handler = this.getAuthHandler(req);
- if (handler == null) {
- log.debug("authenticate: no authentication needed, anonymous access");
- return this.getAnonymousSession(req, res);
+ // 0. Nothing to do, if the session is also in the request
+ // this might be the case if the request is handled as a result
+ // of a servlet container include inside another Sling request
+ Object sessionAttr = req.getAttribute(SlingHttpContext.SESSION);
+ if (sessionAttr instanceof Session) {
+ log.debug("authenticate: Request already authenticated, nothing to do");
+ return true;
+ } else if (sessionAttr != null) {
+ // warn and remove existing non-session
+ log.warn(
+ "authenticate: Overwriting existing Session attribute ({})",
+ sessionAttr);
+ req.removeAttribute(SlingHttpContext.SESSION);
}
- // 1. Check request login session - only if we have sessions
- // not any more :-)
-
- // 2. Ask the packages handler for the credentials
- Credentials creds = handler.authenticate(req, res);
+ // 1. Ask all authentication handlers to try to extract credentials
+ AuthenticationInfo authInfo = getAuthenticationInfo(req, res);
// 3. Check Credentials
- if (creds == AuthenticationHandler.DOING_AUTH) {
+ if (authInfo == AuthenticationInfo.DOING_AUTH) {
log.debug("authenticate: ongoing authentication in the handler");
- // is this the correct return value ??
- return null;
+ return false;
- } else if (creds == null) {
+ } else if (authInfo == null) {
log.debug("authenticate: no credentials in the request, anonymous");
- return this.getAnonymousSession(req, res);
+ return getAnonymousSession(req, res);
} else {
// try to connect
try {
log.debug("authenticate: credentials, trying to get a ticket");
- Session session = getRepository().login(creds, null);
+ Session session = getRepository().login(
+ authInfo.getCredentials(), null);
// handle impersonation
- session = this.handleImpersonation(req, res, session);
+ session = handleImpersonation(req, res, session);
+ setAttributes(session, authInfo.getAuthType(), req);
- return session;
+ return true;
} catch (TooManySessionsException se) {
log.info("Too many sessions for user: {}", se.getMessage());
@@ -244,13 +253,11 @@
}
// request authentication information and send 403 (Forbidden)
- // if the handler cannot request authentication information.
- if (!handler.requestAuthentication(req, res)) {
- this.sendFailure(res);
- }
+ // if no handler can request authentication information.
+ requestAuthentication(req, res);
// end request
- return null;
+ return false;
}
}
@@ -266,22 +273,30 @@
*
* @param req The request object
* @param res The response object to which to send the request
- * @return true if the information could be requested or false, if the
- * request should fail with the appropriate error status
*/
- public boolean requestAuthentication(HttpServletRequest req,
- HttpServletResponse res) {
+ public void requestAuthentication(HttpServletRequest request,
+ HttpServletResponse response) {
- AuthenticationHandler handler = this.getAuthHandler(req);
- if (handler != null) {
- log.debug("requestAuthentication: requesting authentication using "
- + "handler: {0}", handler);
+ AuthenticationHandler[] handlers = getAuthenticationHandlers();
+ boolean done = false;
+ for (int i = 0; !done && i < handlers.length; i++) {
+ log.debug(
+ "requestAuthentication: requesting authentication using handler: {0}",
+ handlers[i]);
- return handler.requestAuthentication(req, res);
+ try {
+ done = handlers[i].requestAuthentication(request, response);
+ } catch (IOException ioe) {
+ log.error(
+ "requestAuthentication: Failed sending authentication request through handler "
+ + handlers[i] + ", access forbidden", ioe);
+ done = true;
+ }
}
- log.info("requestAuthentication: no handler found for request");
- return false;
+ // no handler could send an authentication request, fail with FORBIDDEN
+ log.info("requestAuthentication: No handler for request, sending FORBIDDEN");
+ sendFailure(response);
}
// ----------- ManagedService interface -----------------------------------
@@ -337,43 +352,31 @@
return authHandlerCache;
}
- private AuthenticationHandler getAuthHandler(HttpServletRequest req) {
+ private AuthenticationInfo getAuthenticationInfo(
+ HttpServletRequest request, HttpServletResponse response) {
AuthenticationHandler[] local = getAuthenticationHandlers();
for (int i = 0; i < local.length; i++) {
- if (local[i].handles(req)) {
- return local[i];
+ AuthenticationInfo authInfo = local[i].authenticate(request,
+ response);
+ if (authInfo != null) {
+ return authInfo;
}
}
// no handler found for the request ....
+ log.debug("getCredentials: no handler could extract credentials");
return null;
}
- // private AuthPackage getAuthPackage(HttpServletRequest req) {
- //
- // // Get the request URI from the request or from the include
- // String requestURI = req.getRequestURI();
- // log.debug("getAuthPackage: Check for {0}", requestURI);
- //
- // // Look in the packages list
- // for (int i = 0; i < numPackages; i++) {
- // if (packages[i].contains(requestURI)) {
- // return packages[i];
- // }
- // }
- // // invariant: returned or no package found
- //
- // // if no package is responsible
- // return null;
- // }
-
// TODO
- private Session getAnonymousSession(HttpServletRequest req,
+ private boolean getAnonymousSession(HttpServletRequest req,
HttpServletResponse res) {
// login anonymously, log the exact cause in case of failure
if (this.anonymousAllowed) {
try {
- return getRepository().login();
+ Session session = getRepository().login();
+ setAttributes(session, null, req);
+ return true;
} catch (TooManySessionsException se) {
log.error(
"getAnonymousSession: Too many anonymous users active", se);
@@ -390,12 +393,10 @@
}
// request authentication now, and fail if not possible
- if (!this.requestAuthentication(req, res)) {
- this.sendFailure(res);
- }
+ requestAuthentication(req, res);
// fallback to no session
- return null;
+ return false;
}
// TODO
@@ -409,62 +410,18 @@
}
/**
- * Tries to instantiate a handler from the given handler configuration.
- *
- * @param defaultPackage The name of the package for the handler class if
- * the class name is not a fully qualified class name.
- * @param className The name of the class. If this is not fully qualified,
- * the class is assumed to be in the defaultPackage.
- * @param configPath The path name (handle) of the handler configuration or
- * <code>null</code> if the handler has no configuration.
- * @throws ServiceException if the handler cannot be instantiated and
- * initialized.
- */
- // private AuthenticationHandler getHandlerInstance(String defaultPackage,
- // String className, String configPath) {
- //
- // // check fully qualified classname
- // if (className.indexOf('.') < 0 && defaultPackage != null) {
- // className = defaultPackage + "." + className;
- // }
- //
- // Exception e = null;
- // try {
- // // Read the configuration
- // Config config = (configPath != null) ? MutableConfig.createFromXml(
- // null, ticket, configPath) : null;
- //
- // // get the instance
- // Class clazz = classLoader.loadClass(className);
- // AuthenticationHandler handler = (AuthenticationHandler)
- // clazz.newInstance();
- //
- // // initialize the handler
- // handler.init(ticket, config);
- //
- // // return the handler
- // return handler;
- //
- // } catch (ContentBusException cbe) {
- // // MutableConfig.createFromXml()
- // e = cbe;
- // } catch (ClassNotFoundException cnfe) {
- // // Class.forName()
- // e = cnfe;
- // } catch (InstantiationException ie) {
- // // newInstance()
- // e = ie;
- // } catch (IllegalAccessException iae) {
- // // newInstance()
- // e = iae;
- // } catch (ClassCastException cce) {
- // // clazz is not an AuthenticationHandler
- // e = cce;
- // }
- //
- // // invariant : e != null if we get here
- // throw new ServiceException(e.getMessage(), e);
- // }
+ * Sets the request attributes required by the OSGi HttpContext interface
+ * specification for the <code>handleSecurity</code> method. In addition
+ * the {@link SlingHttpContext#SESSION} request attribute is set with the
+ * JCR Session.
+ */
+ private void setAttributes(Session session, String authType,
+ HttpServletRequest request) {
+ request.setAttribute(HttpContext.REMOTE_USER, session.getUserID());
+ request.setAttribute(HttpContext.AUTHENTICATION_TYPE, authType);
+ request.setAttribute(SlingHttpContext.SESSION, session);
+ }
+
/**
* Sends the session cookie for the name session with the given age in
* seconds. This sends a Version 1 cookie.
@@ -583,107 +540,4 @@
return session;
}
- // ---------- internal class -----------------------------------------------
-
- /**
- * The <code>AuthPackage</code> class implements the
- * {@link ContentPackage} package providing additional information for
- * handler detection.
- */
- // private class AuthPackage implements ContentPackage {
- //
- // /**
- // * The name of the configuration attribute defining the handler to use
- // * for requests matching this package.
- // */
- // private static final String HANDLER_ATTR = "handler";
- //
- // /**
- // * The name of the configuration attribute defining the parameter the
- // * handler may use when requesting authentication.
- // */
- // private static final String PARAM_ATTR = "param";
- //
- // /**
- // * The default value of the parameter attribute
- // *
- // * @see #PARAM_ATTR
- // */
- // private static final String DEFAULT_PARAM = "";
- //
- // /** the name of the handler */
- // private final String handler;
- //
- // /** the addInfo parameter for the requestAuthentication call */
- // private final String param;
- //
- // private final ContentPackage delegatee;
- //
- // /**
- // * Create the package from the configuration element using the given
- // * handler name as the default handler name
- // *
- // * @param config The configuration element on which to base the package
- // * definition and authentication configuration.
- // * @param defaultHandler The defualt authentication handler name to use
- // * if none is specified in the configuration.
- // */
- // AuthPackage(Configuration config, String defaultHandler) throws
- // RepositoryException {
- // FilterContentPackageBuilder builder = new FilterContentPackageBuilder();
- // builder.addFilters((Session) null, config);
- // delegatee = builder.createContentPackage();
- //
- // this.handler = config.getString(HANDLER_ATTR, defaultHandler);
- // this.param = config.getString(PARAM_ATTR, DEFAULT_PARAM);
- // }
- //
- // /**
- // * Returns the name of the handler to use for requests matching this
- // * package.
- // *
- // * @return The name of the handler to use.
- // */
- // String getHandler() {
- // return handler;
- // }
- //
- // /**
- // * The parameter to provide to the handler when requesting
- // * authentication.
- // *
- // * @return The authentication request parameter for the handler.
- // */
- // String getParam() {
- // return param;
- // }
- //
- // /**
- // * @see ContentPackage#contains(String)
- // */
- // public boolean contains(String handle) {
- // return delegatee.contains(handle);
- // }
- //
- // /**
- // * @see ContentPackage#contains(Ticket, String)
- // */
- // public boolean contains(Session session, String handle) {
- // return delegatee.contains(session, handle);
- // }
- //
- // /**
- // * @see ContentPackage#contains(Page)
- // */
- // public boolean contains(Item item) {
- // return delegatee.contains(item);
- // }
- //
- // /**
- // * @see ContentPackage#getTraversingStartPoints()
- // */
- // public String[] getTraversingStartPoints() {
- // return delegatee.getTraversingStartPoints();
- // }
- // }
}
Modified: incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/SlingServletContext.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/SlingServletContext.java?rev=597404&r1=597403&r2=597404&view=diff
==============================================================================
--- incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/SlingServletContext.java (original)
+++ incubator/sling/trunk/sling/core/src/main/java/org/apache/sling/core/impl/helper/SlingServletContext.java Thu Nov 22 05:17:02 2007
@@ -21,7 +21,10 @@
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Collections;
+import java.util.Dictionary;
import java.util.Enumeration;
+import java.util.Hashtable;
import java.util.Set;
import javax.servlet.RequestDispatcher;
@@ -29,74 +32,191 @@
import javax.servlet.ServletContext;
import org.apache.sling.core.impl.SlingMainServlet;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * The <code>SlingServletContext</code> TODO
+ * The <code>SlingServletContext</code> class is the
+ * <code>ServletContext</code> which is registered as a service usable by
+ * servlets and helpers inside Sling. Most methods just call into the servlet
+ * context in which the {@link SlingMainServlet} is running.
+ * <dl>
+ * <dt><b>MIME Type Mapping</b></dt>
+ * <dd>Just forwards to the servlet context of the {@link SlingMainServlet} for
+ * MIME type mapping.</dd>
+ * <dt><b>Resources</b></dt>
+ * <dd>This class provides access to the resources in the web application by
+ * means of the respective resource accessor methods. These are not the same
+ * resources as available through the <code>ResourceResolver</code>.</dd>
+ * <dt><b>Request Dispatcher</b></dt>
+ * <dd>The {@link #getRequestDispatcher(String)} method returns a
+ * {@link SlingRequestDispatcher} which may dispatch a request inside sling
+ * without going through the servlet container. The
+ * {@link #getNamedDispatcher(String)} method returns a servlet container
+ * request dispatcher which always goes through the servlet container.</dd>
+ * <dt><b>Parameters and Attributes</b></dt>
+ * <dd>Initialization parameters and context attributes are shared with the
+ * servlet context in which the {@link SlingMainServlet} is running.</dd>
+ * <dt><b>Logging</b></dt>
+ * <dd>Logging is diverted to a logger whose name is the fully qualified name
+ * of this class.</dd>
+ * </dl>
*/
public class SlingServletContext implements ServletContext {
/** default log */
private final Logger log = LoggerFactory.getLogger(getClass());
- SlingMainServlet requestHandler;
+ /** The {@link SlingMainServlet} to which some calls are delegated */
+ private final SlingMainServlet requestHandler;
+ /** The service registration of this service as a ManagedService */
+ private final ServiceRegistration registration;
+
+ /**
+ * Creates an instance of this class delegating some methods to the given
+ * {@link SlingMainServlet}. In addition the new instance is registered as
+ * a <code>ManagedService</code> and <code>ServletContext</code> to
+ * receive configuration information.
+ */
public SlingServletContext(SlingMainServlet requestHandler) {
this.requestHandler = requestHandler;
+
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+ props.put(Constants.SERVICE_PID, getClass().getName());
+ props.put(Constants.SERVICE_DESCRIPTION, "Sling ServletContext");
+ props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+ registration = requestHandler.getBundleContext().registerService(
+ ServletContext.class.getName(), this, props);
}
/**
- * @see javax.servlet.ServletContext#getAttribute(java.lang.String)
+ * Disposes of this servlet context by just unregistering as a service.
*/
- public Object getAttribute(String name) {
- return getServletContext().getAttribute(name);
+ public void dispose() {
+ if (registration != null) {
+ registration.unregister();
+ }
}
+ // ---------- Web App configuration ----------------------------------------
+
/**
- * @see javax.servlet.ServletContext#getAttributeNames()
+ * Returns the name of the servlet context in which Sling is configured.
+ * This method calls on the <code>ServletContext</code> in which the
+ * {@link SlingMainServlet} is running.
*/
- @SuppressWarnings("unchecked")
- public Enumeration<String> getAttributeNames() {
- return getServletContext().getAttributeNames();
+ public String getServletContextName() {
+ return getServletContext().getServletContextName();
}
/**
- * @see javax.servlet.ServletContext#getInitParameter(java.lang.String)
+ * Returns the init-param of the servlet context in which Sling is
+ * configured. This method calls on the <code>ServletContext</code> in
+ * which the {@link SlingMainServlet} is running.
*/
public String getInitParameter(String name) {
return getServletContext().getInitParameter(name);
}
/**
- * @see javax.servlet.ServletContext#getInitParameterNames()
+ * Returns the names of the init-params of the servlet context in which
+ * Sling is configured. This method calls on the <code>ServletContext</code>
+ * in which the {@link SlingMainServlet} is running.
*/
@SuppressWarnings("unchecked")
public Enumeration<String> getInitParameterNames() {
return getServletContext().getInitParameterNames();
}
+ // ---------- attributes ---------------------------------------------------
+
/**
- * @see javax.servlet.ServletContext#getMajorVersion()
+ * Returns the named servlet context attribute. This method calls on the
+ * <code>ServletContext</code> in which the {@link SlingMainServlet} is
+ * running.
*/
- public int getMajorVersion() {
- return getServletContext().getMajorVersion();
+ public Object getAttribute(String name) {
+ return getServletContext().getAttribute(name);
}
/**
- * @see javax.servlet.ServletContext#getMimeType(java.lang.String)
+ * Returns the names of all servlet context attributes. This method calls on
+ * the <code>ServletContext</code> in which the {@link SlingMainServlet}
+ * is running.
*/
- public String getMimeType(String file) {
- return getServletContext().getMimeType(file);
+ @SuppressWarnings("unchecked")
+ public Enumeration<String> getAttributeNames() {
+ return getServletContext().getAttributeNames();
+ }
+
+ /**
+ * Removes the named servlet context attribute. This method calls on the
+ * <code>ServletContext</code> in which the {@link SlingMainServlet} is
+ * running.
+ */
+ public void removeAttribute(String name) {
+ getServletContext().removeAttribute(name);
}
/**
- * @see javax.servlet.ServletContext#getMinorVersion()
+ * Sets the name servlet context attribute to the requested value. This
+ * method calls on the <code>ServletContext</code> in which the
+ * {@link SlingMainServlet} is running.
+ */
+ public void setAttribute(String name, Object object) {
+ getServletContext().removeAttribute(name);
+ }
+
+ // ---------- Servlet Container information --------------------------------
+
+ /**
+ * Returns the Sling server info string. This is not the same server info
+ * string as returned by the servlet context in which Sling is configured.
+ */
+ public String getServerInfo() {
+ return requestHandler.getServerInfo();
+ }
+
+ /**
+ * Returns the major version number of the Servlet API supported by the
+ * servlet container in which Sling is running. This method calls on the
+ * <code>ServletContext</code> in which the {@link SlingMainServlet} is
+ * running.
+ */
+ public int getMajorVersion() {
+ return getServletContext().getMajorVersion();
+ }
+
+ /**
+ * Returns the minor version number of the Servlet API supported by the
+ * servlet container in which Sling is running. This method calls on the
+ * <code>ServletContext</code> in which the {@link SlingMainServlet} is
+ * running.
*/
public int getMinorVersion() {
return getServletContext().getMinorVersion();
}
+ // ---------- MIME type mapping --------------------------------------------
+
+ /**
+ * Returns a MIME type for the extension of the given file name. This method
+ * calls on the <code>ServletContext</code> in which the
+ * {@link SlingMainServlet} is running.
+ */
+ public String getMimeType(String file) {
+ return getServletContext().getMimeType(file);
+ }
+
+ // ---------- Request Dispatcher -------------------------------------------
+
+ /**
+ * Returns a {@link SlingRequestDispatcher} for the given path if not
+ * <code>null</code>. Otherwise <code>null</code> is returned.
+ */
public RequestDispatcher getRequestDispatcher(String path) {
// return no dispatcher if content is null
if (path == null) {
@@ -107,91 +227,110 @@
return new SlingRequestDispatcher(path);
}
+ /**
+ * Returns a servlet container request dispatcher for the named servlet.
+ * This method calls on the <code>ServletContext</code> in which the
+ * {@link SlingMainServlet} is running.
+ */
+ public RequestDispatcher getNamedDispatcher(String name) {
+ return getServletContext().getNamedDispatcher(name);
+ }
+
+ // ---------- Resource Access ----------------------------------------------
+
+ /**
+ * Returns the URI for the given path. This method calls on the
+ * <code>ServletContext</code> in which the {@link SlingMainServlet} is
+ * running.
+ */
public URL getResource(String path) throws MalformedURLException {
- // TODO Auto-generated method stub
- return null;
+ return getServletContext().getResource(path);
}
+ /**
+ * Returns an input stream to the given path. This method calls on the
+ * <code>ServletContext</code> in which the {@link SlingMainServlet} is
+ * running.
+ */
public InputStream getResourceAsStream(String path) {
- // TODO Auto-generated method stub
- return null;
+ return getServletContext().getResourceAsStream(path);
}
- public Set getResourcePaths(String arg0) {
- // TODO Auto-generated method stub
- return null;
+ /**
+ * Returns a set of names for path entries considered children of the given
+ * path. This method calls on the <code>ServletContext</code> in which the
+ * {@link SlingMainServlet} is running.
+ */
+ @SuppressWarnings("unchecked")
+ public Set<String> getResourcePaths(String parentPath) {
+ return getServletContext().getResourcePaths(parentPath);
}
- /*
- * (non-Javadoc)
- *
- * @see javax.servlet.ServletContext#getServerInfo()
+ /**
+ * Returns the real file inside the web application to which the given path
+ * maps or <code>null</code> if no such file exists. This method calls on
+ * the <code>ServletContext</code> in which the {@link SlingMainServlet}
+ * is running.
*/
- public String getServerInfo() {
- return requestHandler.getServerInfo();
+ public String getRealPath(String path) {
+ return getServletContext().getRealPath(path);
}
+ // ---------- logging ------------------------------------------------------
+
+ /** Logs the message and optional throwable at error level to the logger */
public void log(String message, Throwable throwable) {
log.error(message, throwable);
}
- public void log(String msg) {
- log.info(msg);
+ /** Logs the message at info level to the logger */
+ public void log(String message) {
+ log.info(message);
}
- public void log(Exception exception, String msg) {
- log(msg, exception);
+ /** Logs the message and optional exception at error level to the logger */
+ @Deprecated
+ public void log(Exception exception, String message) {
+ log(message, exception);
}
- /**
- * @see javax.servlet.ServletContext#removeAttribute(java.lang.String)
- */
- public void removeAttribute(String name) {
- getServletContext().removeAttribute(name);
- }
+ // ---------- foreign Servlets ---------------------------------------------
/**
- * @see javax.servlet.ServletContext#setAttribute(java.lang.String,
- * java.lang.Object)
+ * Returns the servlet context from the servlet container in which sling is
+ * running. This method calls on the <code>ServletContext</code> in which
+ * the {@link SlingMainServlet} is running.
*/
- public void setAttribute(String name, Object object) {
- getServletContext().removeAttribute(name);
- }
-
- private ServletContext getServletContext() {
- return requestHandler.getServletContext();
- }
-
public ServletContext getContext(String uripath) {
- // check whether to return ComponentContext ??
return getServletContext().getContext(uripath);
}
- public RequestDispatcher getNamedDispatcher(String name) {
- return getServletContext().getNamedDispatcher(name);
- }
-
- public String getRealPath(String path) {
- return getServletContext().getRealPath(path);
- }
-
- public String getServletContextName() {
- return getServletContext().getServletContextName();
- }
-
+ /** Returns <code>null</code> as defined in Servlet API 2.4 */
@Deprecated
public Servlet getServlet(String name) {
return null;
}
+ /** Returns <code>null</code> as defined in Servlet API 2.4 */
@Deprecated
public Enumeration<?> getServletNames() {
- return null;
+ return Collections.enumeration(Collections.emptyList());
}
+ /** Returns <code>null</code> as defined in Servlet API 2.4 */
@Deprecated
public Enumeration<?> getServlets() {
- return null;
+ return Collections.enumeration(Collections.emptyList());
+ }
+
+ // ---------- internal -----------------------------------------------------
+
+ /**
+ * Returns the real servlet context of the servlet container in which the
+ * Sling Servlet is running.
+ */
+ private ServletContext getServletContext() {
+ return requestHandler.getServletContext();
}
}