diff --git a/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java
index bf7a5a5d51..bdb4138012 100644
--- a/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java
+++ b/source/java/org/alfresco/repo/webdav/auth/BaseKerberosAuthenticationFilter.java
@@ -274,6 +274,10 @@ public abstract class BaseKerberosAuthenticationFilter extends BaseSSOAuthentica
restartLoginChallenge(context, req, resp);
return false;
}
+ else if (isFallbackEnabled())
+ {
+ return performFallbackAuthentication(context, req, resp);
+ }
}
// Check if the user is already authenticated
@@ -631,6 +635,12 @@ public abstract class BaseKerberosAuthenticationFilter extends BaseSSOAuthentica
getLogger().debug("Issuing login challenge to browser.");
// Force the logon to start again
resp.setHeader("WWW-Authenticate", "Negotiate");
+
+ if (isFallbackEnabled())
+ {
+ includeFallbackAuth(context, req, resp);
+ }
+
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
writeLoginPageLink(context, req, resp);
diff --git a/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java b/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java
index 368608fefe..34d160fa53 100644
--- a/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java
+++ b/source/java/org/alfresco/repo/webdav/auth/BaseSSOAuthenticationFilter.java
@@ -73,6 +73,8 @@ public abstract class BaseSSOAuthenticationFilter extends BaseAuthenticationFilt
private boolean m_isActive = true;
+ private AuthenticationDriver fallbackDelegate;
+
protected static final String MIME_HTML_TEXT = "text/html";
/**
@@ -104,6 +106,24 @@ public abstract class BaseSSOAuthenticationFilter extends BaseAuthenticationFilt
return m_isActive;
}
+ /**
+ * Activates or deactivates the fallback authentication support for this filter
+ *
+ * @param delegate
+ */
+ public final void setFallback(AuthenticationDriver delegate)
+ {
+ this.fallbackDelegate = delegate;
+ }
+
+ /**
+ * @return true
if fallback authentication enabled
+ */
+ public final boolean isFallbackEnabled()
+ {
+ return fallbackDelegate != null;
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
@@ -551,6 +571,53 @@ public abstract class BaseSSOAuthenticationFilter extends BaseAuthenticationFilt
}
}
+ /**
+ * Include into response authentication method that is supported by fallback mechanism
+ *
+ * @param context ServletContext
+ * @param req HttpServletRequest
+ * @param resp HttpServletResponse
+ * @throws IOException
+ */
+ protected void includeFallbackAuth(ServletContext context, HttpServletRequest req, HttpServletResponse resp) throws IOException
+ {
+ fallbackDelegate.restartLoginChallenge(context, req, resp);
+ }
+
+ /**
+ * Delegate authentication to the fallback mechanism
+ *
+ * @param context ServletContext
+ * @param req HttpServletRequest
+ * @param resp HttpServletResponse
+ * @return
+ * @throws IOException
+ * @throws ServletException
+ */
+ protected boolean performFallbackAuthentication(ServletContext context, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
+ {
+ if (getLogger().isDebugEnabled())
+ {
+ getLogger().debug("Performing fallback authentication...");
+ }
+
+ boolean fallbackSuccess = fallbackDelegate.authenticateRequest(context, req, resp);
+
+ if (!fallbackSuccess)
+ {
+ restartLoginChallenge(context, req, resp);
+ if (getLogger().isDebugEnabled())
+ {
+ getLogger().debug("Fallback authentication failed. Restarting login...");
+ }
+ }
+ if (fallbackSuccess && getLogger().isDebugEnabled())
+ {
+ getLogger().debug("Fallback authentication succeeded.");
+ }
+
+ return fallbackSuccess;
+ }
}
diff --git a/source/java/org/alfresco/repo/webdav/auth/SSOFallbackBasicAuthenticationDriver.java b/source/java/org/alfresco/repo/webdav/auth/SSOFallbackBasicAuthenticationDriver.java
new file mode 100644
index 0000000000..b41081045a
--- /dev/null
+++ b/source/java/org/alfresco/repo/webdav/auth/SSOFallbackBasicAuthenticationDriver.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2005-2014 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see
+ * Basic HTTP web authentication implementation. Main purpose to use as fallback authentication with SSO filters. + *
+ * + * @author pavel.yurkevich + */ +public class SSOFallbackBasicAuthenticationDriver implements AuthenticationDriver +{ + public static final String AUTHENTICATION_USER = "_alfAuthTicket"; + + private Log logger = LogFactory.getLog(SSOFallbackBasicAuthenticationDriver.class); + + private AuthenticationService authenticationService; + private PersonService personService; + private NodeService nodeService; + private TransactionService transactionService; + + private String userAttributeName = AUTHENTICATION_USER; + + public void setAuthenticationService(AuthenticationService authenticationService) + { + this.authenticationService = authenticationService; + } + + public void setPersonService(PersonService personService) + { + this.personService = personService; + } + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setTransactionService(TransactionService transactionService) + { + this.transactionService = transactionService; + } + + public void setUserAttributeName(String userAttributeName) + { + this.userAttributeName = userAttributeName; + } + + @Override + public boolean authenticateRequest(ServletContext context, HttpServletRequest request, HttpServletResponse response) + throws IOException, ServletException + { + String authHdr = request.getHeader("Authorization"); + HttpSession session = request.getSession(false); + SessionUser user = session == null ? null : (SessionUser) session.getAttribute(userAttributeName); + if (user == null) + { + if (authHdr != null && authHdr.length() > 5 && authHdr.substring(0, 5).equalsIgnoreCase("Basic")) + { + String basicAuth = new String(Base64.decodeBase64(authHdr.substring(5).getBytes())); + String username = null; + String password = null; + + int pos = basicAuth.indexOf(":"); + if (pos != -1) + { + username = basicAuth.substring(0, pos); + password = basicAuth.substring(pos + 1); + } + else + { + username = basicAuth; + password = ""; + } + + try + { + if (logger.isDebugEnabled()) + logger.debug("Authenticating user '" + username + "'"); + + authenticationService.authenticate(username, password.toCharArray()); + + final RetryingTransactionCallback