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 2009/02/08 23:00:06 UTC
svn commit: r742179 -
/incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/impl/auth/SlingAuthenticator.java
Author: fmeschbe
Date: Sun Feb 8 22:00:05 2009
New Revision: 742179
URL: http://svn.apache.org/viewvc?rev=742179&view=rev
Log:
SLING-849 Apply patch by Rory Douglas (thanks) allowing
for per-virtual host authentication handlers
Modified:
incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/impl/auth/SlingAuthenticator.java
Modified: incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/impl/auth/SlingAuthenticator.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/impl/auth/SlingAuthenticator.java?rev=742179&r1=742178&r2=742179&view=diff
==============================================================================
--- incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/impl/auth/SlingAuthenticator.java (original)
+++ incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/impl/auth/SlingAuthenticator.java Sun Feb 8 22:00:05 2009
@@ -20,11 +20,13 @@
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.Comparator;
import java.util.Dictionary;
+import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
+import java.util.Map;
import javax.jcr.Credentials;
import javax.jcr.LoginException;
@@ -117,7 +119,7 @@
private int authHandlerTrackerCount;
- private AuthenticationHandlerInfo[] authHandlerCache;
+ private Map<String, Map<String, AuthenticationHandlerInfo[]>> authHandlerCache;
/** The name of the impersonation parameter */
private String sudoParameterName;
@@ -252,7 +254,7 @@
public void requestAuthentication(HttpServletRequest request,
HttpServletResponse response) {
- AuthenticationHandlerInfo[] handlerInfos = getAuthenticationHandlers();
+ AuthenticationHandlerInfo[] handlerInfos = findApplicableAuthenticationHandlers(request);
boolean done = false;
for (int i = 0; !done && i < handlerInfos.length; i++) {
if ( request.getPathInfo().startsWith(handlerInfos[i].path) ) {
@@ -274,8 +276,8 @@
if ( !done ) {
// no handler could send an authentication request, fail with FORBIDDEN
log.info(
- "requestAuthentication: No handler for request, sending FORBIDDEN ({} handlers available)",
- handlerInfos.length
+ "requestAuthentication: No handler for request, sending FORBIDDEN ({} handlers available)",
+ handlerInfos.length
);
sendFailure(response);
}
@@ -330,32 +332,121 @@
return repo;
}
+ private static Map<String,Map<String, AuthenticationHandlerInfo[]>> EMPTY_PROTOCOL_MAP = new HashMap<String, Map<String,AuthenticationHandlerInfo[]>>();
private static AuthenticationHandlerInfo[] EMPTY_INFO = new AuthenticationHandlerInfo[0];
- private AuthenticationHandlerInfo[] getAuthenticationHandlers() {
+
+ private AuthenticationHandlerInfo[] findApplicableAuthenticationHandlers(HttpServletRequest request) {
+ Map<String, Map<String, AuthenticationHandlerInfo[]>> byProtocolMap = getAuthenticationHandlers();
+
+ Map<String, AuthenticationHandlerInfo[]> byHostMap = byProtocolMap.get(request.getScheme());
+ if(byHostMap == null) {
+ byHostMap = byProtocolMap.get("");
+ }
+
+ String hostname = request.getServerName() +
+ (request.getServerPort() != 80 && request.getServerPort() != 443 ? ":" + request.getServerPort() : "");
+
+ AuthenticationHandlerInfo[] infos = byHostMap.get(hostname);
+ if(infos == null) {
+ infos = byHostMap.get("");
+ }
+
+ if(infos != null) {
+ return infos;
+ }
+
+ return EMPTY_INFO;
+ }
+
+ private Map<String, Map<String, AuthenticationHandlerInfo[]>> getAuthenticationHandlers() {
if (authHandlerCache == null
|| authHandlerTrackerCount < authHandlerTracker.getTrackingCount()) {
final ServiceReference[] services = authHandlerTracker.getServiceReferences();
if ( services == null || services.length == 0 ) {
- this.authHandlerCache = EMPTY_INFO;
+ this.authHandlerCache = EMPTY_PROTOCOL_MAP;
} else {
- final List<AuthenticationHandlerInfo> infos = new ArrayList<AuthenticationHandlerInfo>();
+ final Map<String, Map<String, List<AuthenticationHandlerInfo>>> byProtocolMap = new HashMap<String, Map<String,List<AuthenticationHandlerInfo>>>();
+ int regPathCount = 0;
+
for (int i = 0; i < services.length; i++) {
final String paths[] = OsgiUtil.toStringArray(services[i].getProperty(AuthenticationHandler.PATH_PROPERTY));
+
if ( paths != null && paths.length > 0 ) {
final AuthenticationHandler handler = (AuthenticationHandler) authHandlerTracker.getService(services[i]);
+
for(int m = 0; m < paths.length; m++) {
if ( paths[m] != null && paths[m].length() > 0 ) {
- infos.add(new AuthenticationHandlerInfo(paths[m], handler));
+ String path = paths[m];
+ String host = "";
+ String protocol = "";
+
+ if(path.startsWith("http://") || path.startsWith("https://")) {
+ int idxProtocolEnd = path.indexOf("://");
+ protocol = path.substring(0,idxProtocolEnd);
+ path = path.substring(idxProtocolEnd + 1);
+ }
+
+ if (path.startsWith("//")) {
+ int idxHostEnd = path.indexOf("/",2);
+ idxHostEnd = idxHostEnd == -1 ? path.length() : idxHostEnd;
+
+ if(path.length() > 2) {
+ host = path.substring(2,idxHostEnd);
+ if(idxHostEnd < path.length()) {
+ path = path.substring(idxHostEnd);
+ } else {
+ path="/";
+ }
+ } else {
+ path="/";
+ }
+ }
+
+ AuthenticationHandlerInfo newInfo = new AuthenticationHandlerInfo(path, host, protocol, handler);
+
+ Map<String, List<AuthenticationHandlerInfo>> byHostMap = byProtocolMap.get(protocol);
+ if(byHostMap == null) {
+ byHostMap = new HashMap<String, List<AuthenticationHandlerInfo>>();
+ byProtocolMap.put(protocol, byHostMap);
+ }
+
+ List<AuthenticationHandlerInfo> byPathList = byHostMap.get(host);
+ if(byPathList == null) {
+ byPathList = new ArrayList<AuthenticationHandlerInfo>();
+ byHostMap.put(host, byPathList);
+ }
+
+ byPathList.add(newInfo);
+ regPathCount++;
}
}
}
}
- if ( infos.size() == 0 ) {
- authHandlerCache = EMPTY_INFO;
+ if ( regPathCount == 0 ) {
+ authHandlerCache = EMPTY_PROTOCOL_MAP;
} else {
- final AuthenticationHandlerInfo[] ac = infos.toArray(new AuthenticationHandlerInfo[infos.size()]);
- Arrays.sort(ac, AuthenticationHandlerInfoComparator.SINGLETON);
- authHandlerCache = ac;
+ authHandlerCache = new HashMap<String, Map<String,AuthenticationHandlerInfo[]>>();
+
+ for(Map.Entry<String, Map<String,List<AuthenticationHandlerInfo>>> protocolEntry : byProtocolMap.entrySet()) {
+ Map<String,List<AuthenticationHandlerInfo>> hostMap = protocolEntry.getValue();
+
+ Map<String, AuthenticationHandlerInfo[]> finalHostMap = authHandlerCache.get(protocolEntry.getKey());
+ if(finalHostMap == null) {
+ finalHostMap = new HashMap<String, AuthenticationHandlerInfo[]>();
+ authHandlerCache.put(protocolEntry.getKey(), finalHostMap);
+ }
+
+ for(Map.Entry<String,List<AuthenticationHandlerInfo>> hostEntry : hostMap.entrySet()) {
+ List<AuthenticationHandlerInfo> pathList = hostEntry.getValue();
+
+ Collections.sort(pathList, AuthenticationHandlerInfoComparator.SINGLETON);
+
+ final AuthenticationHandlerInfo[] authInfos =
+ pathList.toArray(new AuthenticationHandlerInfo[pathList.size()]);
+
+ finalHostMap.put(hostEntry.getKey(), authInfos);
+ }
+ }
}
}
authHandlerTrackerCount = authHandlerTracker.getTrackingCount();
@@ -374,7 +465,7 @@
pathInfo = "/";
}
- AuthenticationHandlerInfo[] local = getAuthenticationHandlers();
+ AuthenticationHandlerInfo[] local = findApplicableAuthenticationHandlers(request);
for (int i = 0; i < local.length; i++) {
if ( pathInfo.startsWith(local[i].path) ) {
final AuthenticationInfo authInfo = local[i].handler.authenticate(request,
@@ -384,7 +475,7 @@
}
}
}
-
+
// no handler found for the request ....
log.debug("getCredentials: no handler could extract credentials");
return null;
@@ -601,10 +692,14 @@
protected static final class AuthenticationHandlerInfo {
public final String path;
+ public final String host;
+ public final String protocol;
public final AuthenticationHandler handler;
- public AuthenticationHandlerInfo(final String p, final AuthenticationHandler h) {
+ public AuthenticationHandlerInfo(final String p, final String host, final String protocol, final AuthenticationHandler h) {
this.path = p;
+ this.host = host;
+ this.protocol = protocol;
this.handler = h;
}
}