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 2010/01/06 08:55:12 UTC
svn commit: r896345 [2/3] - in /sling/trunk/bundles/commons/auth: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/sling/ src/main/java/org/apache/sling/commons/
src/main/java/org/apache/sling/commo...
Added: 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=896345&view=auto
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java (added)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java Wed Jan 6 07:55:01 2010
@@ -0,0 +1,906 @@
+/*
+ * 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.commons.auth.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.jcr.Credentials;
+import javax.jcr.LoginException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.commons.auth.AuthenticationSupport;
+import org.apache.sling.commons.auth.Authenticator;
+import org.apache.sling.commons.auth.NoAuthenticationHandlerException;
+import org.apache.sling.commons.auth.impl.engine.EngineAuthenticationHandlerHolder;
+import org.apache.sling.commons.auth.spi.AuthenticationHandler;
+import org.apache.sling.commons.auth.spi.AuthenticationInfo;
+import org.apache.sling.commons.osgi.OsgiUtil;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.api.TooManySessionsException;
+import org.apache.sling.jcr.resource.JcrResourceResolverFactory;
+import org.osgi.framework.AllServiceListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.http.HttpContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>SlingAuthenticator</code> class is the default implementation for
+ * handling authentication. This class supports :
+ * <ul>
+ * <li>Support for login sessions where session ids are exchanged with cookies
+ * <li>Support for multiple authentication handlers, which must implement the
+ * {@link AuthenticationHandler} interface.
+ * <li>
+ * <p>
+ * Currently this class does not support multiple handlers for any one request
+ * URL.
+ * <p>
+ * Clients of this class use {@link #authenticate} method to create a
+ * {@link AuthenticationInfo} for the handling of the request. This method uses
+ * any of the handlers to extract the user information from the request. Next an
+ * object is created for this user information. If no user information is
+ * contained in the request (according to the handler), the anonymous info is
+ * used.
+ * <p>
+ *
+ * @scr.component name="org.apache.sling.engine.impl.auth.SlingAuthenticator"
+ * label="%auth.name" description="%auth.description"
+ * modified="modified" immediate="true" Register for three
+ * services
+ * @scr.service interface="org.apache.sling.commons.auth.AuthenticationSupport"
+ * @scr.service interface="org.apache.sling.commons.auth.Authenticator"
+ * @scr.service interface="javax.servlet.ServletRequestListener"
+ * @scr.property name="service.description" value="Sling Request Authenticator"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ * @scr.reference name="authHandler"
+ * interface="org.apache.sling.commons.auth.spi.AuthenticationHandler"
+ * policy="dynamic" cardinality="0..n" bind="bindAuthHandler"
+ * unbind="unbindAuthHandler"
+ * @scr.reference name="engineAuthHandler"
+ * interface="org.apache.sling.engine.auth.AuthenticationHandler"
+ * policy="dynamic" cardinality="0..n"
+ * bind="bindEngineAuthHandler" unbind="unbindEngineAuthHandler"
+ */
+public class SlingAuthenticator implements Authenticator,
+ AuthenticationSupport, ServletRequestListener {
+
+ static final String REQUEST_ATTRIBUTE_SESSION = "javax.jcr.Session";
+
+ /** default log */
+ private static final Logger log = LoggerFactory.getLogger(SlingAuthenticator.class);
+
+ /**
+ * @scr.property valueRef="DEFAULT_IMPERSONATION_COOKIE"
+ */
+ public static final String PAR_IMPERSONATION_COOKIE_NAME = "auth.sudo.cookie";
+
+ /**
+ * @scr.property valueRef="DEFAULT_IMPERSONATION_PARAMETER"
+ */
+ public static final String PAR_IMPERSONATION_PAR_NAME = "auth.sudo.parameter";
+
+ /**
+ * @scr.property valueRef="DEFAULT_ANONYMOUS_ALLOWED" type="Boolean"
+ */
+ public static final String PAR_ANONYMOUS_ALLOWED = "auth.annonymous";
+
+ /**
+ * @scr.property type="String" cardinality="+"
+ */
+ private static final String PAR_AUTH_REQ = "sling.auth.requirements";
+
+ /** The default impersonation parameter name */
+ private static final String DEFAULT_IMPERSONATION_PARAMETER = "sudo";
+
+ /** The default impersonation cookie name */
+ private static final String DEFAULT_IMPERSONATION_COOKIE = "sling.sudo";
+
+ /** The default value for allowing anonymous access */
+ private static final boolean DEFAULT_ANONYMOUS_ALLOWED = true;
+
+ private static ArrayList<AbstractAuthenticationHandlerHolder> EMPTY_INFO = new ArrayList<AbstractAuthenticationHandlerHolder>();
+
+ /** @scr.reference */
+ private SlingRepository repository;
+
+ /** @scr.reference */
+ private JcrResourceResolverFactory resourceResolverFactory;
+
+ private PathBasedHolderCache<AbstractAuthenticationHandlerHolder> authHandlerCache = new PathBasedHolderCache<AbstractAuthenticationHandlerHolder>();
+
+ // package protected for access in inner class ...
+ PathBasedHolderCache<AuthenticationRequirementHolder> authRequiredCache = new PathBasedHolderCache<AuthenticationRequirementHolder>();
+
+ /** The name of the impersonation parameter */
+ private String sudoParameterName;
+
+ /** The name of the impersonation cookie */
+ private String sudoCookieName;
+
+ /** Cache control flag */
+ private boolean cacheControl;
+
+ /** Web Console Plugin service registration */
+ private ServiceRegistration webConsolePlugin;
+
+ /**
+ * The listener for services registered with "sling.auth.requirements" to
+ * update the internal authentication requirements
+ */
+ private ServiceListener serviceListener;
+
+ // ---------- SCR integration
+
+ @SuppressWarnings("unused")
+ private void activate(final BundleContext bundleContext,
+ final Map<String, Object> properties) {
+ modified(properties);
+
+ AuthenticatorWebConsolePlugin plugin = new AuthenticatorWebConsolePlugin(
+ this);
+ Hashtable<String, Object> props = new Hashtable<String, Object>();
+ props.put("felix.webconsole.label", plugin.getLabel());
+ props.put("felix.webconsole.title", plugin.getTitle());
+ props.put("service.description",
+ "Sling Request Authenticator WebConsole Plugin");
+ props.put("service.vendor", properties.get("service.vendor"));
+
+ webConsolePlugin = bundleContext.registerService(
+ "javax.servlet.Servlet", plugin, props);
+
+ serviceListener = SlingAuthenticatorServiceListener.createListener(
+ bundleContext, this);
+ }
+
+ private void modified(Map<String, Object> properties) {
+ if (properties == null) {
+ properties = new HashMap<String, Object>();
+ }
+
+ String newCookie = (String) properties.get(PAR_IMPERSONATION_COOKIE_NAME);
+ if (newCookie == null || newCookie.length() == 0) {
+ newCookie = DEFAULT_IMPERSONATION_COOKIE;
+ }
+ if (!newCookie.equals(this.sudoCookieName)) {
+ log.info("Setting new cookie name for impersonation {} (was {})",
+ newCookie, this.sudoCookieName);
+ this.sudoCookieName = newCookie;
+ }
+
+ String newPar = (String) properties.get(PAR_IMPERSONATION_PAR_NAME);
+ if (newPar == null || newPar.length() == 0) {
+ newPar = DEFAULT_IMPERSONATION_PARAMETER;
+ }
+ if (!newPar.equals(this.sudoParameterName)) {
+ log.info(
+ "Setting new parameter name for impersonation {} (was {})",
+ newPar, this.sudoParameterName);
+ this.sudoParameterName = newPar;
+ }
+
+ authRequiredCache.clear();
+
+ boolean flag = OsgiUtil.toBoolean(
+ properties.get(PAR_ANONYMOUS_ALLOWED), DEFAULT_ANONYMOUS_ALLOWED);
+ authRequiredCache.addHolder(new AuthenticationRequirementHolder("/",
+ !flag));
+
+ String[] authReqs = OsgiUtil.toStringArray(properties.get(PAR_AUTH_REQ));
+ if (authReqs != null) {
+ for (String authReq : authReqs) {
+ if (authReq != null && authReq.length() > 0) {
+ authRequiredCache.addHolder(AuthenticationRequirementHolder.fromConfig(authReq));
+ }
+ }
+ }
+
+ // don't require authentication for login/logout servlets
+ authRequiredCache.addHolder(new AuthenticationRequirementHolder(
+ LoginServlet.SERVLET_PATH, false));
+ authRequiredCache.addHolder(new AuthenticationRequirementHolder(
+ LogoutServlet.SERVLET_PATH, false));
+ }
+
+ @SuppressWarnings("unused")
+ private void deactivate(final BundleContext bundleContext) {
+ if (serviceListener != null) {
+ bundleContext.removeServiceListener(serviceListener);
+ serviceListener = null;
+ }
+
+ if (webConsolePlugin != null) {
+ webConsolePlugin.unregister();
+ webConsolePlugin = null;
+ }
+ }
+
+ // --------- AuthenticationSupport interface
+
+ /**
+ * Checks the authentication contained in the request. This check is only
+ * based on the original request object, no URI translation has taken place
+ * yet.
+ * <p>
+ *
+ * @param req The request object containing the information for the
+ * authentication.
+ * @param res The response object which may be used to send the information
+ * on the request failure to the user.
+ */
+ public boolean handleSecurity(HttpServletRequest request,
+ HttpServletResponse response) {
+
+ // 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 = request.getAttribute(REQUEST_ATTRIBUTE_RESOLVER);
+ if (sessionAttr instanceof ResourceResolver) {
+ 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 ResourceResolver attribute ({})",
+ sessionAttr);
+ request.removeAttribute(REQUEST_ATTRIBUTE_RESOLVER);
+ }
+
+ // 1. Ask all authentication handlers to try to extract credentials
+ AuthenticationInfo authInfo = getAuthenticationInfo(request, response);
+
+ // 3. Check Credentials
+ if (authInfo == AuthenticationInfo.DOING_AUTH) {
+
+ log.debug("authenticate: ongoing authentication in the handler");
+ return false;
+
+ } else if (authInfo == null) {
+
+ log.debug("authenticate: no credentials in the request, anonymous");
+ return getAnonymousSession(request, response);
+
+ } else {
+ // try to connect
+ try {
+ log.debug("authenticate: credentials, trying to get a session");
+ Session session = repository.login(authInfo.getCredentials(),
+ authInfo.getWorkspaceName());
+
+ // handle impersonation
+ session = handleImpersonation(request, response, session);
+ setAttributes(session, authInfo.getAuthType(), request);
+
+ return true;
+
+ } catch (RepositoryException re) {
+
+ handleLoginFailure(request, response, re);
+
+ }
+
+ // end request
+ return false;
+ }
+ }
+
+ // ---------- Authenticator interface
+
+ /**
+ * Requests authentication information from the client. Returns
+ * <code>true</code> if the information has been requested and request
+ * processing can be terminated. Otherwise the request information could not
+ * be requested and the request should be terminated with a 403/FORBIDDEN
+ * response.
+ * <p>
+ * Any response sent by the handler is also handled by the error handler
+ * infrastructure.
+ *
+ * @param request The request object
+ * @param response The response object to which to send the request
+ * @throws IllegalStateException If response is already committed
+ * @throws NoAuthenticationHandlerException If no authentication handler
+ * claims responsibility to authenticate the request.
+ */
+ public void login(HttpServletRequest request, HttpServletResponse response) {
+
+ // ensure the response is not committed yet
+ if (response.isCommitted()) {
+ throw new IllegalStateException("Response already committed");
+ }
+
+ // select path used for authentication handler selection
+ final ArrayList<AbstractAuthenticationHandlerHolder> holderList = findApplicableAuthenticationHandlers(request);
+ final String path = getHandlerSelectionPath(request);
+ boolean done = false;
+ for (int i = 0; !done && i < holderList.size(); i++) {
+ final AbstractAuthenticationHandlerHolder holder = holderList.get(i);
+ if (path.startsWith(holder.path)) {
+ log.debug("login: requesting authentication using handler: {}",
+ holder);
+
+ try {
+ done = holder.requestAuthentication(request, response);
+ } catch (IOException ioe) {
+ log.error(
+ "login: Failed sending authentication request through handler "
+ + holder + ", access forbidden", ioe);
+ done = true;
+ }
+ }
+ }
+
+ // no handler could send an authentication request, throw
+ if (!done) {
+ log.info("login: No handler for request ({} handlers available)",
+ holderList.size());
+ throw new NoAuthenticationHandlerException();
+ }
+ }
+
+ /**
+ * Logs out the user calling all applicable
+ * {@link org.apache.sling.engine.auth.AuthenticationHandler2}
+ * authentication handlers.
+ *
+ * @since 2.1
+ */
+ public void logout(HttpServletRequest request, HttpServletResponse response) {
+
+ // ensure the response is not committed yet
+ if (response.isCommitted()) {
+ throw new IllegalStateException("Response already committed");
+ }
+
+ final ArrayList<AbstractAuthenticationHandlerHolder> holderList = findApplicableAuthenticationHandlers(request);
+ final String path = getHandlerSelectionPath(request);
+ for (int i = 0; i < holderList.size(); i++) {
+ AbstractAuthenticationHandlerHolder holder = holderList.get(i);
+ if (path.startsWith(holder.path)) {
+ log.debug("logout: dropping authentication using handler: {}",
+ holder);
+
+ try {
+ holder.dropAuthentication(request, response);
+ } catch (IOException ioe) {
+ log.error(
+ "logout: Failed dropping authentication through handler "
+ + holder, ioe);
+ }
+ }
+ }
+ }
+
+ // ---------- ServletRequestListener
+
+ public void requestInitialized(ServletRequestEvent sre) {
+ // don't care
+ }
+
+ public void requestDestroyed(ServletRequestEvent sre) {
+ ServletRequest request = sre.getServletRequest();
+ Object sessionAttr = request.getAttribute(SlingAuthenticatorSession.ATTR_NAME);
+ if (sessionAttr instanceof SlingAuthenticatorSession) {
+ ((SlingAuthenticatorSession) sessionAttr).logout();
+
+ request.removeAttribute(REQUEST_ATTRIBUTE_RESOLVER);
+ request.removeAttribute(REQUEST_ATTRIBUTE_SESSION);
+ request.removeAttribute(SlingAuthenticatorSession.ATTR_NAME);
+ }
+ }
+
+ // ---------- WebConsolePlugin support
+
+ ArrayList<AbstractAuthenticationHandlerHolder> getAuthenticationHandler() {
+ return authHandlerCache.getHolders();
+ }
+
+ ArrayList<AuthenticationRequirementHolder> getAuthenticationRequirements() {
+ return authRequiredCache.getHolders();
+ }
+
+ // ---------- internal
+
+ private ArrayList<AbstractAuthenticationHandlerHolder> findApplicableAuthenticationHandlers(
+ HttpServletRequest request) {
+
+ final ArrayList<AbstractAuthenticationHandlerHolder> infos = authHandlerCache.findApplicableHolder(request);
+ if (infos != null) {
+ return infos;
+ }
+
+ return EMPTY_INFO;
+ }
+
+ @SuppressWarnings("unused")
+ private void bindAuthHandler(final AuthenticationHandler handler,
+ Map<String, Object> properties) {
+ final String paths[] = OsgiUtil.toStringArray(properties.get(AuthenticationHandler.PATH_PROPERTY));
+ if (paths != null && paths.length > 0) {
+ for (int m = 0; m < paths.length; m++) {
+ if (paths[m] != null && paths[m].length() > 0) {
+ final AuthenticationHandlerHolder holder = new AuthenticationHandlerHolder(
+ paths[m], handler);
+ authHandlerCache.addHolder(holder);
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unused")
+ private void unbindAuthHandler(AuthenticationHandler handler,
+ Map<String, Object> properties) {
+ final String paths[] = OsgiUtil.toStringArray(properties.get(AuthenticationHandler.PATH_PROPERTY));
+ if (paths != null && paths.length > 0) {
+ for (int m = 0; m < paths.length; m++) {
+ if (paths[m] != null && paths[m].length() > 0) {
+ final AuthenticationHandlerHolder holder = new AuthenticationHandlerHolder(
+ paths[m], handler);
+ authHandlerCache.removeHolder(holder);
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings( { "unused", "deprecation" })
+ private void bindEngineAuthHandler(
+ org.apache.sling.engine.auth.AuthenticationHandler handler,
+ Map<String, Object> properties) {
+ final String paths[] = OsgiUtil.toStringArray(properties.get(AuthenticationHandler.PATH_PROPERTY));
+ if (paths != null && paths.length > 0) {
+ for (int m = 0; m < paths.length; m++) {
+ if (paths[m] != null && paths[m].length() > 0) {
+ final EngineAuthenticationHandlerHolder holder = new EngineAuthenticationHandlerHolder(
+ paths[m], handler);
+ authHandlerCache.addHolder(holder);
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings( { "unused", "deprecation" })
+ private void unbindEngineAuthHandler(
+ org.apache.sling.engine.auth.AuthenticationHandler handler,
+ Map<String, Object> properties) {
+ final String paths[] = OsgiUtil.toStringArray(properties.get(AuthenticationHandler.PATH_PROPERTY));
+ if (paths != null && paths.length > 0) {
+ for (int m = 0; m < paths.length; m++) {
+ if (paths[m] != null && paths[m].length() > 0) {
+ final EngineAuthenticationHandlerHolder holder = new EngineAuthenticationHandlerHolder(
+ paths[m], handler);
+ authHandlerCache.removeHolder(holder);
+ }
+ }
+ }
+ }
+
+ private AuthenticationInfo getAuthenticationInfo(
+ HttpServletRequest request, HttpServletResponse response) {
+
+ // Get the path used to select the authenticator, if the SlingServlet
+ // itself has been requested without any more info, this will be null
+ // and we assume the root (SLING-722)
+ String pathInfo = request.getPathInfo();
+ if (pathInfo == null || pathInfo.length() == 0) {
+ pathInfo = "/";
+ }
+
+ ArrayList<AbstractAuthenticationHandlerHolder> local = findApplicableAuthenticationHandlers(request);
+ for (int i = 0; i < local.size(); i++) {
+ AbstractAuthenticationHandlerHolder holder = local.get(i);
+ if (pathInfo.startsWith(holder.path)) {
+ final AuthenticationInfo authInfo = holder.authenticate(
+ request, response);
+ if (authInfo != null) {
+ return authInfo;
+ }
+ }
+ }
+
+ // no handler found for the request ....
+ log.debug("getCredentials: no handler could extract credentials");
+ return null;
+ }
+
+ /** Try to acquire an anonymous Session */
+ private boolean getAnonymousSession(HttpServletRequest req,
+ HttpServletResponse res) {
+
+ // Get an anonymous session if allowed, or if we are handling
+ // a request for the login servlet
+ if (isAnonAllowed(req)) {
+ try {
+ Session session = repository.login();
+ setAttributes(session, null, req);
+ return true;
+ } catch (RepositoryException re) {
+ // cannot login > fail login, do not try to authenticate
+ handleLoginFailure(req, res, re);
+ return false;
+ }
+ }
+
+ // If we get here, anonymous access is not allowed: redirect
+ // to the login servlet
+ log.info("getAnonymousSession: Anonymous access not allowed by configuration - redirecting to login");
+ login(req, res);
+
+ // fallback to no session
+ return false;
+ }
+
+ private boolean isAnonAllowed(HttpServletRequest request) {
+
+ String pathInfo = request.getPathInfo();
+ if (pathInfo == null || pathInfo.length() == 0) {
+ pathInfo = "/";
+ }
+
+ ArrayList<AuthenticationRequirementHolder> holderList = authRequiredCache.findApplicableHolder(request);
+ if (holderList != null && !holderList.isEmpty()) {
+ for (int i = 0; i < holderList.size(); i++) {
+ AuthenticationRequirementHolder holder = holderList.get(i);
+ if (pathInfo.startsWith(holder.path)) {
+ return !holder.requiresAuthentication();
+ }
+ }
+ }
+
+ if (LoginServlet.SERVLET_PATH.equals(pathInfo)) {
+ return true;
+ }
+
+ // fallback to anonymous not allowed (aka authentication required)
+ return false;
+ }
+
+ private void handleLoginFailure(HttpServletRequest request,
+ HttpServletResponse response, Exception reason) {
+
+ if (reason instanceof TooManySessionsException) {
+
+ // to many users, send a 503 Service Unavailable
+ log.info("authenticate: Too many sessions for user: {}",
+ reason.getMessage());
+
+ try {
+ response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
+ "SlingAuthenticator: Too Many Users");
+ } catch (IOException ioe) {
+ log.error("authenticate: Cannot send status 503 to client", ioe);
+ }
+
+ } else if (reason instanceof LoginException) {
+
+ // request authentication information and send 403 (Forbidden)
+ // if no handler can request authentication information.
+ log.info("authenticate: Unable to authenticate: {}",
+ reason.getMessage());
+ log.debug("authenticate", reason);
+
+ login(request, response);
+
+ } else {
+
+ // general problem, send a 500 Internal Server Error
+ log.error("authenticate: Unable to authenticate", reason);
+
+ try {
+ response.sendError(
+ HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "SlingAuthenticator: data access error, reason="
+ + reason.getClass().getSimpleName());
+ } catch (IOException ioe) {
+ log.error("authenticate: Cannot send status 500 to client", ioe);
+ }
+ }
+
+ }
+
+ /**
+ * 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(final Session session, final String authType,
+ final HttpServletRequest request) {
+
+ final ResourceResolver resolver = resourceResolverFactory.getResourceResolver(session);
+ final SlingAuthenticatorSession sas = new SlingAuthenticatorSession(
+ session);
+
+ // HttpService API required attributes
+ request.setAttribute(HttpContext.REMOTE_USER, session.getUserID());
+ request.setAttribute(HttpContext.AUTHENTICATION_TYPE, authType);
+
+ // resource resolver for down-stream use
+ request.setAttribute(REQUEST_ATTRIBUTE_RESOLVER, resolver);
+ request.setAttribute(SlingAuthenticatorSession.ATTR_NAME, sas);
+
+ // JCR session for backwards compatibility
+ request.setAttribute(REQUEST_ATTRIBUTE_SESSION, session);
+
+ log.debug(
+ "ResourceResolver stored as request attribute: user={}, workspace={}",
+ session.getUserID(), session.getWorkspace().getName());
+ }
+
+ /**
+ * Sends the session cookie for the name session with the given age in
+ * seconds. This sends a Version 1 cookie.
+ *
+ * @param response The {@link DeliveryHttpServletResponse} on which to send
+ * back the cookie.
+ * @param name The name of the cookie to send.
+ * @param value The value of cookie.
+ * @param maxAge The maximum age of the cookie in seconds. Positive values
+ * are persisted on the browser for the indicated number of
+ * seconds, setting the age to 0 (zero) causes the cookie to be
+ * deleted in the browser and using a negative value defines a
+ * temporary cookie to be deleted when the browser exits.
+ * @param path The cookie path to use. If empty or <code>null</code> the
+ */
+ private void sendCookie(HttpServletResponse response, String name,
+ String value, int maxAge, String path) {
+
+ if (path == null || path.length() == 0) {
+ log.debug("sendCookie: Using root path ''/''");
+ path = "/";
+ }
+
+ Cookie cookie = new Cookie(name, value);
+ cookie.setMaxAge(maxAge);
+ cookie.setPath(path);
+ response.addCookie(cookie);
+
+ // Tell a potential proxy server that this cookie is uncacheable
+ if (this.cacheControl) {
+ response.addHeader("Cache-Control", "no-cache=\"Set-Cookie\"");
+ }
+ }
+
+ /**
+ * Handles impersonation based on the request parameter for impersonation
+ * (see {@link #sudoParameterName}) and the current setting in the sudo
+ * cookie.
+ * <p>
+ * 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.
+ *
+ * @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.
+ * @return The impersonated session or the input session.
+ * @throws LoginException thrown by the {@link Session#impersonate} method.
+ * @throws ContentBusException thrown by the {@link Session#impersonate}
+ * method.
+ * @see Session#impersonate for details on the user configuration
+ * requirements for impersonation.
+ */
+ private Session handleImpersonation(HttpServletRequest req,
+ HttpServletResponse res, Session session) throws LoginException,
+ RepositoryException {
+
+ // the current state of impersonation
+ String currentSudo = null;
+ Cookie[] cookies = req.getCookies();
+ if (cookies != null) {
+ for (int i = 0; currentSudo == null && i < cookies.length; i++) {
+ if (sudoCookieName.equals(cookies[i].getName())) {
+ currentSudo = cookies[i].getValue();
+ }
+ }
+ }
+
+ /**
+ * sudo parameter : empty or missing to continue to use the setting
+ * already stored in the session; or "-" to remove impersonationa
+ * altogether (also from the session); or the handle of a user page to
+ * impersonate as that user (if possible)
+ */
+ String sudo = req.getParameter(this.sudoParameterName);
+ if (sudo == null || sudo.length() == 0) {
+ sudo = currentSudo;
+ } else if ("-".equals(sudo)) {
+ sudo = null;
+ }
+
+ // sudo the session if needed
+ if (sudo != null && sudo.length() > 0) {
+ Credentials creds = new SimpleCredentials(sudo, new char[0]);
+ session = session.impersonate(creds);
+ }
+ // invariant: same session or successful impersonation
+
+ // set the (new) impersonation
+ if (sudo != currentSudo) {
+ if (sudo == null) {
+ // Parameter set to "-" to clear impersonation, which was
+ // active due to cookie setting
+
+ // clear impersonation
+ this.sendCookie(res, this.sudoCookieName, "", 0,
+ req.getContextPath());
+
+ } else if (currentSudo == null || !currentSudo.equals(sudo)) {
+ // Parameter set to a name. As the cookie is not set yet
+ // or is set to another name, send the cookie with current sudo
+
+ // (re-)set impersonation
+ this.sendCookie(res, this.sudoCookieName, sudo, -1,
+ req.getContextPath());
+ }
+ }
+
+ // return the session
+ return session;
+ }
+
+ /**
+ * Returns the path to be used to select the authentication handler to login
+ * or logout with.
+ * <p>
+ * This method uses the {@link Authenticator#LOGIN_RESOURCE} request
+ * attribute. If this attribute is not set (or is not a string), the request
+ * path info is used. If this is not set either, or is the empty string, "/"
+ * is returned.
+ *
+ * @param request The request providing the request attribute or path info.
+ * @return The path as set by the request attribute or the path info or "/"
+ * if neither is set.
+ */
+ private String getHandlerSelectionPath(HttpServletRequest request) {
+ final Object loginPathO = request.getAttribute(Authenticator.LOGIN_RESOURCE);
+ String path = (loginPathO instanceof String)
+ ? (String) loginPathO
+ : request.getPathInfo();
+ if (path == null || path.length() == 0) {
+ path = "/";
+ }
+ return path;
+ }
+
+ private static class SlingAuthenticatorSession {
+
+ static final String ATTR_NAME = "$$org.apache.sling.commons.auth.impl.SlingAuthenticatorSession$$";
+
+ private Session session;
+
+ SlingAuthenticatorSession(final Session session) {
+ this.session = session;
+ }
+
+ void logout() {
+ if (session != null) {
+ try {
+ // logout if session is still alive (and not logged out)
+ if (session.isLive()) {
+ session.logout();
+ }
+ } catch (Throwable t) {
+ // TODO: log
+ } finally {
+ session = null;
+ }
+ }
+ }
+
+ @Override
+ protected void finalize() {
+ logout();
+ }
+ }
+
+ private static class SlingAuthenticatorServiceListener implements
+ AllServiceListener {
+
+ private final SlingAuthenticator authenticator;
+
+ private final HashMap<Object, String[]> props = new HashMap<Object, String[]>();
+
+ static ServiceListener createListener(final BundleContext context,
+ final SlingAuthenticator authenticator) {
+ SlingAuthenticatorServiceListener listener = new SlingAuthenticatorServiceListener(
+ authenticator);
+ try {
+ final String filter = "(" + PAR_AUTH_REQ + "=*)";
+ context.addServiceListener(listener,filter);
+ ServiceReference[] refs = context.getAllServiceReferences(null, filter);
+ if (refs != null) {
+ for (ServiceReference ref : refs) {
+ listener.addService(ref);
+ }
+ }
+ return listener;
+ } catch (InvalidSyntaxException ise) {
+ }
+ return null;
+ }
+
+ private SlingAuthenticatorServiceListener(
+ final SlingAuthenticator authenticator) {
+ this.authenticator = authenticator;
+ }
+
+ public void serviceChanged(ServiceEvent event) {
+
+ // modification of service properties, unregistration of the
+ // service or service properties does not contain requirements
+ // property any longer (new event with type 8 added in OSGi Core
+ // 4.2)
+ if ((event.getType() & (ServiceEvent.MODIFIED
+ | ServiceEvent.UNREGISTERING | 8)) != 0) {
+ removeService(event.getServiceReference());
+ }
+
+ // add requirements for newly registered services and for
+ // updated services
+ if ((event.getType() & (ServiceEvent.REGISTERED | ServiceEvent.MODIFIED)) != 0) {
+ addService(event.getServiceReference());
+ }
+ }
+
+ private void addService(final ServiceReference ref) {
+ String[] authReqs = OsgiUtil.toStringArray(ref.getProperty(PAR_AUTH_REQ));
+ for (String authReq : authReqs) {
+ if (authReq != null && authReq.length() > 0) {
+ authenticator.authRequiredCache.addHolder(AuthenticationRequirementHolder.fromConfig(authReq));
+ }
+ }
+ props.put(ref.getProperty(Constants.SERVICE_ID), authReqs);
+ }
+
+ private void removeService(final ServiceReference ref) {
+ String[] authReqs = props.remove(ref.getProperty(Constants.SERVICE_ID));
+ for (String authReq : authReqs) {
+ if (authReq != null && authReq.length() > 0) {
+ authenticator.authRequiredCache.removeHolder(AuthenticationRequirementHolder.fromConfig(authReq));
+ }
+ }
+ }
+ };
+
+}
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineAuthenticationHandlerHolder.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineAuthenticationHandlerHolder.java?rev=896345&view=auto
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineAuthenticationHandlerHolder.java (added)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineAuthenticationHandlerHolder.java Wed Jan 6 07:55:01 2010
@@ -0,0 +1,96 @@
+/*
+ * 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.commons.auth.impl.engine;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.commons.auth.impl.AbstractAuthenticationHandlerHolder;
+import org.apache.sling.commons.auth.spi.AuthenticationInfo;
+import org.apache.sling.engine.auth.AuthenticationHandler;
+
+/**
+ * The <code>EngineAuthenticationHandlerHolder</code> class represents an
+ * old-style Sling {@link AuthenticationHandler} service in the internal data
+ * structure of the
+ * {@link org.apache.sling.commons.auth.impl.SlingAuthenticator}.
+ */
+@SuppressWarnings("deprecation")
+public final class EngineAuthenticationHandlerHolder extends
+ AbstractAuthenticationHandlerHolder {
+
+ // the actual authentication handler
+ private final AuthenticationHandler handler;
+
+ public EngineAuthenticationHandlerHolder(final String fullPath,
+ final AuthenticationHandler handler) {
+ super(fullPath);
+ this.handler = handler;
+ }
+
+ public AuthenticationInfo doAuthenticate(HttpServletRequest request,
+ HttpServletResponse response) {
+
+ org.apache.sling.engine.auth.AuthenticationInfo engineAuthInfo = handler.authenticate(
+ request, response);
+ if (engineAuthInfo == null) {
+ return null;
+ } else if (engineAuthInfo == org.apache.sling.engine.auth.AuthenticationInfo.DOING_AUTH) {
+ return AuthenticationInfo.DOING_AUTH;
+ }
+
+ return new AuthenticationInfo(engineAuthInfo.getAuthType(),
+ engineAuthInfo.getCredentials(), engineAuthInfo.getWorkspaceName());
+
+ }
+
+ public boolean doRequestAuthentication(HttpServletRequest request,
+ HttpServletResponse response) throws IOException {
+ return handler.requestAuthentication(request, response);
+ }
+
+ public void doDropAuthentication(HttpServletRequest request,
+ HttpServletResponse response) {
+ // Engine AuthenticationHandler does not have this method
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+
+ // equality is the base class equality (based on the fullpath)
+ // and the encapsulated holders being the same.
+ if (super.equals(obj)) {
+ if (obj.getClass() == getClass()) {
+ EngineAuthenticationHandlerHolder other = (EngineAuthenticationHandlerHolder) obj;
+ return other.handler == handler;
+ }
+ }
+
+ // handlers are not the same, so the holders are not the same
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return handler.toString() + " (Legacy API Handler)";
+ }
+
+}
\ No newline at end of file
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineAuthenticationHandlerHolder.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineAuthenticationHandlerHolder.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineSlingAuthenticator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineSlingAuthenticator.java?rev=896345&view=auto
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineSlingAuthenticator.java (added)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineSlingAuthenticator.java Wed Jan 6 07:55:01 2010
@@ -0,0 +1,54 @@
+/*
+ * 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.commons.auth.impl.engine;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.engine.auth.Authenticator;
+
+/**
+ * The <code>EngineSlingAuthenticator</code> class is a simple proxy service
+ * providing the old Sling Engine {@link Authenticator} service calling into the
+ * new standalone Apache Sling
+ * {@link org.apache.sling.commons.auth.Authenticator} service.
+ *
+ * @scr.component metatype="no"
+ * @scr.service interface="org.apache.sling.engine.auth.Authenticator"
+ * @scr.property name="service.description"
+ * value="Apache Sling Request Authenticator (Legacy Bridge)"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ */
+@SuppressWarnings("deprecation")
+public class EngineSlingAuthenticator implements Authenticator {
+
+ /**
+ * @scr.reference
+ */
+ private org.apache.sling.commons.auth.Authenticator slingAuthenticator;
+
+ public void login(HttpServletRequest request, HttpServletResponse response) {
+ slingAuthenticator.login(request, response);
+ }
+
+ public void logout(HttpServletRequest request, HttpServletResponse response) {
+ slingAuthenticator.logout(request, response);
+ }
+
+}
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineSlingAuthenticator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineSlingAuthenticator.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationHandler.java?rev=896345&view=auto
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationHandler.java (added)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationHandler.java Wed Jan 6 07:55:01 2010
@@ -0,0 +1,143 @@
+/*
+ * 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.commons.auth.spi;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * The <code>AuthenticationHandler</code> interface defines the service API used
+ * by the authentication implementation to support plugin various ways of
+ * extracting credentials from the request.
+ */
+public interface AuthenticationHandler {
+
+ /**
+ * The name under which an implementation of this interface must be
+ * registered to be used as an authentication handler.
+ */
+ static final String SERVICE_NAME = "org.apache.sling.commons.auth.AuthenticationHandler";
+
+ /**
+ * The name of the service registration property listing one or more URL
+ * paths for which the authentication handler is to be used. The property
+ * may be a single string value or an array of strings or a Collection of
+ * strings.
+ * <p>
+ * Each string value may either be an absolute path (e.g. /content) or an
+ * absolute URL (e.g. http://thehost/content) to assign the authentication
+ * handler to authenticate request for a select virtual host.
+ * <p>
+ * Authentication handlers without a <code>path</code> service registration
+ * property are ignored.
+ */
+ static final String PATH_PROPERTY = "path";
+
+ /**
+ * Extracts credential data from the request if at all contained.
+ * <p>
+ * The method returns any of the following values :
+ * <table>
+ * <tr>
+ * <th>value
+ * <th>description
+ * </tr>
+ * <tr>
+ * <td><code>null</code>
+ * <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 AuthenticationInfo#DOING_AUTH}
+ * <td>the handler is in an ongoing authentication transaction with the
+ * client. Request processing should be aborted at this stage.
+ * <tr>
+ * <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
+ * they are not found in the request.
+ * <p>
+ * The value of {@link #PATH_PROPERTY} service registration property value
+ * triggering this call is available as the <code>path</code> request
+ * attribute. If the service is registered with multiple path values, the
+ * value of the <code>path</code> request attribute may be used to implement
+ * specific handling.
+ *
+ * @param request The request object containing the information for the
+ * 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>AuthenticationInfo</code> instance identifying the
+ * request user, {@link AuthenticationInfo#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 AuthenticationInfo#DOING_AUTH}, the method must
+ * have sent a response indicating that fact to the client.
+ */
+ AuthenticationInfo authenticate(HttpServletRequest request,
+ HttpServletResponse response);
+
+ /**
+ * Requests authentication information from the client. Returns
+ * <code>true</code> if the information has been requested and request
+ * processing can be terminated normally. Otherwise the authorization
+ * information could not be requested.
+ * <p>
+ * The <code>HttpServletResponse.sendError</code> methods should not be used
+ * by the implementation because these responses might be post-processed by
+ * the servlet container's error handling infrastructure thus preventing the
+ * correct operation of the authentication handler. To convey a HTTP
+ * response status the <code>HttpServletResponse.setStatus</code> method
+ * should be used.
+ * <p>
+ * The value of {@link #PATH_PROPERTY} service registration property value
+ * triggering this call is available as the <code>path</code> request
+ * attribute. If the service is registered with multiple path values, the
+ * value of the <code>path</code> request attribute may be used to implement
+ * specific handling.
+ *
+ * @param request The request object.
+ * @param response The response object to which to send the request.
+ * @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) throws IOException;
+
+ /**
+ * Drops any credential and authentication details from the request and asks
+ * the client to do the same.
+ *
+ * @param request The request object.
+ * @param response The response object to which to send the request.
+ * @throws IOException If an error occurrs asking the client to drop any
+ * authentication traces.
+ */
+ void dropAuthentication(HttpServletRequest request,
+ HttpServletResponse response) throws IOException;
+}
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationHandler.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationInfo.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationInfo.java?rev=896345&view=auto
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationInfo.java (added)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationInfo.java Wed Jan 6 07:55:01 2010
@@ -0,0 +1,323 @@
+/*
+ * 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.commons.auth.spi;
+
+import java.util.HashMap;
+import javax.jcr.Credentials;
+import javax.jcr.SimpleCredentials;
+
+/**
+ * The <code>AuthenticationInfo</code> conveys any authentication credentials
+ * and/or details extracted by the
+ * {@link AuthenticationHandler#authenticate(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
+ * method from the request.
+ * <p>
+ * {@link AuthenticationHandler} implementations must return instances of this
+ * class which may be constructed through any of the provided public
+ * constructors.
+ * <p>
+ * Internally all values are stored in the map where some property names have
+ * special semantics and the data type of the properties are ensured by the
+ * {@link #put(String, Object)} method implementation.
+ */
+@SuppressWarnings("serial")
+public class AuthenticationInfo extends HashMap<String, Object> {
+
+ /**
+ * A special instance of this class which is returned by the
+ * {@link AuthenticationHandler#authenticate(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
+ * method to inform the caller, that a response has been sent to the client
+ * to request for credentials.
+ * <p>
+ * If this value is returned, the request should be considered finished and
+ * no further actions should be taken on this request.
+ */
+ public static final AuthenticationInfo DOING_AUTH = new AuthenticationInfo();
+
+ /**
+ * The name of the special property providing the authentication type
+ * provided by the {@link AuthenticationHandler}. This value must be
+ * supplied to one of the constructors and is ultimately used as the value
+ * of the <code>HttpServletRequest.getAuthType</code> method.
+ * <p>
+ * This property is always present (and cannot be removed) in this map and
+ * is of <code>String</code> type.
+ */
+ public static final String AUTH_TYPE = "sling.authType";
+
+ /**
+ * The name of the property providing the name of the user on whose behalf
+ * the request is being handled. This property is set by the
+ * {@link #AuthenticationInfo(String, String, char[], String)} constructor
+ * and may be <code>null</code> if this instance is created by either the
+ * {@link #AuthenticationInfo(String, Credentials)} or
+ * {@link #AuthenticationInfo(String, Credentials, String)} constructors.
+ * <p>
+ * The type of this property, if present, is <code>String</code>.
+ */
+ public static final String USER = "user.name";
+
+ /**
+ * The name of the property providing the password of the user on whose
+ * behalf the request is being handled. This property is set by the
+ * {@link #AuthenticationInfo(String, String, char[], String)} constructor
+ * and may be <code>null</code> if this instance is created by either the
+ * {@link #AuthenticationInfo(String, Credentials)} or
+ * {@link #AuthenticationInfo(String, Credentials, String)} constructors.
+ * <p>
+ * The type of this property, if present, is <code>char[]</code>.
+ */
+ public static final String PASSWORD = "user.password";
+
+ /**
+ * The name of the property providing the JCR credentials. These credentials
+ * are preset to the credentials given to the
+ * {@link #AuthenticationInfo(String, Credentials)} or
+ * {@link #AuthenticationInfo(String, Credentials, String)} constructors. If
+ * the {@link #AuthenticationInfo(String, String, char[], String)}
+ * constructor is used the credentials property is set to a JCR
+ * <code>SimpleCredentials</code> instance containing the user id and
+ * password passed to the constructor.
+ */
+ public static final String CREDENTIALS = "user.jcr.credentials";
+
+ /**
+ * The name of the property providing the name of the JCR workspace to which
+ * the request should be connected. This property may be set by any of the
+ * constructors. If this property is not set, the user will be connected to
+ * a default workspace as defined by the JCR repository to which the request
+ * is connected.
+ * <p>
+ * The type of this property, if present, is <code>String</code>.
+ */
+ public static final String WORKSPACE = "user.jcr.workspace";
+
+ /** Creates an empty instance, used for the {@link #DOING_AUTH} constant */
+ private AuthenticationInfo() {
+ super.put(AUTH_TYPE, "Authentication in Progress");
+ }
+
+ /**
+ * Creates an instance of this class with the given authentication type and
+ * credentials connecting to the default workspace as if the
+ * {@link #AuthenticationInfo(String, Credentials, String)} method would be
+ * called with a <code>null</code> workspace name.
+ *
+ * @param authType The authentication type, must not be <code>null</code>.
+ * @param credentials The credentials, must not be <code>null</code>.
+ * @throws NullPointerException if <code>authType</code> is
+ * <code>null</code> .
+ */
+ public AuthenticationInfo(final String authType,
+ final Credentials credentials) {
+ this(authType, 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>.
+ * @param workspaceName The name of the workspace to connect to, may be
+ * <code>null</code> to connect to the default workspace.
+ * @throws NullPointerException if <code>authType</code> is
+ * <code>null</code> .
+ */
+ public AuthenticationInfo(final String authType,
+ final Credentials credentials, final String workspaceName) {
+ if (authType == null) {
+ throw new NullPointerException("authType");
+ }
+
+ super.put(AUTH_TYPE, authType);
+ putIfNotNull(CREDENTIALS, credentials);
+ putIfNotNull(WORKSPACE, workspaceName);
+ }
+
+ /**
+ * 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>.
+ * @param workspaceName The name of the workspace to connect to, may be
+ * <code>null</code> to connect to the default workspace.
+ * @throws NullPointerException if <code>authType</code> is
+ * <code>null</code>
+ */
+ public AuthenticationInfo(final String authType, final String userId,
+ final char[] password, final String workspaceName) {
+ if (authType == null) {
+ throw new NullPointerException("authType");
+ }
+
+ super.put(AUTH_TYPE, authType);
+ putIfNotNull(USER, userId);
+ putIfNotNull(PASSWORD, password);
+ putIfNotNull(WORKSPACE, workspaceName);
+
+ // also store credentials if the user id is not null/empty
+ if (userId != null && userId.length() > 0) {
+ final char[] pwd = (password == null) ? new char[0] : password;
+ super.put(CREDENTIALS, new SimpleCredentials(userId, pwd));
+ }
+ }
+
+ /**
+ * Returns the authentication type stored as the {@link #AUTH_TYPE} property
+ * in this map. This value is expected to never be <code>null</code>.
+ * <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 (String) get(AUTH_TYPE);
+ }
+
+ /**
+ * Returns the user name stored as the {@link #USER} property or
+ * <code>null</code> if the user is not set in this map.
+ */
+ public String getUser() {
+ return (String) get(USER);
+ }
+
+ /**
+ * Returns the password stored as the {@link #PASSWORD} property or
+ * <code>null</code> if the password is not set in this map.
+ */
+ public char[] getPassword() {
+ return (char[]) get(PASSWORD);
+ }
+
+ /**
+ * Returns the workspace name stored as the {@link #WORKSPACE} property or
+ * <code>null</code> if the workspace name is not set in this map.
+ */
+ public String getWorkspaceName() {
+ return (String) get(WORKSPACE);
+ }
+
+ /**
+ * Returns the JCR credentials stored as the {@link #CREDENTIALS} property
+ * or <code>null</code> if the credentials are not set in this map.
+ */
+ public Credentials getCredentials() {
+ return (Credentials) get(CREDENTIALS);
+ }
+
+ /**
+ * Sets or resets a property with the given <code>key</code> to a new
+ * <code>value</code>. Some keys have special meanings and their values are
+ * required to have predefined as listed in the following table:
+ * <table>
+ * <tr>
+ * <td>{@link #AUTH_TYPE}</td>
+ * <td><code>String</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link #USER}</td>
+ * <td><code>String</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link #PASSWORD}</td>
+ * <td><code>char[]</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link #CREDENTIALS}</td>
+ * <td><code>javax.jcr.Credentials</code></td>
+ * </tr>
+ * <tr>
+ * <td>{@link #WORKSPACE}</td>
+ * <td><code>String</code></td>
+ * </tr>
+ * </table>
+ * <p>
+ * If the value for the special key does not match the required type an
+ * <code>IllegalArgumentException</code> is thrown.
+ *
+ * @param key The name of the property to set
+ * @param value The value of the property which must be of a special type if
+ * the <code>key</code> designates one of the predefined
+ * properties.
+ * @return The value previously set for the given <code>key</code>.
+ * @throws IllegalArgumentException if <code>key</code> designates one of
+ * the special properties and the <code>value</code> does not
+ * have the correct type for the respective key.
+ */
+ @Override
+ public Object put(final String key, final Object value) {
+
+ if (AUTH_TYPE.equals(key) && !(value instanceof String)) {
+ throw new IllegalArgumentException(AUTH_TYPE
+ + " property must be a String");
+ }
+
+ if (USER.equals(key) && !(value instanceof String)) {
+ throw new IllegalArgumentException(USER
+ + " property must be a String");
+ }
+
+ if (PASSWORD.equals(key) && !(value instanceof char[])) {
+ throw new IllegalArgumentException(PASSWORD
+ + " property must be a char[]");
+ }
+
+ if (CREDENTIALS.equals(key) && !(value instanceof String)) {
+ throw new IllegalArgumentException(CREDENTIALS
+ + " property must be a javax.jcr.Credentials instance");
+ }
+
+ if (WORKSPACE.equals(key) && !(value instanceof String)) {
+ throw new IllegalArgumentException(WORKSPACE
+ + " property must be a String");
+ }
+
+ return super.put(key, value);
+ }
+
+ /**
+ * Removes the entry with the given <code>key</code> and returns its former
+ * value (if existing). If the <code>key</code> is {@link #AUTH_TYPE} the
+ * value is not actually removed and <code>null</code> is always returned.
+ *
+ * @param key Removes the value associated with this key.
+ * @return The former value associated with the key.
+ */
+ @Override
+ public Object remove(Object key) {
+
+ // don't return the auth type from the map
+ if (!AUTH_TYPE.equals(key)) {
+ return null;
+ }
+
+ return super.remove(key);
+ }
+
+ // helper to only set the property if the value is not null
+ private void putIfNotNull(final String key, final Object value) {
+ if (value != null) {
+ super.put(key, value);
+ }
+ }
+}
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationInfo.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationHandler.java?rev=896345&view=auto
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationHandler.java (added)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationHandler.java Wed Jan 6 07:55:01 2010
@@ -0,0 +1,117 @@
+/*
+ * 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.engine.auth;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * The <code>AuthenticationHandler</code> interface defines the service API used
+ * by the authentication implementation to support plugin various ways of
+ * extracting credentials from the request.
+ *
+ * @deprecated use
+ * {@link org.apache.sling.commons.auth.spi.AuthenticationHandler}
+ * instead
+ */
+public interface AuthenticationHandler {
+
+ /**
+ * An authentication handler is associated with url paths. If the handler is
+ * not configured with a path, it is regarded as inactive. If the handler
+ * should be used for all requests, the path should be '/'.
+ */
+ String PATH_PROPERTY = "path";
+
+ /**
+ * Extracts credential data from the request if at all contained.
+ * <p>
+ * The method returns any of the following values :
+ * <table>
+ * <tr>
+ * <th>value
+ * <th>description
+ * </tr>
+ * <tr>
+ * <td><code>null</code>
+ * <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 AuthenticationInfo#DOING_AUTH}
+ * <td>the handler is in an ongoing authentication transaction with the
+ * client. Request processing should be aborted at this stage.
+ * <tr>
+ * <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
+ * they are not found in the request.
+ * <p>
+ * The value of {@link #PATH_PROPERTY} service registration property value
+ * triggering this call is available as the <code>path</code> request
+ * attribute. If the service is registered with multiple path values, the
+ * value of the <code>path</code> request attribute may be used to implement
+ * specific handling.
+ *
+ * @param request The request object containing the information for the
+ * 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>AuthenticationInfo</code> instance identifying the
+ * request user, {@link AuthenticationInfo#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 AuthenticationInfo#DOING_AUTH}, the method must
+ * have sent a response indicating that fact to the client.
+ */
+ AuthenticationInfo authenticate(HttpServletRequest request,
+ HttpServletResponse response);
+
+ /**
+ * Requests authentication information from the client. Returns
+ * <code>true</code> if the information has been requested and request
+ * processing can be terminated normally. Otherwise the authorization
+ * information could not be requested.
+ * <p>
+ * Any response sent by the handler though the <code>sendError</code> method
+ * is also handled by the error handler infrastructure.
+ * <p>
+ * The value of {@link #PATH_PROPERTY} service registration property value
+ * triggering this call is available as the <code>path</code> request
+ * attribute. If the service is registered with multiple path values, the
+ * value of the <code>path</code> request attribute may be used to implement
+ * specific handling.
+ *
+ * @param request The request object.
+ * @param response The response object to which to send the request.
+ * @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) throws IOException;
+}
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationHandler.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationInfo.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationInfo.java?rev=896345&view=auto
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationInfo.java (added)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationInfo.java Wed Jan 6 07:55:01 2010
@@ -0,0 +1,117 @@
+/*
+ * 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.engine.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.
+ *
+ * @deprecated see {@link AuthenticationHandler}
+ */
+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;
+
+ /**
+ * The name of the workspace this user is wishing to login,
+ * <code>null</code> means the default workspace.
+ */
+ private final String workspaceName;
+
+ /** Creates an empty instance, used for the {@link #DOING_AUTH} constants */
+ private AuthenticationInfo() {
+ this(null, null, null);
+ }
+
+ /**
+ * Creates an instance of this class with the given authentication type and
+ * credentials connecting to the default workspace as if the
+ * {@link #AuthenticationInfo(String, Credentials, String)} method would be
+ * called with a <code>null</code> workspace name.
+ *
+ * @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, 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>.
+ * @param workspaceName The name of the workspace to connect to, may be
+ * <code>null</code> to connect to the default workspace.
+ * @see #getAuthType()
+ * @see #getCredentials()
+ */
+ public AuthenticationInfo(String authType, Credentials credentials,
+ String workspaceName) {
+ this.authType = authType;
+ this.credentials = credentials;
+ this.workspaceName = workspaceName;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Returns the name of the workspace the user contained in this instance
+ * wishes to connect to. This may be <code>null</code>, in which case the
+ * user is connected to the default workspace.
+ */
+ public String getWorkspaceName() {
+ return workspaceName;
+ }
+}
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/AuthenticationInfo.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/Authenticator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/Authenticator.java?rev=896345&view=auto
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/Authenticator.java (added)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/Authenticator.java Wed Jan 6 07:55:01 2010
@@ -0,0 +1,62 @@
+/*
+ * 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.engine.auth;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * The <code>Authenticator</code> interface defines the service interface of the
+ * authenticator used by the Sling engine. This service provides a method to
+ * find an {@link AuthenticationHandler} and call its
+ * {@link AuthenticationHandler#requestAuthentication(HttpServletRequest, HttpServletResponse)}
+ * method.
+ * <p>
+ * This interface is not intended to be implemented by applications but may be
+ * used to initiate the authentication process form a request processing servlet
+ * or script.
+ *
+ * @since 2.0.4
+ * @deprecated use {@link org.apache.sling.commons.auth.Authenticator} instead
+ */
+public interface Authenticator {
+
+ /**
+ * Finds an {@link AuthenticationHandler} for the given request and call its
+ * {@link AuthenticationHandler#requestAuthentication(HttpServletRequest, HttpServletResponse)}
+ * method to initiate an authentication process with the client to login to
+ * Sling.
+ * <p>
+ * This method must be called on an uncommitted response since the
+ * implementation may want to reset the response to start the authentication
+ * process with a clean response. If the response is already committed an
+ * <code>IllegalStateException</code> is thrown.
+ * <p>
+ * After this method has finished, request processing should be terminated
+ * and the response be considered committed and finished.
+ *
+ * @param request The object representing the client request.
+ * @param response The object representing the response to the client.
+ * @throws NoAuthenticationHandlerException If no authentication handler
+ * claims responsibility to authenticate the request.
+ * @throws IllegalStateException If the response has already been committed.
+ */
+ public void login(HttpServletRequest request, HttpServletResponse response);
+
+}
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/Authenticator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/Authenticator.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/NoAuthenticationHandlerException.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/NoAuthenticationHandlerException.java?rev=896345&view=auto
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/NoAuthenticationHandlerException.java (added)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/NoAuthenticationHandlerException.java Wed Jan 6 07:55:01 2010
@@ -0,0 +1,44 @@
+/*
+ * 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.engine.auth;
+
+import org.apache.sling.api.SlingException;
+
+/**
+ * The <code>NoAuthenticationHandlerException</code> is thrown to indicate that
+ * there is no {@link AuthenticationHandler} willing to handle the request.
+ * <p>
+ * This exception is thrown without a message. The caller of the
+ * {@link Authenticator} method called is expected to immediately handle this
+ * exception and not to forward it up the call chain.
+ * <p>
+ * This exception is not intended to be thrown by client code but is used by the
+ * {@link Authenticator} implementation to indicate, that no
+ * {@link AuthenticationHandler} is available to login.
+ *
+ * @deprecated see {@link Authenticator}
+ */
+@SuppressWarnings("serial")
+public class NoAuthenticationHandlerException extends SlingException {
+
+ public NoAuthenticationHandlerException() {
+ super();
+ }
+
+}
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/NoAuthenticationHandlerException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/engine/auth/NoAuthenticationHandlerException.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url