SLING-2167 : Use Sling authenticator
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1153126 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index 25cd11c..40f6f1d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -100,6 +100,19 @@
</dependency>
<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.api</artifactId>
+ <version>2.2.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.auth.core</artifactId>
+ <version>1.0.6</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
<version>2.0</version>
diff --git a/src/main/java/org/apache/sling/jcr/davex/impl/servlets/AuthHttpContext.java b/src/main/java/org/apache/sling/jcr/davex/impl/servlets/AuthHttpContext.java
new file mode 100644
index 0000000..95e1fb2
--- /dev/null
+++ b/src/main/java/org/apache/sling/jcr/davex/impl/servlets/AuthHttpContext.java
@@ -0,0 +1,79 @@
+/*
+ * 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.jcr.davex.impl.servlets;
+
+import java.io.IOException;
+import java.net.URL;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.auth.core.AuthenticationSupport;
+import org.osgi.service.http.HttpContext;
+
+class AuthHttpContext implements HttpContext {
+
+ /**
+ * Handles security
+ *
+ * @see #handleSecurity(HttpServletRequest, HttpServletResponse)
+ */
+ private AuthenticationSupport authenticator;
+
+ public void setAuthenticationSupport(final AuthenticationSupport auth) {
+ this.authenticator = auth;
+ }
+
+ // ---------- HttpContext interface ----------------------------------------
+
+ /**
+ * Returns the MIME type as resolved by the <code>MimeTypeService</code> or
+ * <code>null</code> if the service is not available.
+ */
+ public String getMimeType(String name) {
+ return null;
+ }
+
+ /**
+ * Always returns <code>null</code> because resources are all provided
+ * through the {@link MainServlet}.
+ */
+ public URL getResource(String name) {
+ return null;
+ }
+
+ /**
+ * Tries to authenticate the request using the
+ * <code>SlingAuthenticator</code>. If the authenticator or the Repository
+ * is missing this method returns <code>false</code> and sends a 503/SERVICE
+ * UNAVAILABLE status back to the client.
+ */
+ public boolean handleSecurity(final HttpServletRequest request,
+ final HttpServletResponse response)
+ throws IOException {
+ final AuthenticationSupport localAuthenticator = this.authenticator;
+ if ( localAuthenticator != null ) {
+ return localAuthenticator.handleSecurity(request, response);
+ }
+ // send 503/SERVICE UNAVAILABLE, flush to ensure delivery
+ response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+ response.flushBuffer();
+
+ // terminate this request now
+ return false;
+ }
+}
diff --git a/src/main/java/org/apache/sling/jcr/davex/impl/servlets/SlingDavExServlet.java b/src/main/java/org/apache/sling/jcr/davex/impl/servlets/SlingDavExServlet.java
index 8616ab3..6b4d524 100644
--- a/src/main/java/org/apache/sling/jcr/davex/impl/servlets/SlingDavExServlet.java
+++ b/src/main/java/org/apache/sling/jcr/davex/impl/servlets/SlingDavExServlet.java
@@ -16,15 +16,30 @@
*/
package org.apache.sling.jcr.davex.impl.servlets;
-import javax.jcr.Repository;
-import javax.servlet.Servlet;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+import javax.jcr.LoginException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.server.SessionProvider;
import org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.auth.core.AuthenticationSupport;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.http.HttpService;
/**
* DavEx WebDav servlet which acquires a Repository instance via the OSGi
@@ -32,7 +47,6 @@
*
*/
@Component(label = "%dav.name", description = "%dav.description")
-@Service(Servlet.class)
@Properties( { @Property(name = "alias", value = "/server"),
@Property(name = "init.resource-path-prefix", value = "/server"),
@Property(name = "init.missing-auth-mapping", value = ""),
@@ -40,12 +54,73 @@
@Property(name = "service.vendor", value = "The Apache Software Foundation") })
public class SlingDavExServlet extends JcrRemotingServlet {
+ private static final String INIT_KEY_PREFIX = "init.";
+
@Reference
private Repository repository;
+ @Reference
+ private HttpService httpService;
+
+ @Reference
+ private AuthenticationSupport authentiator;
+
+ @Activate
+ protected void activate(final ComponentContext ctx)
+ throws Exception {
+ final AuthHttpContext context = new AuthHttpContext();
+ context.setAuthenticationSupport(authentiator);
+
+ final String alias = (String)ctx.getProperties().get("alias");
+ final Dictionary<String, String> initProps = new Hashtable<String, String>();
+ @SuppressWarnings("unchecked")
+ final Enumeration<String> keyEnum = ctx.getProperties().keys();
+ while ( keyEnum.hasMoreElements() ) {
+ final String key = keyEnum.nextElement();
+ if ( key.startsWith(INIT_KEY_PREFIX) ) {
+ final String paramKey = key.substring(INIT_KEY_PREFIX.length());
+ final Object paramValue = ctx.getProperties().get(key);
+
+ if (paramValue != null) {
+ initProps.put(paramKey, paramValue.toString());
+ }
+ }
+ }
+
+ this.httpService.registerServlet(alias, this, initProps, context);
+ }
+
+ @Deactivate
+ protected void deactivate(final Map<String, Object> props) {
+ final String alias = (String)props.get("alias");
+ this.httpService.unregister(alias);
+ }
+
@Override
protected Repository getRepository() {
return repository;
}
+ @Override
+ protected SessionProvider getSessionProvider() {
+ return new SessionProvider() {
+
+ public Session getSession(final HttpServletRequest req,
+ final Repository paramRepository,
+ final String paramString)
+ throws LoginException, ServletException, RepositoryException {
+ final ResourceResolver resolver = (ResourceResolver) req.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER);
+ if ( resolver != null ) {
+ return resolver.adaptTo(Session.class);
+ }
+ return null;
+ }
+
+ public void releaseSession(Session paramSession) {
+ // nothing to do
+
+ }
+ };
+ }
+
}