Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1bc1196baa |
+2
-1
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="samples/attributes/src/main/java"/>
|
||||
<classpathentry kind="src" path="sandbox/other/src/main/java"/>
|
||||
<classpathentry kind="src" path="samples/acegifier/src/test/resources"/>
|
||||
<classpathentry kind="src" path="samples/acegifier/src/main/resources"/>
|
||||
<classpathentry kind="src" path="samples/acegifier/src/main/java"/>
|
||||
@@ -18,6 +17,8 @@
|
||||
<classpathentry kind="src" path="core/src/main/resources"/>
|
||||
<classpathentry kind="src" path="core/src/test/resources"/>
|
||||
<classpathentry kind="src" path="samples/contacts/src/main/java"/>
|
||||
<classpathentry kind="src" path="sandbox/src/main/java"/>
|
||||
<classpathentry kind="src" path="sandbox/src/test/java"/>
|
||||
<classpathentry kind="src" path="adapters/cas/src/main/java"/>
|
||||
<classpathentry kind="src" path="adapters/cas/src/test/java"/>
|
||||
<classpathentry kind="src" path="adapters/catalina/src/main/java"/>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.0.1</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-cas</artifactId>
|
||||
<name>Acegi Security System for Spring - CAS adapter</name>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.0.1</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-catalina</artifactId>
|
||||
<name>Acegi Security System for Spring - Catalina adapter</name>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.0.1</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-jboss</artifactId>
|
||||
<name>Acegi Security System for Spring - JBoss adapter</name>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.0.1</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-jetty</artifactId>
|
||||
<name>Acegi Security System for Spring - Jetty adapter</name>
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.mortbay.http.UserPrincipal;
|
||||
public class JettyAcegiUserToken extends AbstractAdapterAuthenticationToken implements UserPrincipal {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String password;
|
||||
private String username;
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-parent</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.0.1</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<name>Acegi Security System for Spring - Adapters</name>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<dependency>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.0</version>
|
||||
<type>jar</type>
|
||||
<url>http://acegisecurity.org</url>
|
||||
<properties>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-adapters</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.0.1</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-resin</artifactId>
|
||||
<name>Acegi Security System for Spring - Resin adapter</name>
|
||||
|
||||
+1
-9
@@ -3,17 +3,10 @@
|
||||
<parent>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-parent</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.0.1</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-tiger</artifactId>
|
||||
<name>Acegi Security System for Spring - Java 5 (Tiger)</name>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core-tiger</connection>
|
||||
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core-tiger</developerConnection>
|
||||
<url>http://svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/core-tiger/</url>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
@@ -26,7 +19,6 @@
|
||||
<version>1.2.7</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<dependency>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.0</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+16
-42
@@ -1,21 +1,12 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-parent</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.0.1</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security</artifactId>
|
||||
<name>Acegi Security System for Spring</name>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core</connection>
|
||||
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/acegisecurity/trunk/acegisecurity/core</developerConnection>
|
||||
<url>http://svn.sourceforge.net/viewcvs.cgi/acegisecurity/trunk/acegisecurity/core/</url>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
@@ -60,6 +51,11 @@
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>1.0.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
@@ -102,13 +98,19 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.directory.server</groupId>
|
||||
<artifactId>apacheds-core</artifactId>
|
||||
<version>1.0-RC3</version>
|
||||
<version>1.0-RC1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>nlog4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<version>1.0-rc5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -121,35 +123,7 @@
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${basedir}/../</directory>
|
||||
<targetPath>META-INF</targetPath>
|
||||
<includes>
|
||||
<include>notice.txt</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${basedir}/src/main/resources/org/acegisecurity/taglibs</directory>
|
||||
<targetPath>META-INF</targetPath>
|
||||
<includes>
|
||||
<include>*.tld</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>${basedir}/src/main/resources</directory>
|
||||
<targetPath>/</targetPath>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -29,7 +29,7 @@ public class BadCredentialsException extends AuthenticationException {
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>BadCredentialsException</code> with the specified
|
||||
* message.
|
||||
*
|
||||
@@ -44,7 +44,7 @@ public class BadCredentialsException extends AuthenticationException {
|
||||
this.extraInformation = extraInformation;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs a <code>BadCredentialsException</code> with the specified
|
||||
* message and root cause.
|
||||
*
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
package org.acegisecurity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Represents an authority granted to an {@link Authentication} object.
|
||||
*
|
||||
@@ -29,7 +27,7 @@ import java.io.Serializable;
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface GrantedAuthority extends Serializable {
|
||||
public interface GrantedAuthority {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.io.Serializable;
|
||||
public class GrantedAuthorityImpl implements GrantedAuthority, Serializable {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String role;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -35,6 +35,10 @@ public class SecurityConfig implements ConfigAttribute {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof String) {
|
||||
return obj.equals(this.attrib);
|
||||
}
|
||||
|
||||
if (obj instanceof ConfigAttribute) {
|
||||
ConfigAttribute attr = (ConfigAttribute) obj;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.acegisecurity.acl.basic;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Stores some privileges typical of a domain object.
|
||||
*
|
||||
@@ -44,18 +45,14 @@ public class SimpleAclEntry extends AbstractBasicAclEntry {
|
||||
public static final int READ_WRITE_DELETE = READ | WRITE | DELETE;
|
||||
|
||||
// Array required by the abstract superclass via getValidPermissions()
|
||||
private static final int[] VALID_PERMISSIONS = {
|
||||
private static final int[] validPermissions = {
|
||||
NOTHING, ADMINISTRATION, READ, WRITE, CREATE, DELETE, READ_WRITE_CREATE_DELETE, READ_WRITE_CREATE,
|
||||
READ_WRITE, READ_WRITE_DELETE
|
||||
};
|
||||
|
||||
private static final String[] VALID_PERMISSIONS_AS_STRING = {
|
||||
"NOTHING", "ADMINISTRATION", "READ", "WRITE", "CREATE", "DELETE", "READ_WRITE_CREATE_DELETE", "READ_WRITE_CREATE",
|
||||
"READ_WRITE", "READ_WRITE_DELETE" };
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Allows {@link BasicAclDao} implementations to construct this object
|
||||
* using <code>newInstance()</code>.
|
||||
*
|
||||
@@ -74,11 +71,8 @@ public class SimpleAclEntry extends AbstractBasicAclEntry {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* @return a copy of the permissions array, changes to the values won't affect this class.
|
||||
*/
|
||||
public int[] getValidPermissions() {
|
||||
return (int[]) VALID_PERMISSIONS.clone();
|
||||
return validPermissions;
|
||||
}
|
||||
|
||||
public String printPermissionsBlock(int i) {
|
||||
@@ -116,35 +110,4 @@ public class SimpleAclEntry extends AbstractBasicAclEntry {
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a permission {@link String} literal and return associated value.
|
||||
*
|
||||
* @param permission one of the field names that represent a permission: <code>ADMINISTRATION</code>,
|
||||
* <code>READ</code>, <code>WRITE</code>,...
|
||||
* @return the value associated to that permission
|
||||
* @throws IllegalArgumentException if argument is not a valid permission
|
||||
*/
|
||||
public static int parsePermission(String permission) {
|
||||
for (int i = 0; i < VALID_PERMISSIONS_AS_STRING.length; i++) {
|
||||
if (VALID_PERMISSIONS_AS_STRING[i].equalsIgnoreCase(permission)) {
|
||||
return VALID_PERMISSIONS[i];
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Permission provided does not exist: " + permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a list of permission {@link String} literals and return associated values.
|
||||
*
|
||||
* @param permissions array with permissions as {@link String}
|
||||
* @see #parsePermission(String) for valid values
|
||||
*/
|
||||
public static int[] parsePermissions(String[] permissions) {
|
||||
int[] requirepermissionAsIntArray = new int[permissions.length];
|
||||
for (int i = 0; i < requirepermissionAsIntArray.length; i++) {
|
||||
requirepermissionAsIntArray[i] = parsePermission(permissions[i]);
|
||||
}
|
||||
return requirepermissionAsIntArray;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import java.security.Principal;
|
||||
public class PrincipalAcegiUserToken extends AbstractAdapterAuthenticationToken implements Principal {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Object principal;
|
||||
private String password;
|
||||
private String username;
|
||||
|
||||
+1
-11
@@ -211,16 +211,6 @@ public class BasicAclEntryAfterInvocationCollectionFilteringProvider implements
|
||||
this.requirePermission = requirePermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow setting permissions with String literals instead of integers as {@link #setRequirePermission(int[])}
|
||||
*
|
||||
* @param requirePermission permission literals
|
||||
* @see SimpleAclEntry#parsePermissions(String[]) for valid values
|
||||
*/
|
||||
public void setRequirePermissionFromString(String[] requirePermission) {
|
||||
setRequirePermission(SimpleAclEntry.parsePermissions(requirePermission));
|
||||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) {
|
||||
return true;
|
||||
@@ -342,7 +332,7 @@ class CollectionFilterer implements Filterer {
|
||||
* @see org.acegisecurity.afterinvocation.Filterer#remove(java.lang.Object)
|
||||
*/
|
||||
public void remove(Object object) {
|
||||
removeList.add(object);
|
||||
collectionIter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-10
@@ -39,6 +39,7 @@ import org.springframework.util.Assert;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Given a domain object instance returned from a secure object invocation, ensures the principal has
|
||||
* appropriate permission as defined by the {@link AclManager}.</p>
|
||||
@@ -186,16 +187,6 @@ public class BasicAclEntryAfterInvocationProvider implements AfterInvocationProv
|
||||
this.requirePermission = requirePermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow setting permissions with String literals instead of integers as {@link #setRequirePermission(int[])}
|
||||
*
|
||||
* @param requirePermission Permission literals
|
||||
* @see SimpleAclEntry#parsePermissions(String[]) for valid values
|
||||
*/
|
||||
public void setRequirePermissionFromString(String[] requirePermission) {
|
||||
setRequirePermission(SimpleAclEntry.parsePermissions(requirePermission));
|
||||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) {
|
||||
return true;
|
||||
|
||||
+2
-4
@@ -100,10 +100,6 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi
|
||||
*/
|
||||
private boolean forceEagerSessionCreation = false;
|
||||
|
||||
public HttpSessionContextIntegrationFilter() throws ServletException {
|
||||
this.contextObject = generateNewContext();
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
@@ -117,6 +113,8 @@ public class HttpSessionContextIntegrationFilter implements InitializingBean, Fi
|
||||
throw new IllegalArgumentException(
|
||||
"If using forceEagerSessionCreation, you must set allowSessionCreation to also be true");
|
||||
}
|
||||
|
||||
this.contextObject = generateNewContext();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,7 +41,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.context.MessageSource;
|
||||
@@ -277,7 +276,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
|
||||
} catch (AccessDeniedException accessDeniedException) {
|
||||
AuthorizationFailureEvent event = new AuthorizationFailureEvent(object, attr, authenticated,
|
||||
accessDeniedException);
|
||||
publishEvent(event);
|
||||
this.eventPublisher.publishEvent(event);
|
||||
|
||||
throw accessDeniedException;
|
||||
}
|
||||
@@ -287,7 +286,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
|
||||
}
|
||||
|
||||
AuthorizedEvent event = new AuthorizedEvent(object, attr, authenticated);
|
||||
publishEvent(event);
|
||||
this.eventPublisher.publishEvent(event);
|
||||
|
||||
// Attempt to run as a different user
|
||||
Authentication runAs = this.runAsManager.buildRunAs(authenticated, object, attr);
|
||||
@@ -312,7 +311,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
|
||||
logger.debug("Public object - authentication not attempted");
|
||||
}
|
||||
|
||||
publishEvent(new PublicInvocationEvent(object));
|
||||
this.eventPublisher.publishEvent(new PublicInvocationEvent(object));
|
||||
|
||||
return null; // no further work post-invocation
|
||||
}
|
||||
@@ -331,7 +330,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
|
||||
|
||||
AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(secureObject,
|
||||
configAttribs, exception);
|
||||
publishEvent(event);
|
||||
this.eventPublisher.publishEvent(event);
|
||||
|
||||
throw exception;
|
||||
}
|
||||
@@ -432,10 +431,4 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean, A
|
||||
public void setValidateConfigAttributes(boolean validateConfigAttributes) {
|
||||
this.validateConfigAttributes = validateConfigAttributes;
|
||||
}
|
||||
|
||||
private void publishEvent(ApplicationEvent event) {
|
||||
if (this.eventPublisher != null) {
|
||||
this.eventPublisher.publishEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ package org.acegisecurity.intercept.method;
|
||||
|
||||
import org.acegisecurity.ConfigAttribute;
|
||||
import org.acegisecurity.ConfigAttributeDefinition;
|
||||
import org.acegisecurity.SecurityConfig;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -233,25 +232,4 @@ public class MethodDefinitionMap extends AbstractMethodDefinitionSource {
|
||||
definition.addConfigAttribute((ConfigAttribute) attribs.next());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Easier configuration of the instance, using {@link MethodDefinitionSourceMapping}.
|
||||
*
|
||||
* @param mappings {@link List} of {@link MethodDefinitionSourceMapping} objects.
|
||||
*/
|
||||
public void setMappings(List mappings) {
|
||||
Iterator it = mappings.iterator();
|
||||
while (it.hasNext()) {
|
||||
MethodDefinitionSourceMapping mapping = (MethodDefinitionSourceMapping) it.next();
|
||||
ConfigAttributeDefinition configDefinition = new ConfigAttributeDefinition();
|
||||
|
||||
Iterator configAttributesIt = mapping.getConfigAttributes().iterator();
|
||||
while (configAttributesIt.hasNext()) {
|
||||
String s = (String) configAttributesIt.next();
|
||||
configDefinition.addConfigAttribute(new SecurityConfig(s));
|
||||
}
|
||||
|
||||
addSecureMethod(mapping.getMethodName(), configDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-13
@@ -15,17 +15,17 @@
|
||||
|
||||
package org.acegisecurity.intercept.method;
|
||||
|
||||
import org.acegisecurity.ConfigAttributeDefinition;
|
||||
import org.acegisecurity.ConfigAttributeEditor;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.propertyeditors.PropertiesEditor;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
|
||||
@@ -56,24 +56,20 @@ public class MethodDefinitionSourceEditor extends PropertyEditorSupport {
|
||||
Properties props = (Properties) propertiesEditor.getValue();
|
||||
|
||||
// Now we have properties, process each one individually
|
||||
List mappings = new ArrayList();
|
||||
ConfigAttributeEditor configAttribEd = new ConfigAttributeEditor();
|
||||
|
||||
for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
|
||||
String name = (String) iter.next();
|
||||
String value = props.getProperty(name);
|
||||
|
||||
MethodDefinitionSourceMapping mapping = new MethodDefinitionSourceMapping();
|
||||
mapping.setMethodName(name);
|
||||
// Convert value to series of security configuration attributes
|
||||
configAttribEd.setAsText(value);
|
||||
|
||||
String[] tokens = StringUtils.commaDelimitedListToStringArray(value);
|
||||
ConfigAttributeDefinition attr = (ConfigAttributeDefinition) configAttribEd.getValue();
|
||||
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
mapping.addConfigAttribute(tokens[i].trim());
|
||||
}
|
||||
|
||||
mappings.add(mapping);
|
||||
// Register name and attribute
|
||||
source.addSecureMethod(name, attr);
|
||||
}
|
||||
source.setMappings(mappings);
|
||||
}
|
||||
|
||||
setValue(source);
|
||||
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
/* Copyright 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed 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.acegisecurity.intercept.method;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.acegisecurity.ConfigAttribute;
|
||||
|
||||
/**
|
||||
* Configuration entry for {@link MethodDefinitionSource}, that holds
|
||||
* the method to be protected and the {@link ConfigAttribute}s as {@link String}
|
||||
* that apply to that url.
|
||||
*
|
||||
* @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
|
||||
* @version $Id$
|
||||
* @since 1.1
|
||||
*/
|
||||
public class MethodDefinitionSourceMapping {
|
||||
|
||||
private String methodName;
|
||||
|
||||
private List configAttributes = new ArrayList();
|
||||
|
||||
/**
|
||||
* Name of the method to be secured, including package and class name.
|
||||
* eg. <code>org.mydomain.MyClass.myMethod</code>
|
||||
*
|
||||
* @param methodName
|
||||
*/
|
||||
public void setMethodName(String methodName) {
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the method to be secured.
|
||||
*
|
||||
* @return the name of the method
|
||||
*/
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param roles {@link List}<{@link String}>
|
||||
*/
|
||||
public void setConfigAttributes(List roles) {
|
||||
this.configAttributes = roles;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return {@link List}<{@link String}>
|
||||
*/
|
||||
public List getConfigAttributes() {
|
||||
return configAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link ConfigAttribute} as {@link String}
|
||||
*
|
||||
* @param configAttribute
|
||||
*/
|
||||
public void addConfigAttribute(String configAttribute) {
|
||||
configAttributes.add(configAttribute);
|
||||
}
|
||||
|
||||
}
|
||||
-153
@@ -1,153 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed 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.acegisecurity.intercept.web;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.acegisecurity.ConfigAttributeDefinition;
|
||||
import org.acegisecurity.SecurityConfig;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Decorator of {@link FilterInvocationDefinition} for easier configuration,
|
||||
* using {@link FilterInvocationDefinitionSourceMapping}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Delegates all calls to decorated object set in constructor
|
||||
* {@link #FilterInvocationDefinitionDecorator(FilterInvocationDefinition)} or
|
||||
* by calling {@link #setDecorated(FilterInvocationDefinition)}
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
|
||||
* @version $Id$
|
||||
* @since 1.1
|
||||
*/
|
||||
public class FilterInvocationDefinitionDecorator implements FilterInvocationDefinition {
|
||||
|
||||
private FilterInvocationDefinition decorated;
|
||||
|
||||
private List mappings;
|
||||
|
||||
public FilterInvocationDefinitionDecorator() {
|
||||
}
|
||||
|
||||
public FilterInvocationDefinitionDecorator(FilterInvocationDefinition decorated) {
|
||||
this.setDecorated(decorated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the decorated object
|
||||
*
|
||||
* @param decorated
|
||||
* the decorated {@link FilterInvocationDefinition}
|
||||
*/
|
||||
public void setDecorated(FilterInvocationDefinition decorated) {
|
||||
this.decorated = decorated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get decorated object
|
||||
*
|
||||
* @return the decorated {@link FilterInvocationDefinition}
|
||||
*/
|
||||
public FilterInvocationDefinition getDecorated() {
|
||||
return decorated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the decorated {@link FilterInvocationDefinitionMap} easier,
|
||||
* using {@link FilterInvocationDefinitionSourceMapping}.
|
||||
*
|
||||
* @param mappings
|
||||
* {@link List} of
|
||||
* {@link FilterInvocationDefinitionSourceMapping} objects.
|
||||
*/
|
||||
public void setMappings(List mappings) {
|
||||
|
||||
if (decorated == null) {
|
||||
throw new IllegalStateException("decorated object has not been set");
|
||||
}
|
||||
|
||||
this.mappings = mappings;
|
||||
Iterator it = mappings.iterator();
|
||||
while (it.hasNext()) {
|
||||
FilterInvocationDefinitionSourceMapping mapping = (FilterInvocationDefinitionSourceMapping) it.next();
|
||||
ConfigAttributeDefinition configDefinition = new ConfigAttributeDefinition();
|
||||
|
||||
Iterator configAttributesIt = mapping.getConfigAttributes().iterator();
|
||||
while (configAttributesIt.hasNext()) {
|
||||
String s = (String) configAttributesIt.next();
|
||||
configDefinition.addConfigAttribute(new SecurityConfig(s));
|
||||
}
|
||||
|
||||
decorated.addSecureUrl(mapping.getUrl(), configDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mappings used for configuration.
|
||||
*
|
||||
* @return {@link List} of {@link FilterInvocationDefinitionSourceMapping}
|
||||
* objects.
|
||||
*/
|
||||
public List getMappings() {
|
||||
return mappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate to decorated object
|
||||
*/
|
||||
public void addSecureUrl(String expression, ConfigAttributeDefinition attr) {
|
||||
getDecorated().addSecureUrl(expression, attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate to decorated object
|
||||
*/
|
||||
public boolean isConvertUrlToLowercaseBeforeComparison() {
|
||||
return getDecorated().isConvertUrlToLowercaseBeforeComparison();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate to decorated object
|
||||
*/
|
||||
public void setConvertUrlToLowercaseBeforeComparison(boolean convertUrlToLowercaseBeforeComparison) {
|
||||
getDecorated().setConvertUrlToLowercaseBeforeComparison(convertUrlToLowercaseBeforeComparison);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate to decorated object
|
||||
*/
|
||||
public ConfigAttributeDefinition getAttributes(Object object) throws IllegalArgumentException {
|
||||
return getDecorated().getAttributes(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate to decorated object
|
||||
*/
|
||||
public Iterator getConfigAttributeDefinitions() {
|
||||
return getDecorated().getConfigAttributeDefinitions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate to decorated object
|
||||
*/
|
||||
public boolean supports(Class clazz) {
|
||||
return getDecorated().supports(clazz);
|
||||
}
|
||||
}
|
||||
+13
-19
@@ -15,6 +15,9 @@
|
||||
|
||||
package org.acegisecurity.intercept.web;
|
||||
|
||||
import org.acegisecurity.ConfigAttributeDefinition;
|
||||
import org.acegisecurity.ConfigAttributeEditor;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -24,8 +27,6 @@ import java.beans.PropertyEditorSupport;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
@@ -49,15 +50,14 @@ public class FilterInvocationDefinitionSourceEditor extends PropertyEditorSuppor
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void setAsText(String s) throws IllegalArgumentException {
|
||||
FilterInvocationDefinitionDecorator source = new FilterInvocationDefinitionDecorator();
|
||||
source.setDecorated(new RegExpBasedFilterInvocationDefinitionMap());
|
||||
FilterInvocationDefinitionMap source = new RegExpBasedFilterInvocationDefinitionMap();
|
||||
|
||||
if ((s == null) || "".equals(s)) {
|
||||
// Leave target object empty
|
||||
} else {
|
||||
// Check if we need to override the default definition map
|
||||
if (s.lastIndexOf(DIRECTIVE_PATTERN_TYPE_APACHE_ANT) != -1) {
|
||||
source.setDecorated(new PathBasedFilterInvocationDefinitionMap());
|
||||
source = new PathBasedFilterInvocationDefinitionMap();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(("Detected " + DIRECTIVE_PATTERN_TYPE_APACHE_ANT
|
||||
@@ -77,8 +77,6 @@ public class FilterInvocationDefinitionSourceEditor extends PropertyEditorSuppor
|
||||
BufferedReader br = new BufferedReader(new StringReader(s));
|
||||
int counter = 0;
|
||||
String line;
|
||||
|
||||
List mappings = new ArrayList();
|
||||
|
||||
while (true) {
|
||||
counter++;
|
||||
@@ -140,7 +138,7 @@ public class FilterInvocationDefinitionSourceEditor extends PropertyEditorSuppor
|
||||
|
||||
// Attempt to detect malformed lines (as per SEC-204)
|
||||
if (source.isConvertUrlToLowercaseBeforeComparison()
|
||||
&& source.getDecorated() instanceof PathBasedFilterInvocationDefinitionMap) {
|
||||
&& source instanceof PathBasedFilterInvocationDefinitionMap) {
|
||||
// Should all be lowercase; check each character
|
||||
// We only do this for Ant (regexp have control chars)
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
@@ -155,21 +153,17 @@ public class FilterInvocationDefinitionSourceEditor extends PropertyEditorSuppor
|
||||
}
|
||||
}
|
||||
|
||||
FilterInvocationDefinitionSourceMapping mapping = new FilterInvocationDefinitionSourceMapping();
|
||||
mapping.setUrl(name);
|
||||
// Convert value to series of security configuration attributes
|
||||
ConfigAttributeEditor configAttribEd = new ConfigAttributeEditor();
|
||||
configAttribEd.setAsText(value);
|
||||
|
||||
String[] tokens = org.springframework.util.StringUtils
|
||||
.commaDelimitedListToStringArray(value);
|
||||
ConfigAttributeDefinition attr = (ConfigAttributeDefinition) configAttribEd.getValue();
|
||||
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
mapping.addConfigAttribute(tokens[i].trim());
|
||||
}
|
||||
|
||||
mappings.add(mapping);
|
||||
// Register the regular expression and its attribute
|
||||
source.addSecureUrl(name, attr);
|
||||
}
|
||||
source.setMappings(mappings);
|
||||
}
|
||||
|
||||
setValue(source.getDecorated());
|
||||
setValue(source);
|
||||
}
|
||||
}
|
||||
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
/* Copyright 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed 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.acegisecurity.intercept.web;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.acegisecurity.ConfigAttribute;
|
||||
|
||||
/**
|
||||
* Configuration entry for {@link FilterInvocationDefinitionSource}, that holds
|
||||
* the url to be protected and the {@link ConfigAttribute}s as {@link String}
|
||||
* that apply to that url.
|
||||
*
|
||||
* @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
|
||||
* @version $Id$
|
||||
* @since 1.1
|
||||
*/
|
||||
public class FilterInvocationDefinitionSourceMapping {
|
||||
|
||||
private String url;
|
||||
|
||||
private List configAttributes = new ArrayList();
|
||||
|
||||
/**
|
||||
* Url to be secured.
|
||||
*
|
||||
* @param url
|
||||
*/
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Url to be secured.
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param roles
|
||||
* {@link List}<{@link String}>
|
||||
*/
|
||||
public void setConfigAttributes(List roles) {
|
||||
this.configAttributes = roles;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return {@link List}<{@link String}>
|
||||
*/
|
||||
public List getConfigAttributes() {
|
||||
return configAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link ConfigAttribute} as {@link String}
|
||||
*
|
||||
* @param configAttribute
|
||||
*/
|
||||
public void addConfigAttribute(String configAttribute) {
|
||||
configAttributes.add(configAttribute);
|
||||
}
|
||||
|
||||
}
|
||||
+4
-4
@@ -44,7 +44,7 @@ import java.util.Vector;
|
||||
* @version $Id$
|
||||
*/
|
||||
public class PathBasedFilterInvocationDefinitionMap extends AbstractFilterInvocationDefinitionSource
|
||||
implements FilterInvocationDefinition {
|
||||
implements FilterInvocationDefinitionMap {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(PathBasedFilterInvocationDefinitionMap.class);
|
||||
@@ -86,14 +86,14 @@ public class PathBasedFilterInvocationDefinitionMap extends AbstractFilterInvoca
|
||||
}
|
||||
|
||||
public ConfigAttributeDefinition lookupAttributes(String url) {
|
||||
// Strip anything after a question mark symbol, as per SEC-161. See also SEC-321
|
||||
int firstQuestionMarkIndex = url.indexOf("?");
|
||||
// Strip anything after a question mark symbol, as per SEC-161.
|
||||
int firstQuestionMarkIndex = url.lastIndexOf("?");
|
||||
|
||||
if (firstQuestionMarkIndex != -1) {
|
||||
url = url.substring(0, firstQuestionMarkIndex);
|
||||
}
|
||||
|
||||
if (isConvertUrlToLowercaseBeforeComparison()) {
|
||||
if (convertUrlToLowercaseBeforeComparison) {
|
||||
url = url.toLowerCase();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
+2
-2
@@ -45,7 +45,7 @@ import java.util.Vector;
|
||||
* <p>If no registered regular expressions match the HTTP URL, <code>null</code> is returned.</p>
|
||||
*/
|
||||
public class RegExpBasedFilterInvocationDefinitionMap extends AbstractFilterInvocationDefinitionSource
|
||||
implements FilterInvocationDefinition {
|
||||
implements FilterInvocationDefinitionMap {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(RegExpBasedFilterInvocationDefinitionMap.class);
|
||||
@@ -100,7 +100,7 @@ public class RegExpBasedFilterInvocationDefinitionMap extends AbstractFilterInvo
|
||||
|
||||
Iterator iter = requestMap.iterator();
|
||||
|
||||
if (isConvertUrlToLowercaseBeforeComparison()) {
|
||||
if (convertUrlToLowercaseBeforeComparison) {
|
||||
url = url.toLowerCase();
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
@@ -34,8 +34,6 @@ import java.util.StringTokenizer;
|
||||
import javax.naming.CommunicationException;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.OperationNotSupportedException;
|
||||
import javax.naming.ldap.InitialLdapContext;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
|
||||
@@ -106,32 +104,13 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory
|
||||
*/
|
||||
private boolean useConnectionPool = true;
|
||||
|
||||
/** Set to true for ldap v3 compatible servers */
|
||||
private boolean useLdapContext = false;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
* Create and initialize an instance to the LDAP url provided
|
||||
*
|
||||
* @param providerUrl a String of the form <code>ldap://localhost:389/base_dn<code>
|
||||
*/
|
||||
public DefaultInitialDirContextFactory(String providerUrl) {
|
||||
this.setProviderUrl(providerUrl);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Set the LDAP url
|
||||
*
|
||||
* @param providerUrl a String of the form <code>ldap://localhost:389/base_dn<code>
|
||||
*/
|
||||
private void setProviderUrl(String providerUrl) {
|
||||
Assert.hasLength(providerUrl, "An LDAP connection URL must be supplied.");
|
||||
|
||||
this.providerUrl = providerUrl;
|
||||
|
||||
Assert.hasLength(providerUrl, "An LDAP connection URL must be supplied.");
|
||||
|
||||
StringTokenizer st = new StringTokenizer(providerUrl);
|
||||
|
||||
// Work out rootDn from the first URL and check that the other URLs (if any) match
|
||||
@@ -152,14 +131,7 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory
|
||||
//Assert.isTrue(uri.getScheme().equals("ldap"), "Ldap URL must start with 'ldap://'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the LDAP url
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
private String getProviderUrl() {
|
||||
return providerUrl;
|
||||
}
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
private InitialDirContext connect(Hashtable env) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -173,22 +145,17 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory
|
||||
}
|
||||
|
||||
try {
|
||||
return useLdapContext ? new InitialLdapContext(env, null) : new InitialDirContext(env);
|
||||
} catch (NamingException ne) {
|
||||
if ((ne instanceof javax.naming.AuthenticationException) ||
|
||||
(ne instanceof OperationNotSupportedException)) {
|
||||
throw new BadCredentialsException(messages.getMessage("DefaultIntitalDirContextFactory.badCredentials",
|
||||
"Bad credentials"), ne);
|
||||
}
|
||||
|
||||
if (ne instanceof CommunicationException) {
|
||||
throw new LdapDataAccessException(messages.getMessage(
|
||||
"DefaultIntitalDirContextFactory.communicationFailure", "Unable to connect to LDAP server"), ne);
|
||||
}
|
||||
|
||||
return new InitialDirContext(env);
|
||||
} catch (CommunicationException ce) {
|
||||
throw new LdapDataAccessException(messages.getMessage(
|
||||
"DefaultIntitalDirContextFactory.communicationFailure", "Unable to connect to LDAP server"), ce);
|
||||
} catch (javax.naming.AuthenticationException ae) {
|
||||
throw new BadCredentialsException(messages.getMessage("DefaultIntitalDirContextFactory.badCredentials",
|
||||
"Bad credentials"), ae);
|
||||
} catch (NamingException nx) {
|
||||
throw new LdapDataAccessException(messages.getMessage(
|
||||
"DefaultIntitalDirContextFactory.unexpectedException",
|
||||
"Failed to obtain InitialDirContext due to unexpected exception"), ne);
|
||||
"Failed to obtain InitialDirContext due to unexpected exception"), nx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +169,7 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory
|
||||
|
||||
env.put(Context.SECURITY_AUTHENTICATION, authenticationType);
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
|
||||
env.put(Context.PROVIDER_URL, getProviderUrl());
|
||||
env.put(Context.PROVIDER_URL, providerUrl);
|
||||
|
||||
if (useConnectionPool) {
|
||||
env.put(CONNECTION_POOL_KEY, "true");
|
||||
@@ -313,8 +280,4 @@ public class DefaultInitialDirContextFactory implements InitialDirContextFactory
|
||||
public void setUseConnectionPool(boolean useConnectionPool) {
|
||||
this.useConnectionPool = useConnectionPool;
|
||||
}
|
||||
|
||||
public void setUseLdapContext(boolean useLdapContext) {
|
||||
this.useLdapContext = useLdapContext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import java.util.Set;
|
||||
import javax.naming.NameNotFoundException;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
@@ -133,21 +132,17 @@ public class LdapTemplate {
|
||||
|
||||
public boolean nameExists(final String dn) {
|
||||
Boolean exists = (Boolean) execute(new LdapCallback() {
|
||||
public Object doInDirContext(DirContext ctx)
|
||||
throws NamingException {
|
||||
try {
|
||||
Object obj = ctx.lookup(LdapUtils.getRelativeName(dn, ctx));
|
||||
if (obj instanceof Context) {
|
||||
LdapUtils.closeContext((Context) obj);
|
||||
public Object doInDirContext(DirContext ctx)
|
||||
throws NamingException {
|
||||
try {
|
||||
ctx.lookup(LdapUtils.getRelativeName(dn, ctx));
|
||||
} catch (NameNotFoundException nnfe) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
} catch (NameNotFoundException nnfe) {
|
||||
return Boolean.FALSE;
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return exists.booleanValue();
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.context.MessageSource;
|
||||
@@ -96,7 +95,6 @@ public class ProviderManager extends AbstractAuthenticationManager implements In
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ProviderManager.class);
|
||||
private static final Properties DEFAULT_EXCEPTION_MAPPINGS = new Properties();
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
@@ -104,39 +102,36 @@ public class ProviderManager extends AbstractAuthenticationManager implements In
|
||||
private ConcurrentSessionController sessionController = new NullConcurrentSessionController();
|
||||
private List providers;
|
||||
protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
|
||||
private Properties exceptionMappings = new Properties();
|
||||
|
||||
static {
|
||||
DEFAULT_EXCEPTION_MAPPINGS.put(AccountExpiredException.class.getName(),
|
||||
AuthenticationFailureExpiredEvent.class.getName());
|
||||
DEFAULT_EXCEPTION_MAPPINGS.put(AuthenticationServiceException.class.getName(),
|
||||
AuthenticationFailureServiceExceptionEvent.class.getName());
|
||||
DEFAULT_EXCEPTION_MAPPINGS.put(LockedException.class.getName(), AuthenticationFailureLockedEvent.class.getName());
|
||||
DEFAULT_EXCEPTION_MAPPINGS.put(CredentialsExpiredException.class.getName(),
|
||||
AuthenticationFailureCredentialsExpiredEvent.class.getName());
|
||||
DEFAULT_EXCEPTION_MAPPINGS.put(DisabledException.class.getName(), AuthenticationFailureDisabledEvent.class.getName());
|
||||
DEFAULT_EXCEPTION_MAPPINGS.put(BadCredentialsException.class.getName(),
|
||||
AuthenticationFailureBadCredentialsEvent.class.getName());
|
||||
DEFAULT_EXCEPTION_MAPPINGS.put(UsernameNotFoundException.class.getName(),
|
||||
AuthenticationFailureBadCredentialsEvent.class.getName());
|
||||
DEFAULT_EXCEPTION_MAPPINGS.put(ConcurrentLoginException.class.getName(),
|
||||
AuthenticationFailureConcurrentLoginEvent.class.getName());
|
||||
DEFAULT_EXCEPTION_MAPPINGS.put(ProviderNotFoundException.class.getName(),
|
||||
AuthenticationFailureProviderNotFoundEvent.class.getName());
|
||||
DEFAULT_EXCEPTION_MAPPINGS.put(ProxyUntrustedException.class.getName(),
|
||||
AuthenticationFailureProxyUntrustedEvent.class.getName());
|
||||
}
|
||||
|
||||
public ProviderManager() {
|
||||
exceptionMappings.putAll(DEFAULT_EXCEPTION_MAPPINGS);
|
||||
}
|
||||
private Properties exceptionMappings;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
checkIfValidList(this.providers);
|
||||
Assert.notNull(this.messages, "A message source must be set");
|
||||
doAddExtraDefaultExceptionMappings(DEFAULT_EXCEPTION_MAPPINGS);
|
||||
|
||||
if (exceptionMappings == null) {
|
||||
exceptionMappings = new Properties();
|
||||
exceptionMappings.put(AccountExpiredException.class.getName(),
|
||||
AuthenticationFailureExpiredEvent.class.getName());
|
||||
exceptionMappings.put(AuthenticationServiceException.class.getName(),
|
||||
AuthenticationFailureServiceExceptionEvent.class.getName());
|
||||
exceptionMappings.put(LockedException.class.getName(), AuthenticationFailureLockedEvent.class.getName());
|
||||
exceptionMappings.put(CredentialsExpiredException.class.getName(),
|
||||
AuthenticationFailureCredentialsExpiredEvent.class.getName());
|
||||
exceptionMappings.put(DisabledException.class.getName(), AuthenticationFailureDisabledEvent.class.getName());
|
||||
exceptionMappings.put(BadCredentialsException.class.getName(),
|
||||
AuthenticationFailureBadCredentialsEvent.class.getName());
|
||||
exceptionMappings.put(UsernameNotFoundException.class.getName(),
|
||||
AuthenticationFailureBadCredentialsEvent.class.getName());
|
||||
exceptionMappings.put(ConcurrentLoginException.class.getName(),
|
||||
AuthenticationFailureConcurrentLoginEvent.class.getName());
|
||||
exceptionMappings.put(ProviderNotFoundException.class.getName(),
|
||||
AuthenticationFailureProviderNotFoundEvent.class.getName());
|
||||
exceptionMappings.put(ProxyUntrustedException.class.getName(),
|
||||
AuthenticationFailureProxyUntrustedEvent.class.getName());
|
||||
doAddExtraDefaultExceptionMappings(exceptionMappings);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIfValidList(List listToCheck) {
|
||||
@@ -194,7 +189,7 @@ public class ProviderManager extends AbstractAuthenticationManager implements In
|
||||
|
||||
if (result != null) {
|
||||
sessionController.registerSuccessfulAuthentication(result);
|
||||
publishEvent(new AuthenticationSuccessEvent(result));
|
||||
applicationEventPublisher.publishEvent(new AuthenticationSuccessEvent(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -227,7 +222,7 @@ public class ProviderManager extends AbstractAuthenticationManager implements In
|
||||
}
|
||||
|
||||
if (event != null) {
|
||||
publishEvent(event);
|
||||
applicationEventPublisher.publishEvent(event);
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No event was found for the exception " + lastException.getClass().getName());
|
||||
@@ -278,7 +273,6 @@ public class ProviderManager extends AbstractAuthenticationManager implements In
|
||||
try {
|
||||
currentObject = iter.next();
|
||||
|
||||
//TODO bad idea, should use assignable from or instance of
|
||||
AuthenticationProvider attemptToCast = (AuthenticationProvider) currentObject;
|
||||
} catch (ClassCastException cce) {
|
||||
throw new IllegalArgumentException("AuthenticationProvider " + currentObject.getClass().getName()
|
||||
@@ -298,10 +292,4 @@ public class ProviderManager extends AbstractAuthenticationManager implements In
|
||||
public void setSessionController(ConcurrentSessionController sessionController) {
|
||||
this.sessionController = sessionController;
|
||||
}
|
||||
|
||||
private void publishEvent( ApplicationEvent event ) {
|
||||
if ( applicationEventPublisher != null ) {
|
||||
applicationEventPublisher.publishEvent( event );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.acegisecurity.GrantedAuthority;
|
||||
public class TestingAuthenticationToken extends AbstractAuthenticationToken {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Object credentials;
|
||||
private Object principal;
|
||||
|
||||
|
||||
-1
@@ -30,7 +30,6 @@ import org.acegisecurity.GrantedAuthority;
|
||||
public class UsernamePasswordAuthenticationToken extends AbstractAuthenticationToken {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Object credentials;
|
||||
private Object principal;
|
||||
|
||||
|
||||
-1
@@ -31,7 +31,6 @@ import java.io.Serializable;
|
||||
public class AnonymousAuthenticationToken extends AbstractAuthenticationToken implements Serializable {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Object principal;
|
||||
private int keyHash;
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ import java.util.List;
|
||||
public class CasAuthenticationToken extends AbstractAuthenticationToken implements Serializable {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final List proxyList;
|
||||
private final Object credentials;
|
||||
private final Object principal;
|
||||
|
||||
+2
-2
@@ -55,7 +55,7 @@ public class DaoCasAuthoritiesPopulator implements CasAuthoritiesPopulator, Init
|
||||
return userDetailsService;
|
||||
}
|
||||
|
||||
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
||||
this.userDetailsService = userDetailsService;
|
||||
public void setUserDetailsService(UserDetailsService authenticationDao) {
|
||||
this.userDetailsService = authenticationDao;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-9
@@ -145,15 +145,10 @@ public abstract class AbstractUserDetailsAuthenticationProvider implements Authe
|
||||
try {
|
||||
additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
|
||||
} catch (AuthenticationException exception) {
|
||||
if(cacheWasUsed) {
|
||||
// There was a problem, so try again after checking
|
||||
// we're using latest data (ie not from the cache)
|
||||
cacheWasUsed = false;
|
||||
user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
|
||||
additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
|
||||
} else {
|
||||
throw exception;
|
||||
}
|
||||
// There was a problem, so try again after checking we're using latest data
|
||||
cacheWasUsed = false;
|
||||
user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);
|
||||
additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
|
||||
}
|
||||
|
||||
if (!user.isCredentialsNonExpired()) {
|
||||
|
||||
@@ -63,7 +63,7 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
||||
}
|
||||
|
||||
protected void doAfterPropertiesSet() throws Exception {
|
||||
Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
|
||||
Assert.notNull(this.userDetailsService, "An Authentication DAO must be set");
|
||||
}
|
||||
|
||||
public PasswordEncoder getPasswordEncoder() {
|
||||
@@ -90,7 +90,7 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
||||
|
||||
if (loadedUser == null) {
|
||||
throw new AuthenticationServiceException(
|
||||
"UserDetailsService returned null, which is an interface contract violation");
|
||||
"AuthenticationDao returned null, which is an interface contract violation");
|
||||
}
|
||||
|
||||
return loadedUser;
|
||||
@@ -117,7 +117,7 @@ public class DaoAuthenticationProvider extends AbstractUserDetailsAuthentication
|
||||
this.saltSource = saltSource;
|
||||
}
|
||||
|
||||
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
||||
this.userDetailsService = userDetailsService;
|
||||
public void setUserDetailsService(UserDetailsService authenticationDao) {
|
||||
this.userDetailsService = authenticationDao;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public interface PasswordEncoder {
|
||||
* @param salt optionally used by the implementation to "salt" the raw password before encoding. A
|
||||
* <code>null</code> value is legal.
|
||||
*
|
||||
* @return encoded password
|
||||
* @return DOCUMENT ME!
|
||||
*
|
||||
* @throws DataAccessException DOCUMENT ME!
|
||||
*/
|
||||
@@ -67,7 +67,7 @@ public interface PasswordEncoder {
|
||||
* @param salt optionally used by the implementation to "salt" the raw password before encoding. A
|
||||
* <code>null</code> value is legal.
|
||||
*
|
||||
* @return true if the password is valid , false otherwise
|
||||
* @return DOCUMENT ME!
|
||||
*
|
||||
* @throws DataAccessException DOCUMENT ME!
|
||||
*/
|
||||
|
||||
@@ -30,7 +30,6 @@ import javax.security.auth.login.LoginContext;
|
||||
public class JaasAuthenticationToken extends UsernamePasswordAuthenticationToken {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private transient LoginContext loginContext = null;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -32,7 +32,6 @@ import java.security.Principal;
|
||||
public class JaasGrantedAuthority extends GrantedAuthorityImpl {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Principal principal;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
+9
-26
@@ -123,36 +123,15 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
* Create an initialized instance to the values passed as arguments
|
||||
*
|
||||
* @param authenticator
|
||||
* @param authoritiesPopulator
|
||||
*/
|
||||
public LdapAuthenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authoritiesPopulator) {
|
||||
this.setAuthenticator(authenticator);
|
||||
this.setAuthoritiesPopulator(authoritiesPopulator);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
private void setAuthenticator(LdapAuthenticator authenticator) {
|
||||
Assert.notNull(authenticator, "An LdapAuthenticator must be supplied");
|
||||
this.authenticator = authenticator;
|
||||
}
|
||||
|
||||
private LdapAuthenticator getAuthenticator() {
|
||||
return authenticator;
|
||||
}
|
||||
|
||||
private void setAuthoritiesPopulator(LdapAuthoritiesPopulator authoritiesPopulator) {
|
||||
Assert.notNull(authoritiesPopulator, "An LdapAuthoritiesPopulator must be supplied");
|
||||
|
||||
this.authenticator = authenticator;
|
||||
this.authoritiesPopulator = authoritiesPopulator;
|
||||
}
|
||||
|
||||
protected LdapAuthoritiesPopulator getAuthoritiesPopulator() {
|
||||
return authoritiesPopulator;
|
||||
}
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
protected void additionalAuthenticationChecks(UserDetails userDetails,
|
||||
UsernamePasswordAuthenticationToken authentication)
|
||||
@@ -182,7 +161,7 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio
|
||||
user.setUsername(username);
|
||||
user.setPassword(password);
|
||||
|
||||
GrantedAuthority[] extraAuthorities = getAuthoritiesPopulator().getGrantedAuthorities(ldapUser);
|
||||
GrantedAuthority[] extraAuthorities = authoritiesPopulator.getGrantedAuthorities(ldapUser);
|
||||
|
||||
for (int i = 0; i < extraAuthorities.length; i++) {
|
||||
user.addAuthority(extraAuthorities[i]);
|
||||
@@ -191,6 +170,10 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio
|
||||
return user.createUserDetails();
|
||||
}
|
||||
|
||||
protected LdapAuthoritiesPopulator getAuthoritiesPoulator() {
|
||||
return authoritiesPopulator;
|
||||
}
|
||||
|
||||
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)
|
||||
throws AuthenticationException {
|
||||
if (!StringUtils.hasLength(username)) {
|
||||
@@ -212,7 +195,7 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio
|
||||
}
|
||||
|
||||
try {
|
||||
LdapUserDetails ldapUser = getAuthenticator().authenticate(username, password);
|
||||
LdapUserDetails ldapUser = authenticator.authenticate(username, password);
|
||||
|
||||
return createUserDetails(ldapUser, username, password);
|
||||
|
||||
|
||||
+8
-23
@@ -70,29 +70,7 @@ public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, In
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
* Create an initialized instance to the {@link InitialDirContextFactory} provided.
|
||||
*
|
||||
* @param initialDirContextFactory
|
||||
*/
|
||||
public AbstractLdapAuthenticator(InitialDirContextFactory initialDirContextFactory) {
|
||||
this.setInitialDirContextFactory(initialDirContextFactory);
|
||||
}
|
||||
|
||||
// ~ Methods
|
||||
// ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.isTrue((userDnFormat != null) || (userSearch != null),
|
||||
"Either an LdapUserSearch or DN pattern (or both) must be supplied.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link InitialDirContextFactory} and initialize this instance from its data.
|
||||
*
|
||||
* @param initialDirContextFactory
|
||||
*/
|
||||
private void setInitialDirContextFactory(InitialDirContextFactory initialDirContextFactory) {
|
||||
protected AbstractLdapAuthenticator(InitialDirContextFactory initialDirContextFactory) {
|
||||
Assert.notNull(initialDirContextFactory, "initialDirContextFactory must not be null.");
|
||||
this.initialDirContextFactory = initialDirContextFactory;
|
||||
|
||||
@@ -103,6 +81,13 @@ public abstract class AbstractLdapAuthenticator implements LdapAuthenticator, In
|
||||
}
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.isTrue((userDnFormat != null) || (userSearch != null),
|
||||
"Either an LdapUserSearch or DN pattern (or both) must be supplied.");
|
||||
}
|
||||
|
||||
protected InitialDirContextFactory getInitialDirContextFactory() {
|
||||
return initialDirContextFactory;
|
||||
}
|
||||
|
||||
+8
-19
@@ -26,7 +26,6 @@ import org.acegisecurity.userdetails.ldap.LdapUserDetailsImpl;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
@@ -45,11 +44,6 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
* Create an initialized instance to the {@link InitialDirContextFactory} provided.
|
||||
*
|
||||
* @param initialDirContextFactory
|
||||
*/
|
||||
public BindAuthenticator(InitialDirContextFactory initialDirContextFactory) {
|
||||
super(initialDirContextFactory);
|
||||
}
|
||||
@@ -83,6 +77,10 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
|
||||
private LdapUserDetails bindWithDn(String userDn, String username, String password) {
|
||||
LdapTemplate template = new LdapTemplate(getInitialDirContextFactory(), userDn, password);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Attempting to bind with DN = " + userDn);
|
||||
}
|
||||
|
||||
try {
|
||||
LdapUserDetailsImpl.Essence user = (LdapUserDetailsImpl.Essence) template.retrieveEntry(userDn,
|
||||
getUserDetailsMapper(), getUserAttributes());
|
||||
@@ -91,21 +89,12 @@ public class BindAuthenticator extends AbstractLdapAuthenticator {
|
||||
return user.createUserDetails();
|
||||
} catch (BadCredentialsException e) {
|
||||
// This will be thrown if an invalid user name is used and the method may
|
||||
// be called multiple times to try different names, so we trap the exception
|
||||
// unless a subclass wishes to implement more specialized behaviour.
|
||||
handleBindException(userDn, username, e.getCause());
|
||||
// be called multiple times to try different names, so we trap the exception.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to bind as " + userDn + ": " + e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows subclasses to inspect the exception thrown by an attempt to bind with a particular DN.
|
||||
* The default implementation just reports the failure to the debug log.
|
||||
*/
|
||||
void handleBindException(String userDn, String username, Throwable cause) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to bind as " + userDn + ": " + cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-37
@@ -121,8 +121,18 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
||||
* context factory.
|
||||
*/
|
||||
public DefaultLdapAuthoritiesPopulator(InitialDirContextFactory initialDirContextFactory, String groupSearchBase) {
|
||||
this.setInitialDirContextFactory(initialDirContextFactory);
|
||||
this.setGroupSearchBase(groupSearchBase);
|
||||
Assert.notNull(initialDirContextFactory, "InitialDirContextFactory must not be null");
|
||||
Assert.notNull(groupSearchBase, "The groupSearchBase (name to search under), must not be null.");
|
||||
this.initialDirContextFactory = initialDirContextFactory;
|
||||
this.groupSearchBase = groupSearchBase;
|
||||
|
||||
if (groupSearchBase.length() == 0) {
|
||||
logger.info("groupSearchBase is empty. Searches will be performed from the root: "
|
||||
+ initialDirContextFactory.getRootDn());
|
||||
}
|
||||
|
||||
ldapTemplate = new LdapTemplate(initialDirContextFactory);
|
||||
ldapTemplate.setSearchControls(searchControls);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
@@ -194,16 +204,16 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
||||
public Set getGroupMembershipRoles(String userDn, String username) {
|
||||
Set authorities = new HashSet();
|
||||
|
||||
if (getGroupSearchBase() == null) {
|
||||
if (groupSearchBase == null) {
|
||||
return authorities;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Searching for roles for user '" + username + "', DN = " + "'" + userDn + "', with filter "
|
||||
+ groupSearchFilter + " in search base '" + getGroupSearchBase() + "'");
|
||||
+ groupSearchFilter + " in search base '" + groupSearchBase + "'");
|
||||
}
|
||||
|
||||
Set userRoles = ldapTemplate.searchForSingleAttributeValues(getGroupSearchBase(), groupSearchFilter,
|
||||
Set userRoles = ldapTemplate.searchForSingleAttributeValues(groupSearchBase, groupSearchFilter,
|
||||
new String[] {userDn, username}, groupRoleAttribute);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -244,38 +254,6 @@ public class DefaultLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator
|
||||
return initialDirContextFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link InitialDirContextFactory}
|
||||
*
|
||||
* @param initialDirContextFactory supplies the contexts used to search for user roles.
|
||||
*/
|
||||
private void setInitialDirContextFactory(InitialDirContextFactory initialDirContextFactory) {
|
||||
Assert.notNull(initialDirContextFactory, "InitialDirContextFactory must not be null");
|
||||
this.initialDirContextFactory = initialDirContextFactory;
|
||||
|
||||
ldapTemplate = new LdapTemplate(initialDirContextFactory);
|
||||
ldapTemplate.setSearchControls(searchControls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the group search base (name to search under)
|
||||
*
|
||||
* @param groupSearchBase if this is an empty string the search will be performed from the root DN of the context
|
||||
* factory.
|
||||
*/
|
||||
private void setGroupSearchBase(String groupSearchBase) {
|
||||
Assert.notNull(groupSearchBase, "The groupSearchBase (name to search under), must not be null.");
|
||||
this.groupSearchBase = groupSearchBase;
|
||||
if (groupSearchBase.length() == 0) {
|
||||
logger.info("groupSearchBase is empty. Searches will be performed from the root: "
|
||||
+ getInitialDirContextFactory().getRootDn());
|
||||
}
|
||||
}
|
||||
|
||||
private String getGroupSearchBase() {
|
||||
return groupSearchBase;
|
||||
}
|
||||
|
||||
public void setConvertToUpperCase(boolean convertToUpperCase) {
|
||||
this.convertToUpperCase = convertToUpperCase;
|
||||
}
|
||||
|
||||
+13
-5
@@ -15,11 +15,14 @@
|
||||
|
||||
package org.acegisecurity.providers.rememberme;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
|
||||
import org.acegisecurity.providers.AbstractAuthenticationToken;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a remembered <code>Authentication</code>.<p>A remembered <code>Authentication</code> must provide a
|
||||
@@ -31,13 +34,12 @@ import org.acegisecurity.providers.AbstractAuthenticationToken;
|
||||
public class RememberMeAuthenticationToken extends AbstractAuthenticationToken implements Serializable {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Object principal;
|
||||
private int keyHash;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param key to identify if this object made by an authorised client
|
||||
@@ -49,10 +51,16 @@ public class RememberMeAuthenticationToken extends AbstractAuthenticationToken i
|
||||
public RememberMeAuthenticationToken(String key, Object principal, GrantedAuthority[] authorities) {
|
||||
super(authorities);
|
||||
|
||||
if ((key == null) || ("".equals(key)) || (principal == null) || "".equals(principal)) {
|
||||
if ((key == null) || ("".equals(key)) || (principal == null) || "".equals(principal) || (authorities == null)
|
||||
|| (authorities.length == 0)) {
|
||||
throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
|
||||
}
|
||||
|
||||
for (int i = 0; i < authorities.length; i++) {
|
||||
Assert.notNull(authorities[i],
|
||||
"Granted authority element " + i + " is null - GrantedAuthority[] cannot contain any null elements");
|
||||
}
|
||||
|
||||
this.keyHash = key.hashCode();
|
||||
this.principal = principal;
|
||||
setAuthenticated(true);
|
||||
|
||||
-132
@@ -1,132 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed 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.acegisecurity.providers.siteminder;
|
||||
|
||||
import org.acegisecurity.AccountExpiredException;
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
import org.acegisecurity.AuthenticationServiceException;
|
||||
import org.acegisecurity.CredentialsExpiredException;
|
||||
import org.acegisecurity.DisabledException;
|
||||
import org.acegisecurity.LockedException;
|
||||
import org.acegisecurity.providers.AuthenticationProvider;
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
import org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider;
|
||||
import org.acegisecurity.userdetails.UserDetails;
|
||||
import org.acegisecurity.userdetails.UserDetailsService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An {@link AuthenticationProvider} implementation that retrieves user details from an {@link UserDetailsService}.
|
||||
*
|
||||
* @author Scott McCrory
|
||||
* @version $Id: SiteminderAuthenticationProvider.java 1582 2006-07-15 15:18:51Z smccrory $
|
||||
*/
|
||||
public class SiteminderAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
|
||||
|
||||
/**
|
||||
* Our logging object
|
||||
*/
|
||||
private static final Log logger = LogFactory.getLog(SiteminderAuthenticationProvider.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
/**
|
||||
* Our user details service (which does the real work of checking the user against a back-end user store).
|
||||
*/
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* @see org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider#additionalAuthenticationChecks(org.acegisecurity.userdetails.UserDetails, org.acegisecurity.providers.UsernamePasswordAuthenticationToken)
|
||||
*/
|
||||
protected void additionalAuthenticationChecks(final UserDetails user,
|
||||
final UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
|
||||
|
||||
// No need for password authentication checks - we only expect one identifying string
|
||||
// from the HTTP Request header (as populated by Siteminder), but we do need to see if
|
||||
// the user's account is OK to let them in.
|
||||
if (!user.isEnabled()) {
|
||||
throw new DisabledException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.disabled",
|
||||
"Account disabled"));
|
||||
}
|
||||
|
||||
if (!user.isAccountNonExpired()) {
|
||||
throw new AccountExpiredException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.expired",
|
||||
"Account expired"));
|
||||
}
|
||||
|
||||
if (!user.isAccountNonLocked()) {
|
||||
throw new LockedException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.locked",
|
||||
"Account locked"));
|
||||
}
|
||||
|
||||
if (!user.isCredentialsNonExpired()) {
|
||||
throw new CredentialsExpiredException(messages.getMessage(
|
||||
"AbstractUserDetailsAuthenticationProvider.credentialsExpired", "Credentials expired"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider#doAfterPropertiesSet()
|
||||
*/
|
||||
protected void doAfterPropertiesSet() throws Exception {
|
||||
Assert.notNull(this.userDetailsService, "A UserDetailsService must be set");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user details service.
|
||||
* @return The user details service.
|
||||
*/
|
||||
public UserDetailsService getUserDetailsService() {
|
||||
return userDetailsService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider#retrieveUser(java.lang.String, org.acegisecurity.providers.UsernamePasswordAuthenticationToken)
|
||||
*/
|
||||
protected final UserDetails retrieveUser(final String username,
|
||||
final UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
|
||||
|
||||
UserDetails loadedUser;
|
||||
|
||||
try {
|
||||
loadedUser = this.getUserDetailsService().loadUserByUsername(username);
|
||||
} catch (DataAccessException repositoryProblem) {
|
||||
throw new AuthenticationServiceException(repositoryProblem.getMessage(), repositoryProblem);
|
||||
}
|
||||
|
||||
if (loadedUser == null) {
|
||||
throw new AuthenticationServiceException(
|
||||
"UserDetailsService returned null, which is an interface contract violation");
|
||||
}
|
||||
|
||||
return loadedUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user details service.
|
||||
* @param userDetailsService The user details service.
|
||||
*/
|
||||
public void setUserDetailsService(final UserDetailsService userDetailsService) {
|
||||
this.userDetailsService = userDetailsService;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
A Siteminder authentication provider.
|
||||
</body>
|
||||
</html>
|
||||
@@ -31,7 +31,6 @@ import java.security.cert.X509Certificate;
|
||||
public class X509AuthenticationToken extends AbstractAuthenticationToken {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Object principal;
|
||||
private X509Certificate credentials;
|
||||
|
||||
|
||||
+2
-2
@@ -117,7 +117,7 @@ public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator, In
|
||||
this.subjectDNRegex = subjectDNRegex;
|
||||
}
|
||||
|
||||
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
||||
this.userDetailsService = userDetailsService;
|
||||
public void setUserDetailsService(UserDetailsService authenticationDao) {
|
||||
this.userDetailsService = authenticationDao;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.acegisecurity.providers.AbstractAuthenticationToken;
|
||||
public class RunAsUserToken extends AbstractAuthenticationToken {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Class originalAuthentication;
|
||||
private Object credentials;
|
||||
private Object principal;
|
||||
|
||||
@@ -313,13 +313,13 @@ public abstract class AbstractProcessingFilter implements Filter, InitializingBe
|
||||
return uri.endsWith(request.getContextPath() + filterProcessesUrl);
|
||||
}
|
||||
|
||||
protected void sendRedirect(HttpServletRequest request, HttpServletResponse response, String url)
|
||||
protected void sendRedirect(HttpServletRequest request, HttpServletResponse response, String failureUrl)
|
||||
throws IOException {
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
||||
url = request.getContextPath() + url;
|
||||
if (!failureUrl.startsWith("http://") && !failureUrl.startsWith("https://")) {
|
||||
failureUrl = request.getContextPath() + failureUrl;
|
||||
}
|
||||
|
||||
response.sendRedirect(response.encodeRedirectURL(url));
|
||||
response.sendRedirect(response.encodeRedirectURL(failureUrl));
|
||||
}
|
||||
|
||||
public void setAlwaysUseDefaultTargetUrl(boolean alwaysUseDefaultTargetUrl) {
|
||||
@@ -348,8 +348,6 @@ public abstract class AbstractProcessingFilter implements Filter, InitializingBe
|
||||
}
|
||||
|
||||
public void setDefaultTargetUrl(String defaultTargetUrl) {
|
||||
Assert.isTrue(defaultTargetUrl.startsWith("/") | defaultTargetUrl.startsWith("http"),
|
||||
"defaultTarget must start with '/' or with 'http(s)'");
|
||||
this.defaultTargetUrl = defaultTargetUrl;
|
||||
}
|
||||
|
||||
@@ -381,11 +379,14 @@ public abstract class AbstractProcessingFilter implements Filter, InitializingBe
|
||||
logger.debug("Updated SecurityContextHolder to contain the following Authentication: '" + authResult + "'");
|
||||
}
|
||||
|
||||
// Don't attempt to obtain the url from the saved request if alwaysUsedefaultTargetUrl is set
|
||||
String targetUrl = alwaysUseDefaultTargetUrl ? null : obtainFullRequestUrl(request);
|
||||
String targetUrl = obtainFullRequestUrl(request);
|
||||
|
||||
if (alwaysUseDefaultTargetUrl) {
|
||||
targetUrl = null;
|
||||
}
|
||||
|
||||
if (targetUrl == null) {
|
||||
targetUrl = getDefaultTargetUrl();
|
||||
targetUrl = request.getContextPath() + getDefaultTargetUrl();
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -401,7 +402,7 @@ public abstract class AbstractProcessingFilter implements Filter, InitializingBe
|
||||
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
|
||||
}
|
||||
|
||||
sendRedirect(request, response, targetUrl);
|
||||
response.sendRedirect(response.encodeRedirectURL(targetUrl));
|
||||
}
|
||||
|
||||
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||
|
||||
@@ -62,13 +62,21 @@ public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
|
||||
|
||||
// Perform RequestDispatcher "forward"
|
||||
RequestDispatcher rd = request.getRequestDispatcher(errorPage);
|
||||
rd.forward(request, response);
|
||||
|
||||
try {
|
||||
rd.forward(request, response);
|
||||
((HttpServletResponse) response).setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||
|
||||
return;
|
||||
} catch (Exception responseCommitted) {
|
||||
if (logger.isErrorEnabled()) {
|
||||
logger.error("Error processing " + request.toString(), responseCommitted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!response.isCommitted()) {
|
||||
// Send 403 (we do this after response has been written)
|
||||
((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage());
|
||||
}
|
||||
// Send 403 (we do this after response has been written)
|
||||
((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,27 @@
|
||||
|
||||
package org.acegisecurity.ui.basicauth;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
import org.acegisecurity.AuthenticationManager;
|
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.acegisecurity.ui.AuthenticationDetailsSource;
|
||||
import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
|
||||
import org.acegisecurity.ui.AuthenticationEntryPoint;
|
||||
import org.acegisecurity.ui.rememberme.RememberMeServices;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
@@ -26,21 +47,6 @@ import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthenticationException;
|
||||
import org.acegisecurity.AuthenticationManager;
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
import org.acegisecurity.ui.AuthenticationDetailsSource;
|
||||
import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
|
||||
import org.acegisecurity.ui.AuthenticationEntryPoint;
|
||||
import org.acegisecurity.ui.rememberme.RememberMeServices;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
/**
|
||||
* Processes a HTTP request's BASIC authorization headers, putting the result into the
|
||||
@@ -129,10 +135,7 @@ public class BasicProcessingFilter implements Filter, InitializingBean {
|
||||
// Only reauthenticate if username doesn't match SecurityContextHolder and user isn't authenticated (see SEC-53)
|
||||
Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
|
||||
|
||||
// Limit username comparison to providers which user usernames (ie UsernamePasswordAuthenticationToken) (see SEC-348)
|
||||
if ((existingAuth == null)
|
||||
|| (existingAuth instanceof UsernamePasswordAuthenticationToken && !existingAuth.getName().equals(username))
|
||||
|| !existingAuth.isAuthenticated()) {
|
||||
if ((existingAuth == null) || !existingAuth.getName().equals(username) || !existingAuth.isAuthenticated()) {
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username,
|
||||
password);
|
||||
authRequest.setDetails(authenticationDetailsSource.buildDetails((HttpServletRequest) request));
|
||||
|
||||
@@ -431,7 +431,7 @@ public class DigestProcessingFilter implements Filter, InitializingBean, Message
|
||||
this.userCache = userCache;
|
||||
}
|
||||
|
||||
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
||||
this.userDetailsService = userDetailsService;
|
||||
public void setUserDetailsService(UserDetailsService authenticationDao) {
|
||||
this.userDetailsService = authenticationDao;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,60 +18,28 @@ package org.acegisecurity.ui.logout;
|
||||
import org.acegisecurity.Authentication;
|
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
|
||||
/**
|
||||
* Performs a logout by modifying the {@link org.acegisecurity.context.SecurityContextHolder}.
|
||||
*
|
||||
* <p>Will also invalidate the {@link HttpSession} if {@link #isInvalidateHttpSession()} is
|
||||
* <code>true</code> and the session is not <code>null</code>.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class SecurityContextLogoutHandler implements LogoutHandler {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
private boolean invalidateHttpSession = true;
|
||||
|
||||
/**
|
||||
* Requires the request to be passed in.
|
||||
* Does not use any arguments. They can all be <code>null</code>.
|
||||
*
|
||||
* @param request from which to obtain a HTTP session (cannot be null)
|
||||
* @param request not used (can be <code>null</code>)
|
||||
* @param response not used (can be <code>null</code>)
|
||||
* @param authentication not used (can be <code>null</code>)
|
||||
*/
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
|
||||
Assert.notNull(request, "HttpServletRequest required");
|
||||
if (invalidateHttpSession) {
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session != null) {
|
||||
session.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
SecurityContextHolder.clearContext();
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
public boolean isInvalidateHttpSession() {
|
||||
return invalidateHttpSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the {@link HttpSession} to be invalidated when this
|
||||
* {@link LogoutHandler} is invoked. Defaults to true.
|
||||
*
|
||||
* @param invalidateHttpSession true if you wish the session to be
|
||||
* invalidated (default) or false if it should not be
|
||||
*/
|
||||
public void setInvalidateHttpSession(boolean invalidateHttpSession) {
|
||||
this.invalidateHttpSession = invalidateHttpSession;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -319,7 +319,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
|
||||
this.tokenValiditySeconds = tokenValiditySeconds;
|
||||
}
|
||||
|
||||
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
||||
this.userDetailsService = userDetailsService;
|
||||
public void setUserDetailsService(UserDetailsService authenticationDao) {
|
||||
this.userDetailsService = authenticationDao;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
||||
/**
|
||||
@@ -55,8 +55,8 @@ public class SavedRequest implements java.io.Serializable {
|
||||
|
||||
private ArrayList cookies = new ArrayList();
|
||||
private ArrayList locales = new ArrayList();
|
||||
private Map headers = new TreeMap(String.CASE_INSENSITIVE_ORDER);
|
||||
private Map parameters = new TreeMap(String.CASE_INSENSITIVE_ORDER);
|
||||
private HashMap headers = new HashMap();
|
||||
private HashMap parameters = new HashMap();
|
||||
private String contextPath;
|
||||
private String method;
|
||||
private String pathInfo;
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.acegisecurity.GrantedAuthorityImpl;
|
||||
public class SwitchUserGrantedAuthority extends GrantedAuthorityImpl {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Authentication source;
|
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
@@ -439,8 +439,8 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, App
|
||||
*
|
||||
* @param authenticationDao The authentication dao
|
||||
*/
|
||||
public void setUserDetailsService(UserDetailsService userDetailsService) {
|
||||
this.userDetailsService = userDetailsService;
|
||||
public void setUserDetailsService(UserDetailsService authenticationDao) {
|
||||
this.userDetailsService = authenticationDao;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Authenticates users via HTTP properties, headers and session.
|
||||
Authenticates users via a standard web form and <code>HttpSession</code>.
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.springframework.util.Assert;
|
||||
public class User implements UserDetails {
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String password;
|
||||
private String username;
|
||||
private GrantedAuthority[] authorities;
|
||||
|
||||
@@ -41,7 +41,6 @@ import javax.naming.ldap.Control;
|
||||
public class LdapUserDetailsImpl implements LdapUserDetails {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final GrantedAuthority[] NO_AUTHORITIES = new GrantedAuthority[0];
|
||||
private static final Control[] NO_CONTROLS = new Control[0];
|
||||
|
||||
@@ -110,7 +109,7 @@ public class LdapUserDetailsImpl implements LdapUserDetails {
|
||||
* Variation of essence pattern. Used to create mutable intermediate object
|
||||
*/
|
||||
public static class Essence {
|
||||
LdapUserDetailsImpl instance = createTarget();
|
||||
LdapUserDetailsImpl instance = new LdapUserDetailsImpl();
|
||||
List mutableAuthorities = new ArrayList();
|
||||
|
||||
public Essence() {}
|
||||
@@ -128,10 +127,6 @@ public class LdapUserDetailsImpl implements LdapUserDetails {
|
||||
setAuthorities(copyMe.getAuthorities());
|
||||
}
|
||||
|
||||
LdapUserDetailsImpl createTarget() {
|
||||
return new LdapUserDetailsImpl();
|
||||
}
|
||||
|
||||
public Essence addAuthority(GrantedAuthority a) {
|
||||
mutableAuthorities.add(a);
|
||||
|
||||
|
||||
@@ -58,7 +58,14 @@ public class LdapUserDetailsMapper implements LdapEntryMapper {
|
||||
Attribute passwordAttribute = attributes.get(passwordAttributeName);
|
||||
|
||||
if (passwordAttribute != null) {
|
||||
essence.setPassword(mapPassword(passwordAttribute));
|
||||
Object retrievedPassword = passwordAttribute.get();
|
||||
|
||||
if (!(retrievedPassword instanceof String)) {
|
||||
// Assume it's binary
|
||||
retrievedPassword = new String((byte[]) retrievedPassword);
|
||||
}
|
||||
|
||||
essence.setPassword((String) retrievedPassword);
|
||||
}
|
||||
|
||||
// Map the roles
|
||||
@@ -86,25 +93,6 @@ public class LdapUserDetailsMapper implements LdapEntryMapper {
|
||||
return essence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension point to allow customized creation of the user's password from
|
||||
* the attribute stored in the directory.
|
||||
*
|
||||
* @param passwordAttribute the attribute instance containing the password
|
||||
* @return a String representation of the password.
|
||||
*/
|
||||
protected String mapPassword(Attribute passwordAttribute) throws NamingException {
|
||||
Object retrievedPassword = passwordAttribute.get();
|
||||
|
||||
if (!(retrievedPassword instanceof String)) {
|
||||
// Assume it's binary
|
||||
retrievedPassword = new String((byte[]) retrievedPassword);
|
||||
}
|
||||
|
||||
return (String) retrievedPassword;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a GrantedAuthority from a role attribute. Override to customize
|
||||
* authority object creation.
|
||||
|
||||
@@ -18,8 +18,6 @@ package org.acegisecurity.userdetails.memory;
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.GrantedAuthorityImpl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
@@ -55,32 +53,6 @@ public class UserAttribute {
|
||||
return (GrantedAuthority[]) this.authorities.toArray(toReturn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all authorities for this user.
|
||||
*
|
||||
* @param authorities {@link List} <{@link GrantedAuthority}>
|
||||
* @since 1.1
|
||||
*/
|
||||
public void setAuthorities(List authorities) {
|
||||
this.authorities = authorities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all authorities for this user from String values.
|
||||
* It will create the necessary {@link GrantedAuthority} objects.
|
||||
*
|
||||
* @param authoritiesAsString {@link List} <{@link String}>
|
||||
* @since 1.1
|
||||
*/
|
||||
public void setAuthoritiesAsString(List authoritiesAsString) {
|
||||
setAuthorities(new ArrayList(authoritiesAsString.size()));
|
||||
Iterator it = authoritiesAsString.iterator();
|
||||
while (it.hasNext()) {
|
||||
GrantedAuthority grantedAuthority = new GrantedAuthorityImpl((String) it.next());
|
||||
addAuthority(grantedAuthority);
|
||||
}
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
@@ -15,12 +15,13 @@
|
||||
|
||||
package org.acegisecurity.userdetails.memory;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.acegisecurity.GrantedAuthorityImpl;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
|
||||
|
||||
/**
|
||||
* Property editor that creates a {@link UserAttribute} from a comma separated list of values.
|
||||
*
|
||||
@@ -34,8 +35,6 @@ public class UserAttributeEditor extends PropertyEditorSupport {
|
||||
if (StringUtils.hasText(s)) {
|
||||
String[] tokens = StringUtils.commaDelimitedListToStringArray(s);
|
||||
UserAttribute userAttrib = new UserAttribute();
|
||||
|
||||
List authoritiesAsString = new ArrayList();
|
||||
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
String currentToken = tokens[i].trim();
|
||||
@@ -48,11 +47,10 @@ public class UserAttributeEditor extends PropertyEditorSupport {
|
||||
} else if (currentToken.toLowerCase().equals("disabled")) {
|
||||
userAttrib.setEnabled(false);
|
||||
} else {
|
||||
authoritiesAsString.add(currentToken);
|
||||
userAttrib.addAuthority(new GrantedAuthorityImpl(currentToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
userAttrib.setAuthoritiesAsString(authoritiesAsString);
|
||||
|
||||
if (userAttrib.isValid()) {
|
||||
setValue(userAttrib);
|
||||
|
||||
@@ -15,15 +15,18 @@
|
||||
|
||||
package org.acegisecurity.userdetails.memory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.acegisecurity.userdetails.User;
|
||||
import org.acegisecurity.userdetails.UserDetails;
|
||||
import org.acegisecurity.userdetails.UsernameNotFoundException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Used by {@link InMemoryDaoImpl} to store a list of users and their corresponding granted authorities.
|
||||
@@ -65,8 +68,8 @@ public class UserMap {
|
||||
*
|
||||
* @throws UsernameNotFoundException if the user could not be found
|
||||
*/
|
||||
public UserDetails getUser(String username) throws UsernameNotFoundException {
|
||||
UserDetails result = (UserDetails) this.userMap.get(username.toLowerCase());
|
||||
public User getUser(String username) throws UsernameNotFoundException {
|
||||
User result = (User) this.userMap.get(username.toLowerCase());
|
||||
|
||||
if (result == null) {
|
||||
throw new UsernameNotFoundException("Could not find user: " + username);
|
||||
@@ -83,14 +86,4 @@ public class UserMap {
|
||||
public int getUserCount() {
|
||||
return this.userMap.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the users in this {@link UserMap}. Overrides previously added users.
|
||||
*
|
||||
* @param users {@link Map} <{@link String}, {@link UserDetails}> with pairs (username, userdetails)
|
||||
* @since 1.1
|
||||
*/
|
||||
public void setUsers(Map users) {
|
||||
this.userMap = users;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed 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.acegisecurity.util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.spec.KeySpec;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.DESedeKeySpec;
|
||||
|
||||
import org.acegisecurity.AcegiSecurityException;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A static utility class that can encrypt and decrypt text.
|
||||
*
|
||||
* <p>This class is useful if you have simple needs and wish to use the DESede
|
||||
* encryption cipher. More sophisticated requirements will need to use the
|
||||
* Java crypto libraries directly.
|
||||
*
|
||||
* @author Alan Stewart
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class EncryptionUtils {
|
||||
|
||||
/**
|
||||
* This is a static class that should not be instantiated.
|
||||
*/
|
||||
private EncryptionUtils() {}
|
||||
|
||||
/**
|
||||
* Converts a String into a byte array using UTF-8, falling back to the
|
||||
* platform's default character set if UTF-8 fails.
|
||||
*
|
||||
* @param input the input (required)
|
||||
* @return a byte array representation of the input string
|
||||
*/
|
||||
public static byte[] stringToByteArray(String input) {
|
||||
Assert.hasLength(input, "Input required");
|
||||
try {
|
||||
return input.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException fallbackToDefault) {
|
||||
return input.getBytes();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array into a String using UTF-8, falling back to the
|
||||
* platform's default character set if UTF-8 fails.
|
||||
*
|
||||
* @param byteArray the byte array to convert (required)
|
||||
* @return a string representation of the byte array
|
||||
*/
|
||||
public static String byteArrayToString(byte[] byteArray) {
|
||||
Assert.notNull(byteArray, "ByteArray required");
|
||||
Assert.isTrue(byteArray.length > 0, "ByteArray cannot be empty");
|
||||
try {
|
||||
return new String(byteArray, "UTF8");
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
return new String(byteArray);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] cipher(String key, byte[] passedBytes, int cipherMode) throws EncryptionException {
|
||||
try {
|
||||
final KeySpec keySpec = new DESedeKeySpec(stringToByteArray(key));
|
||||
final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
|
||||
final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
|
||||
final SecretKey secretKey = keyFactory.generateSecret(keySpec);
|
||||
cipher.init(cipherMode, secretKey);
|
||||
return cipher.doFinal(passedBytes);
|
||||
} catch (final Exception e) {
|
||||
throw new EncryptionException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts the inputString using the key.
|
||||
*
|
||||
* @param key at least 24 character long key (required)
|
||||
* @param inputString the string to encrypt (required)
|
||||
* @return the encrypted version of the inputString
|
||||
* @throws EncryptionException in the event of an encryption failure
|
||||
*/
|
||||
public static String encrypt(String key, String inputString) throws EncryptionException {
|
||||
isValidKey(key);
|
||||
final byte[] cipherText = cipher(key, stringToByteArray(inputString), Cipher.ENCRYPT_MODE);
|
||||
return byteArrayToString(Base64.encodeBase64(cipherText));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts the inputString using the key.
|
||||
*
|
||||
* @param key the key used to originally encrypt the string (required)
|
||||
* @param inputString the encrypted string (required)
|
||||
* @return the decrypted version of inputString
|
||||
* @throws EncryptionException in the event of an encryption failure
|
||||
*/
|
||||
public static String decrypt(String key, String inputString) throws EncryptionException {
|
||||
Assert.hasText(key, "A key is required to attempt decryption");
|
||||
final byte[] cipherText = cipher(key, Base64.decodeBase64(stringToByteArray(inputString)), Cipher.DECRYPT_MODE);
|
||||
return byteArrayToString(cipherText);
|
||||
}
|
||||
|
||||
private static void isValidKey(String key) {
|
||||
Assert.hasText(key, "A key to perform the encryption is required");
|
||||
Validate.isTrue(key.length() >= 24, "Key must be at least 24 characters long");
|
||||
}
|
||||
|
||||
public static class EncryptionException extends AcegiSecurityException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public EncryptionException(String message, Throwable t) {
|
||||
super(message, t);
|
||||
}
|
||||
|
||||
public EncryptionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,40 +28,32 @@ import java.util.Map;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Delegates <code>Filter</code> requests to a Spring-managed bean.</p>
|
||||
*
|
||||
* <p>This class acts as a proxy on behalf of a
|
||||
* Delegates <code>Filter</code> requests to a Spring-managed bean.<p>This class acts as a proxy on behalf of a
|
||||
* target <code>Filter</code> that is defined in the Spring bean context. It is necessary to specify which target
|
||||
* <code>Filter</code> should be proxied as a filter initialization parameter.</p>
|
||||
*
|
||||
* <p>On filter initialisation, the class will use Spring's {@link
|
||||
* <p>On filter initialisation, the class will use Spring's {@link
|
||||
* WebApplicationContextUtils#getWebApplicationContext(ServletContext sc)} method to obtain an
|
||||
* <code>ApplicationContext</code> instance. It will expect to find the target <code>Filter</code> in this
|
||||
* <code>ApplicationContext</code>.</p>
|
||||
*
|
||||
* <p>To use this filter, it is necessary to specify <b>one</b> of the following filter initialization parameters:
|
||||
* <p>To use this filter, it is necessary to specify <b>one</b> of the following filter initialization parameters:</p>
|
||||
* <ul>
|
||||
* <li><code>targetClass</code> indicates the class of the target <code>Filter</code> defined in the bean
|
||||
* context. The only requirements are that this target class implements the <code>javax.servlet.Filter</code>
|
||||
* interface and at least one instance is available in the <code>ApplicationContext</code>.</li>
|
||||
* <li><code>targetBean</code> indicates the bean name of the target class.</li>
|
||||
* </ul>
|
||||
* If both initialization parameters are specified, <code>targetBean</code> takes priority.</p>
|
||||
*
|
||||
* <p>An additional
|
||||
* If both initialization parameters are specified, <code>targetBean</code> takes priority.<P>An additional
|
||||
* initialization parameter, <code>init</code>, is also supported. If set to "<code>lazy</code>" the initialization
|
||||
* will take place on the first HTTP request, rather than at filter creation time. This makes it possible to use
|
||||
* <code>FilterToBeanProxy</code> with the Spring <code>ContextLoaderServlet</code>. Where possible you should not use
|
||||
* this initialization parameter, instead using <code>ContextLoaderListener</code>.</p>
|
||||
*
|
||||
* <p>A final optional initialization parameter, <code>lifecycle</code>, determines whether the servlet container
|
||||
* <p>A final optional initialization parameter, <code>lifecycle</code>, determines whether the servlet container
|
||||
* or the IoC container manages the lifecycle of the proxied filter. When possible you should write your filters to be
|
||||
* managed via the IoC container interfaces such as {@link org.springframework.beans.factory.InitializingBean} and
|
||||
* {@link org.springframework.beans.factory.DisposableBean}. If you cannot control the filters you wish to proxy (eg
|
||||
|
||||
@@ -72,7 +72,7 @@ public class MethodInvocationUtils {
|
||||
classArgs = (Class[]) list.toArray(new Class[] {});
|
||||
}
|
||||
|
||||
return createFromClass(object.getClass(), methodName, classArgs, args);
|
||||
return createFromClass(object.getClass(), methodName, classArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +84,7 @@ public class MethodInvocationUtils {
|
||||
* @return a <code>MethodInvocation</code>, or <code>null</code> if there was a problem
|
||||
*/
|
||||
public static MethodInvocation createFromClass(Class clazz, String methodName) {
|
||||
return createFromClass(clazz, methodName, null, null);
|
||||
return createFromClass(clazz, methodName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,18 +93,18 @@ public class MethodInvocationUtils {
|
||||
*
|
||||
* @param clazz the class of object that will be used to find the relevant <code>Method</code>
|
||||
* @param methodName the name of the method to find
|
||||
* @param classArgs arguments that are required to locate the relevant method signature
|
||||
* @param args the actual arguments that should be passed to SimpleMethodInvocation
|
||||
* @param args arguments that are required as part of the method signature
|
||||
*
|
||||
* @return a <code>MethodInvocation</code>, or <code>null</code> if there was a problem
|
||||
*/
|
||||
public static MethodInvocation createFromClass(Class clazz, String methodName, Class[] classArgs, Object[] args) {
|
||||
public static MethodInvocation createFromClass(Class clazz, String methodName, Class[] args) {
|
||||
Assert.notNull(clazz, "Class required");
|
||||
Assert.hasText(methodName, "MethodName required");
|
||||
|
||||
Method method;
|
||||
|
||||
try {
|
||||
method = clazz.getMethod(methodName, classArgs);
|
||||
method = clazz.getMethod(methodName, args);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.acegisecurity.ConfigAttributeDefinition;
|
||||
import org.acegisecurity.acl.AclEntry;
|
||||
import org.acegisecurity.acl.AclManager;
|
||||
import org.acegisecurity.acl.basic.BasicAclEntry;
|
||||
import org.acegisecurity.acl.basic.SimpleAclEntry;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -144,16 +143,6 @@ public class BasicAclEntryVoter extends AbstractAclVoter implements Initializing
|
||||
this.requirePermission = requirePermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow setting permissions with String literals instead of integers as {@link #setRequirePermission(int[])}
|
||||
*
|
||||
* @param requirePermission Permission literals
|
||||
* @see SimpleAclEntry#parsePermissions(String[]) for valid values
|
||||
*/
|
||||
public void setRequirePermissionFromString(String[] requirePermission) {
|
||||
setRequirePermission(SimpleAclEntry.parsePermissions(requirePermission));
|
||||
}
|
||||
|
||||
public boolean supports(ConfigAttribute attribute) {
|
||||
if ((attribute.getAttribute() != null) && attribute.getAttribute().startsWith(getProcessConfigAttribute())) {
|
||||
return true;
|
||||
|
||||
@@ -66,9 +66,8 @@ public class SecurityConfigTests extends TestCase {
|
||||
SecurityConfig security2 = new SecurityConfig("TEST");
|
||||
assertEquals(security1, security2);
|
||||
|
||||
// SEC-311: Must observe symmetry requirement of Object.equals(Object) contract
|
||||
String securityString1 = "TEST";
|
||||
assertNotSame(security1, securityString1);
|
||||
assertEquals(security1, securityString1);
|
||||
|
||||
String securityString2 = "NOT_EQUAL";
|
||||
assertTrue(!security1.equals(securityString2));
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.acegisecurity.acl.basic;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link SimpleAclEntry}.
|
||||
*
|
||||
@@ -170,38 +171,4 @@ public class SimpleAclEntryTests extends TestCase {
|
||||
acl.addPermissions(new int[] {SimpleAclEntry.READ, SimpleAclEntry.WRITE, SimpleAclEntry.CREATE});
|
||||
assertTrue(acl.toString().endsWith("marissa=-RWC- ............................111. (14)]"));
|
||||
}
|
||||
|
||||
public void testParsePermission() {
|
||||
assertPermission("NOTHING", SimpleAclEntry.NOTHING);
|
||||
assertPermission("ADMINISTRATION", SimpleAclEntry.ADMINISTRATION);
|
||||
assertPermission("READ", SimpleAclEntry.READ);
|
||||
assertPermission("WRITE", SimpleAclEntry.WRITE);
|
||||
assertPermission("CREATE", SimpleAclEntry.CREATE);
|
||||
assertPermission("DELETE", SimpleAclEntry.DELETE);
|
||||
assertPermission("READ_WRITE_DELETE", SimpleAclEntry.READ_WRITE_DELETE);
|
||||
}
|
||||
|
||||
public void testParsePermissionWrongValues() {
|
||||
try {
|
||||
SimpleAclEntry.parsePermission("X");
|
||||
fail(IllegalArgumentException.class.getName() + " must have been thrown.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private void assertPermission(String permission, int value) {
|
||||
assertEquals(value, SimpleAclEntry.parsePermission(permission));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the value returned by {@link SimpleAclEntry#getValidPermissions()} is not modifiable.
|
||||
*/
|
||||
public void testGetPermissions() {
|
||||
SimpleAclEntry acl = new SimpleAclEntry("", new NamedEntityObjectIdentity("x", "x"), null, 0);
|
||||
int[] permissions = acl.getValidPermissions();
|
||||
int i = permissions[0];
|
||||
permissions[0] -= 100;
|
||||
assertEquals("Value returned by getValidPermissions can be modified", i, acl.getValidPermissions()[0]);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -190,8 +190,7 @@ public class HttpSessionContextIntegrationFilterTests extends TestCase {
|
||||
// Prepare filter
|
||||
HttpSessionContextIntegrationFilter filter = new HttpSessionContextIntegrationFilter();
|
||||
filter.setContext(SecurityContextImpl.class);
|
||||
// don't call afterPropertiesSet to test case when not instantiated by Spring
|
||||
//filter.afterPropertiesSet();
|
||||
filter.afterPropertiesSet();
|
||||
|
||||
// Execute filter
|
||||
executeFilterInContainerSimulator(new MockFilterConfig(), filter, request, response, chain);
|
||||
|
||||
+2
-2
@@ -89,7 +89,7 @@ public class MethodInvocationPrivilegeEvaluatorTests extends TestCase {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("MOCK_LOWER")});
|
||||
MethodInvocation mi = MethodInvocationUtils.createFromClass(ITargetObject.class, "makeLowerCase",
|
||||
new Class[] {String.class}, new Object[] {"Hello world"});
|
||||
new Class[] {String.class});
|
||||
MethodSecurityInterceptor interceptor = makeSecurityInterceptor();
|
||||
|
||||
MethodInvocationPrivilegeEvaluator mipe = new MethodInvocationPrivilegeEvaluator();
|
||||
@@ -118,7 +118,7 @@ public class MethodInvocationPrivilegeEvaluatorTests extends TestCase {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("Test", "Password",
|
||||
new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_NOT_HELD")});
|
||||
MethodInvocation mi = MethodInvocationUtils.createFromClass(ITargetObject.class, "makeLowerCase",
|
||||
new Class[] {String.class}, new Object[] {"helloWorld"});
|
||||
new Class[] {String.class});
|
||||
MethodSecurityInterceptor interceptor = makeSecurityInterceptor();
|
||||
|
||||
MethodInvocationPrivilegeEvaluator mipe = new MethodInvocationPrivilegeEvaluator();
|
||||
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
/* Copyright 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed 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.acegisecurity.intercept.web;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.acegisecurity.ConfigAttributeDefinition;
|
||||
import org.acegisecurity.SecurityConfig;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Test for {@link FilterInvocationDefinitionDecorator}
|
||||
*
|
||||
* @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class FilterInvocationDefinitionDecoratorTest extends TestCase {
|
||||
|
||||
private FilterInvocationDefinitionDecorator decorator;
|
||||
|
||||
private FilterInvocationDefinition decorated;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
decorated = new MockFilterInvocationDefinition();
|
||||
decorator = new FilterInvocationDefinitionDecorator(decorated);
|
||||
}
|
||||
|
||||
public void testFilterInvocationDefinitionMapDecorator() {
|
||||
decorator = new FilterInvocationDefinitionDecorator();
|
||||
decorator.setDecorated(decorated);
|
||||
assertEquals(decorated, decorator.getDecorated());
|
||||
}
|
||||
|
||||
public void testSetMappings() {
|
||||
List roles = new ArrayList();
|
||||
roles.add("ROLE_USER");
|
||||
roles.add("ROLE_ADMIN");
|
||||
|
||||
FilterInvocationDefinitionSourceMapping mapping = new FilterInvocationDefinitionSourceMapping();
|
||||
mapping.setUrl("/secure/**");
|
||||
mapping.setConfigAttributes(roles);
|
||||
|
||||
List mappings = new ArrayList();
|
||||
mappings.add(mapping);
|
||||
|
||||
decorator.setMappings(mappings);
|
||||
|
||||
ConfigAttributeDefinition configDefinition = new ConfigAttributeDefinition();
|
||||
Iterator it = roles.iterator();
|
||||
while (it.hasNext()) {
|
||||
String role = (String) it.next();
|
||||
configDefinition.addConfigAttribute(new SecurityConfig(role));
|
||||
}
|
||||
|
||||
it = decorator.getConfigAttributeDefinitions();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
i++;
|
||||
assertEquals(configDefinition, it.next());
|
||||
}
|
||||
assertEquals(1, i);
|
||||
|
||||
assertEquals(mappings, decorator.getMappings());
|
||||
}
|
||||
}
|
||||
+3
-29
@@ -30,16 +30,17 @@ import org.acegisecurity.MockAuthenticationManager;
|
||||
import org.acegisecurity.MockRunAsManager;
|
||||
import org.acegisecurity.RunAsManager;
|
||||
import org.acegisecurity.SecurityConfig;
|
||||
|
||||
import org.acegisecurity.context.SecurityContextHolder;
|
||||
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
@@ -230,33 +231,6 @@ public class FilterSecurityInterceptorTests extends TestCase {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
public void testNotLoadedFromApplicationContext() throws Exception {
|
||||
FilterInvocationDefinitionSourceMapping mapping = new FilterInvocationDefinitionSourceMapping();
|
||||
mapping.setUrl("/secure/**");
|
||||
mapping.addConfigAttribute("ROLE_USER");
|
||||
|
||||
List mappings = new ArrayList(1);
|
||||
mappings.add(mapping);
|
||||
|
||||
PathBasedFilterInvocationDefinitionMap filterInvocationDefinitionSource = new PathBasedFilterInvocationDefinitionMap();
|
||||
filterInvocationDefinitionSource
|
||||
.setConvertUrlToLowercaseBeforeComparison(true);
|
||||
FilterInvocationDefinitionDecorator decorator = new FilterInvocationDefinitionDecorator(
|
||||
filterInvocationDefinitionSource);
|
||||
decorator.setMappings(mappings);
|
||||
|
||||
FilterSecurityInterceptor filter = new FilterSecurityInterceptor();
|
||||
filter.setObjectDefinitionSource(filterInvocationDefinitionSource);
|
||||
|
||||
MockFilterChain filterChain = new MockFilterChain();
|
||||
filterChain.expectToProceed = true;
|
||||
|
||||
FilterInvocation fi = new FilterInvocation(
|
||||
new MockHttpServletRequest(), new MockHttpServletResponse(),
|
||||
filterChain);
|
||||
filter.invoke(fi);
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockFilterChain implements FilterChain {
|
||||
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed 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.acegisecurity.intercept.web;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.acegisecurity.ConfigAttributeDefinition;
|
||||
|
||||
/**
|
||||
* Mock for {@link FilterInvocationDefinitionMap}
|
||||
*
|
||||
* @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
|
||||
* @version $Id: MockFilterInvocationDefinitionSource.java 1496 2006-05-23
|
||||
* 13:38:33Z benalex $
|
||||
*/
|
||||
public class MockFilterInvocationDefinition implements FilterInvocationDefinition {
|
||||
|
||||
private Map secureUrls = new HashMap();
|
||||
|
||||
private boolean convertUrlToLowercaseBeforeComparison = false;
|
||||
|
||||
public void addSecureUrl(String expression, ConfigAttributeDefinition attr) {
|
||||
secureUrls.put(expression, attr);
|
||||
}
|
||||
|
||||
public boolean isConvertUrlToLowercaseBeforeComparison() {
|
||||
return convertUrlToLowercaseBeforeComparison;
|
||||
}
|
||||
|
||||
public void setConvertUrlToLowercaseBeforeComparison(boolean convertUrlToLowercaseBeforeComparison) {
|
||||
this.convertUrlToLowercaseBeforeComparison = convertUrlToLowercaseBeforeComparison;
|
||||
}
|
||||
|
||||
public ConfigAttributeDefinition getSecureUrl(String expression) {
|
||||
return (ConfigAttributeDefinition) secureUrls.get(expression);
|
||||
}
|
||||
|
||||
public ConfigAttributeDefinition getAttributes(Object object) throws IllegalArgumentException {
|
||||
return (ConfigAttributeDefinition) secureUrls.get(object);
|
||||
}
|
||||
|
||||
public Iterator getConfigAttributeDefinitions() {
|
||||
return secureUrls.values().iterator();
|
||||
}
|
||||
|
||||
public boolean supports(Class clazz) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -24,7 +24,7 @@ import java.util.Vector;
|
||||
|
||||
|
||||
/**
|
||||
* Mock for {@link FilterInvocationDefinitionSource}
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
|
||||
+40
-33
@@ -45,6 +45,14 @@ public class PathBasedFilterDefinitionMapTests extends TestCase {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(PathBasedFilterDefinitionMapTests.class);
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testConvertUrlToLowercaseIsFalseByDefault() {
|
||||
PathBasedFilterInvocationDefinitionMap map = new PathBasedFilterInvocationDefinitionMap();
|
||||
assertFalse(map.isConvertUrlToLowercaseBeforeComparison());
|
||||
@@ -65,7 +73,14 @@ public class PathBasedFilterDefinitionMapTests extends TestCase {
|
||||
def.addConfigAttribute(new SecurityConfig("ROLE_ONE"));
|
||||
map.addSecureUrl("/secure/super/**", def);
|
||||
|
||||
FilterInvocation fi = createFilterinvocation("/SeCuRE/super/somefile.html");
|
||||
// Build a HTTP request
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestURI(null);
|
||||
|
||||
MockHttpServletRequest req = request;
|
||||
req.setServletPath("/SeCuRE/super/somefile.html");
|
||||
|
||||
FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new MockFilterChain());
|
||||
|
||||
ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl());
|
||||
assertEquals(def, response);
|
||||
@@ -79,7 +94,14 @@ public class PathBasedFilterDefinitionMapTests extends TestCase {
|
||||
def.addConfigAttribute(new SecurityConfig("ROLE_ONE"));
|
||||
map.addSecureUrl("/secure/super/**", def);
|
||||
|
||||
FilterInvocation fi = createFilterinvocation("/SeCuRE/super/somefile.html");
|
||||
// Build a HTTP request
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestURI(null);
|
||||
|
||||
MockHttpServletRequest req = request;
|
||||
req.setServletPath("/SeCuRE/super/somefile.html");
|
||||
|
||||
FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new MockFilterChain());
|
||||
|
||||
ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl());
|
||||
assertEquals(null, response);
|
||||
@@ -93,7 +115,14 @@ public class PathBasedFilterDefinitionMapTests extends TestCase {
|
||||
def.addConfigAttribute(new SecurityConfig("ROLE_ONE"));
|
||||
map.addSecureUrl("/secure/super/**", def);
|
||||
|
||||
FilterInvocation fi = createFilterinvocation("/secure/super/somefile.html");
|
||||
// Build a HTTP request
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestURI(null);
|
||||
|
||||
MockHttpServletRequest req = request;
|
||||
req.setServletPath("/secure/super/somefile.html");
|
||||
|
||||
FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new MockFilterChain());
|
||||
|
||||
ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl());
|
||||
assertEquals(def, response);
|
||||
@@ -107,38 +136,16 @@ public class PathBasedFilterDefinitionMapTests extends TestCase {
|
||||
def.addConfigAttribute(new SecurityConfig("ROLE_ONE"));
|
||||
map.addSecureUrl("/someAdminPage.html**", def);
|
||||
|
||||
FilterInvocation fi = createFilterinvocation("/someAdminPage.html?a=/test");
|
||||
// Build a HTTP request
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestURI(null);
|
||||
|
||||
MockHttpServletRequest req = request;
|
||||
req.setServletPath("/someAdminPage.html?a=/test");
|
||||
|
||||
FilterInvocation fi = new FilterInvocation(req, new MockHttpServletResponse(), new MockFilterChain());
|
||||
|
||||
ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl());
|
||||
assertEquals(def, response); // see SEC-161 (it should truncate after ? sign)
|
||||
}
|
||||
|
||||
/** Check fixes for SEC-321 */
|
||||
public void testExtraQuestionMarkStillMatches() {
|
||||
PathBasedFilterInvocationDefinitionMap map = new PathBasedFilterInvocationDefinitionMap();
|
||||
assertFalse(map.isConvertUrlToLowercaseBeforeComparison());
|
||||
|
||||
ConfigAttributeDefinition def = new ConfigAttributeDefinition();
|
||||
def.addConfigAttribute(new SecurityConfig("ROLE_ONE"));
|
||||
map.addSecureUrl("/someAdminPage.html*", def);
|
||||
|
||||
FilterInvocation fi = createFilterinvocation("/someAdminPage.html?x=2/aa?y=3");
|
||||
|
||||
ConfigAttributeDefinition response = map.lookupAttributes(fi.getRequestUrl());
|
||||
assertEquals(def, response);
|
||||
|
||||
fi = createFilterinvocation("/someAdminPage.html??");
|
||||
|
||||
response = map.lookupAttributes(fi.getRequestUrl());
|
||||
assertEquals(def, response);
|
||||
}
|
||||
|
||||
private FilterInvocation createFilterinvocation(String path) {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestURI(null);
|
||||
|
||||
request.setServletPath(path);
|
||||
|
||||
return new FilterInvocation(request, new MockHttpServletResponse(), new MockFilterChain());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -341,7 +341,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown AuthenticationServiceException");
|
||||
} catch (AuthenticationServiceException expected) {
|
||||
assertEquals("UserDetailsService returned null, which is an interface contract violation",
|
||||
assertEquals("AuthenticationDao returned null, which is an interface contract violation",
|
||||
expected.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -417,10 +417,10 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
||||
|
||||
public void testStartupSuccess() throws Exception {
|
||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||
UserDetailsService userDetailsService = new MockAuthenticationDaoUserMarissa();
|
||||
provider.setUserDetailsService(userDetailsService);
|
||||
UserDetailsService dao = new MockAuthenticationDaoUserMarissa();
|
||||
provider.setUserDetailsService(dao);
|
||||
provider.setUserCache(new MockUserCache());
|
||||
assertEquals(userDetailsService, provider.getUserDetailsService());
|
||||
assertEquals(dao, provider.getUserDetailsService());
|
||||
provider.afterPropertiesSet();
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ public class LdapAuthenticationProviderTests extends TestCase {
|
||||
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(new MockAuthenticator(),
|
||||
new MockAuthoritiesPopulator());
|
||||
|
||||
assertNotNull(ldapProvider.getAuthoritiesPopulator());
|
||||
assertNotNull(ldapProvider.getAuthoritiesPoulator());
|
||||
|
||||
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("bob", "bobspassword");
|
||||
UserDetails user = ldapProvider.retrieveUser("bob", authRequest);
|
||||
|
||||
+14
@@ -70,12 +70,26 @@ public class RememberMeAuthenticationTokenTests extends TestCase {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new RememberMeAuthenticationToken("key", "Test", null);
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new RememberMeAuthenticationToken("key", "Test", new GrantedAuthority[] {null});
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
try {
|
||||
new RememberMeAuthenticationToken("key", "Test", new GrantedAuthority[] {});
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testEqualsWhenEqual() {
|
||||
|
||||
-430
@@ -1,430 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed 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.acegisecurity.providers.siteminder;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.acegisecurity.AccountExpiredException;
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.AuthenticationServiceException;
|
||||
import org.acegisecurity.BadCredentialsException;
|
||||
import org.acegisecurity.CredentialsExpiredException;
|
||||
import org.acegisecurity.DisabledException;
|
||||
import org.acegisecurity.GrantedAuthority;
|
||||
import org.acegisecurity.GrantedAuthorityImpl;
|
||||
import org.acegisecurity.LockedException;
|
||||
import org.acegisecurity.providers.TestingAuthenticationToken;
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
import org.acegisecurity.providers.dao.UserCache;
|
||||
import org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache;
|
||||
import org.acegisecurity.providers.dao.cache.NullUserCache;
|
||||
import org.acegisecurity.userdetails.User;
|
||||
import org.acegisecurity.userdetails.UserDetails;
|
||||
import org.acegisecurity.userdetails.UserDetailsService;
|
||||
import org.acegisecurity.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.DataRetrievalFailureException;
|
||||
|
||||
/**
|
||||
* Tests {@link SiteminderAuthenticationProvider}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id: SiteminderAuthenticationProviderTests.java 1582 2006-07-15 15:18:51Z smccrory $
|
||||
*/
|
||||
public class SiteminderAuthenticationProviderTests extends TestCase {
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(SiteminderAuthenticationProviderTests.class);
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsIfAccountExpired() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", "opal");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserPeterAccountExpired());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown AccountExpiredException");
|
||||
} catch (AccountExpiredException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsIfAccountLocked() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", "opal");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserPeterAccountLocked());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown LockedException");
|
||||
} catch (LockedException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsIfCredentialsExpired() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", "opal");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserPeterCredentialsExpired());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown CredentialsExpiredException");
|
||||
} catch (CredentialsExpiredException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsIfUserDisabled() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("peter", "opal");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserPeter());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown DisabledException");
|
||||
} catch (DisabledException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsWhenUserDetailsServiceHasBackendFailure() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceSimulateBackendError());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown AuthenticationServiceException");
|
||||
} catch (AuthenticationServiceException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsWithEmptyUsername() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(null, "koala");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserMarissa());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown BadCredentialsException");
|
||||
} catch (BadCredentialsException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundExceptionFalse() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("INVALID_USER", "koala");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setHideUserNotFoundExceptions(false); // we want UsernameNotFoundExceptions
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserMarissa());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown UsernameNotFoundException");
|
||||
} catch (UsernameNotFoundException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsWithInvalidUsernameAndHideUserNotFoundExceptionsWithDefaultOfTrue() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("INVALID_USER", "koala");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
assertTrue(provider.isHideUserNotFoundExceptions());
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserMarissa());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown BadCredentialsException");
|
||||
} catch (BadCredentialsException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticateFailsWithMixedCaseUsernameIfDefaultChanged() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("MaRiSSA", "koala");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserMarissa());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown BadCredentialsException");
|
||||
} catch (BadCredentialsException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAuthenticates() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala");
|
||||
token.setDetails("192.168.0.1");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserMarissa());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
Authentication result = provider.authenticate(token);
|
||||
|
||||
if (!(result instanceof UsernamePasswordAuthenticationToken)) {
|
||||
fail("Should have returned instance of UsernamePasswordAuthenticationToken");
|
||||
}
|
||||
|
||||
UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result;
|
||||
assertEquals(User.class, castResult.getPrincipal().getClass());
|
||||
assertEquals("koala", castResult.getCredentials());
|
||||
assertEquals("ROLE_ONE", castResult.getAuthorities()[0].getAuthority());
|
||||
assertEquals("ROLE_TWO", castResult.getAuthorities()[1].getAuthority());
|
||||
assertEquals("192.168.0.1", castResult.getDetails());
|
||||
}
|
||||
|
||||
public void testAuthenticatesASecondTime() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserMarissa());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
|
||||
Authentication result = provider.authenticate(token);
|
||||
|
||||
if (!(result instanceof UsernamePasswordAuthenticationToken)) {
|
||||
fail("Should have returned instance of UsernamePasswordAuthenticationToken");
|
||||
}
|
||||
|
||||
// Now try to authenticate with the previous result (with its UserDetails)
|
||||
Authentication result2 = provider.authenticate(result);
|
||||
|
||||
if (!(result2 instanceof UsernamePasswordAuthenticationToken)) {
|
||||
fail("Should have returned instance of UsernamePasswordAuthenticationToken");
|
||||
}
|
||||
|
||||
assertEquals(result.getCredentials(), result2.getCredentials());
|
||||
}
|
||||
|
||||
public void testAuthenticatesWithForcePrincipalAsString() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserMarissa());
|
||||
provider.setUserCache(new MockUserCache());
|
||||
provider.setForcePrincipalAsString(true);
|
||||
|
||||
Authentication result = provider.authenticate(token);
|
||||
|
||||
if (!(result instanceof UsernamePasswordAuthenticationToken)) {
|
||||
fail("Should have returned instance of UsernamePasswordAuthenticationToken");
|
||||
}
|
||||
|
||||
UsernamePasswordAuthenticationToken castResult = (UsernamePasswordAuthenticationToken) result;
|
||||
assertEquals(String.class, castResult.getPrincipal().getClass());
|
||||
assertEquals("marissa", castResult.getPrincipal());
|
||||
}
|
||||
|
||||
public void testDetectsNullBeingReturnedFromUserDetailsService() {
|
||||
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("marissa", "koala");
|
||||
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceReturnsNull());
|
||||
|
||||
try {
|
||||
provider.authenticate(token);
|
||||
fail("Should have thrown AuthenticationServiceException");
|
||||
} catch (AuthenticationServiceException expected) {
|
||||
assertEquals("UserDetailsService returned null, which is an interface contract violation", expected
|
||||
.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGettersSetters() {
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
|
||||
provider.setUserCache(new EhCacheBasedUserCache());
|
||||
assertEquals(EhCacheBasedUserCache.class, provider.getUserCache().getClass());
|
||||
|
||||
assertFalse(provider.isForcePrincipalAsString());
|
||||
provider.setForcePrincipalAsString(true);
|
||||
assertTrue(provider.isForcePrincipalAsString());
|
||||
}
|
||||
|
||||
public void testStartupFailsIfNoUserDetailsService() throws Exception {
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
|
||||
try {
|
||||
provider.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testStartupFailsIfNoUserCacheSet() throws Exception {
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
provider.setUserDetailsService(new MockUserDetailsServiceUserMarissa());
|
||||
assertEquals(NullUserCache.class, provider.getUserCache().getClass());
|
||||
provider.setUserCache(null);
|
||||
|
||||
try {
|
||||
provider.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testStartupSuccess() throws Exception {
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
UserDetailsService userDetailsService = new MockUserDetailsServiceUserMarissa();
|
||||
provider.setUserDetailsService(userDetailsService);
|
||||
provider.setUserCache(new MockUserCache());
|
||||
assertEquals(userDetailsService, provider.getUserDetailsService());
|
||||
provider.afterPropertiesSet();
|
||||
assertTrue(true);
|
||||
}
|
||||
|
||||
public void testSupports() {
|
||||
SiteminderAuthenticationProvider provider = new SiteminderAuthenticationProvider();
|
||||
assertTrue(provider.supports(UsernamePasswordAuthenticationToken.class));
|
||||
assertTrue(!provider.supports(TestingAuthenticationToken.class));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockUserDetailsServiceReturnsNull implements UserDetailsService {
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private class MockUserDetailsServiceSimulateBackendError implements UserDetailsService {
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
|
||||
throw new DataRetrievalFailureException("This mock simulator is designed to fail");
|
||||
}
|
||||
}
|
||||
|
||||
private class MockUserDetailsServiceUserMarissa implements UserDetailsService {
|
||||
private String password = "koala";
|
||||
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
|
||||
if ("marissa".equals(username)) {
|
||||
return new User("marissa", password, true, true, true, true, new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO") });
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Could not find: " + username);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
|
||||
private class MockUserDetailsServiceUserMarissaWithSalt implements UserDetailsService {
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
|
||||
if ("marissa".equals(username)) {
|
||||
return new User("marissa", "koala{SYSTEM_SALT_VALUE}", true, true, true, true, new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO") });
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Could not find: " + username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MockUserDetailsServiceUserPeter implements UserDetailsService {
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
|
||||
if ("peter".equals(username)) {
|
||||
return new User("peter", "opal", false, true, true, true, new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO") });
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Could not find: " + username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MockUserDetailsServiceUserPeterAccountExpired implements UserDetailsService {
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
|
||||
if ("peter".equals(username)) {
|
||||
return new User("peter", "opal", true, false, true, true, new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO") });
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Could not find: " + username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MockUserDetailsServiceUserPeterAccountLocked implements UserDetailsService {
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
|
||||
if ("peter".equals(username)) {
|
||||
return new User("peter", "opal", true, true, true, false, new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO") });
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Could not find: " + username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MockUserDetailsServiceUserPeterCredentialsExpired implements UserDetailsService {
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
|
||||
if ("peter".equals(username)) {
|
||||
return new User("peter", "opal", true, true, false, true, new GrantedAuthority[] {
|
||||
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO") });
|
||||
} else {
|
||||
throw new UsernameNotFoundException("Could not find: " + username);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MockUserCache implements UserCache {
|
||||
private Map cache = new HashMap();
|
||||
|
||||
public UserDetails getUserFromCache(String username) {
|
||||
return (User) cache.get(username);
|
||||
}
|
||||
|
||||
public void putUserInCache(UserDetails user) {
|
||||
cache.put(user.getUsername(), user);
|
||||
}
|
||||
|
||||
public void removeUserFromCache(String username) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -197,13 +197,13 @@ public class ChannelDecisionManagerImplTests extends TestCase {
|
||||
Iterator iter = config.getConfigAttributes();
|
||||
|
||||
if (failIfCalled) {
|
||||
fail("Should not have called this channel processor: " + configAttribute);
|
||||
fail("Should not have called this channel processor");
|
||||
}
|
||||
|
||||
while (iter.hasNext()) {
|
||||
ConfigAttribute attr = (ConfigAttribute) iter.next();
|
||||
|
||||
if (attr.getAttribute().equals(configAttribute)) {
|
||||
if (attr.equals(configAttribute)) {
|
||||
invocation.getHttpResponse().sendRedirect("/redirected");
|
||||
|
||||
return;
|
||||
|
||||
@@ -70,7 +70,6 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
request.setScheme("http");
|
||||
request.setServerName("www.example.com");
|
||||
request.setRequestURI("/mycontext/j_mock_post");
|
||||
request.setContextPath("/mycontext");
|
||||
|
||||
return request;
|
||||
}
|
||||
@@ -155,27 +154,27 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
|
||||
// Setup our test object, to deny access
|
||||
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
|
||||
filter.setAuthenticationFailureUrl("/failed.jsp");
|
||||
filter.setAuthenticationFailureUrl("/myApp/failed.jsp");
|
||||
|
||||
// Test
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
|
||||
assertEquals("/mycontext/failed.jsp", response.getRedirectedUrl());
|
||||
assertEquals("/myApp/failed.jsp", response.getRedirectedUrl());
|
||||
assertNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
|
||||
//Prepare again, this time using the exception mapping
|
||||
filter = new MockAbstractProcessingFilter(new AccountExpiredException("You're account is expired"));
|
||||
filter.setAuthenticationFailureUrl("/failed.jsp");
|
||||
filter.setAuthenticationFailureUrl("/myApp/failed.jsp");
|
||||
|
||||
Properties exceptionMappings = filter.getExceptionMappings();
|
||||
exceptionMappings.setProperty(AccountExpiredException.class.getName(), "/accountExpired.jsp");
|
||||
exceptionMappings.setProperty(AccountExpiredException.class.getName(), "/myApp/accountExpired.jsp");
|
||||
filter.setExceptionMappings(exceptionMappings);
|
||||
response = new MockHttpServletResponse();
|
||||
|
||||
// Test
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
|
||||
assertEquals("/mycontext/accountExpired.jsp", response.getRedirectedUrl());
|
||||
assertEquals("/myApp/accountExpired.jsp", response.getRedirectedUrl());
|
||||
assertNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
@@ -200,7 +199,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
|
||||
// Test
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
|
||||
assertEquals("/logged_in.jsp", response.getRedirectedUrl());
|
||||
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
|
||||
}
|
||||
@@ -227,19 +226,6 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
assertEquals("/fail", filter.getAuthenticationFailureUrl());
|
||||
}
|
||||
|
||||
public void testDefaultUrlMuststartWithSlashOrHttpScheme() {
|
||||
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
|
||||
|
||||
filter.setDefaultTargetUrl("/acceptableRelativeUrl");
|
||||
filter.setDefaultTargetUrl("http://some.site.org/index.html");
|
||||
filter.setDefaultTargetUrl("https://some.site.org/index.html");
|
||||
|
||||
try {
|
||||
filter.setDefaultTargetUrl("missingSlash");
|
||||
fail("Shouldn't accept default target without leading slash");
|
||||
} catch (IllegalArgumentException expected) {}
|
||||
}
|
||||
|
||||
public void testIgnoresAnyServletPathOtherThanFilterProcessesUrl()
|
||||
throws Exception {
|
||||
// Setup our HTTP request
|
||||
@@ -283,7 +269,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
|
||||
// Test
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
|
||||
assertEquals("/logged_in.jsp", response.getRedirectedUrl());
|
||||
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
|
||||
}
|
||||
@@ -368,7 +354,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
|
||||
// Test
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
assertEquals("/mycontext/logged_in.jsp", response.getRedirectedUrl());
|
||||
assertEquals("/logged_in.jsp", response.getRedirectedUrl());
|
||||
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
assertEquals("test", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
|
||||
|
||||
@@ -411,7 +397,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
|
||||
// Test
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
assertEquals("/mycontext/foobar", response.getRedirectedUrl());
|
||||
assertEquals("/foobar", response.getRedirectedUrl());
|
||||
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
@@ -438,27 +424,6 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
/**
|
||||
* SEC-297 fix.
|
||||
*/
|
||||
public void testFullDefaultTargetUrlDoesNotHaveContextPathPrepended() throws Exception {
|
||||
MockHttpServletRequest request = createMockRequest();
|
||||
MockFilterConfig config = new MockFilterConfig(null, null);
|
||||
|
||||
MockFilterChain chain = new MockFilterChain(true);
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
// Setup our test object, to grant access
|
||||
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(true);
|
||||
filter.setFilterProcessesUrl("/j_mock_post");
|
||||
filter.setDefaultTargetUrl("http://monkeymachine.co.uk/");
|
||||
filter.setAlwaysUseDefaultTargetUrl(true);
|
||||
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
assertEquals("http://monkeymachine.co.uk/", response.getRedirectedUrl());
|
||||
assertNotNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockAbstractProcessingFilter extends AbstractProcessingFilter {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import junit.framework.TestCase;
|
||||
import javax.servlet.http.Cookie;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SavedCookieTests extends TestCase {
|
||||
public class SavedCookieTest extends TestCase {
|
||||
|
||||
Cookie cookie;
|
||||
SavedCookie savedCookie;
|
||||
@@ -1,22 +0,0 @@
|
||||
package org.acegisecurity.ui.savedrequest;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.acegisecurity.MockPortResolver;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
|
||||
public class SavedRequestTests extends TestCase {
|
||||
|
||||
public void testCaseInsensitveHeaders() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("USER-aGenT", "Mozilla");
|
||||
SavedRequest saved = new SavedRequest(request, new MockPortResolver(8080, 8443));
|
||||
assertEquals("Mozilla", saved.getHeaderValues("user-agent").next());
|
||||
}
|
||||
|
||||
public void testCaseInsensitveParameters() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addParameter("ThisIsATest", "Hi mom");
|
||||
SavedRequest saved = new SavedRequest(request, new MockPortResolver(8080, 8443));
|
||||
assertEquals("Hi mom", saved.getParameterValues("thisisatest")[0]);
|
||||
}
|
||||
}
|
||||
+25
-12
@@ -19,10 +19,13 @@ import junit.framework.TestCase;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.acegisecurity.MockAuthenticationManager;
|
||||
|
||||
import org.acegisecurity.ui.WebAuthenticationDetails;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* Tests SiteminderAuthenticationProcessingFilter.
|
||||
*
|
||||
@@ -33,18 +36,18 @@ import org.springframework.mock.web.MockHttpServletResponse;
|
||||
public class SiteminderAuthenticationProcessingFilterTests extends TestCase {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
/**
|
||||
* Basic constructor.
|
||||
*/
|
||||
/**
|
||||
* Basic constructor.
|
||||
*/
|
||||
public SiteminderAuthenticationProcessingFilterTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Argument constructor.
|
||||
*
|
||||
* @param arg0
|
||||
*/
|
||||
/**
|
||||
* Argument constructor.
|
||||
*
|
||||
* @param arg0
|
||||
*/
|
||||
public SiteminderAuthenticationProcessingFilterTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
@@ -83,15 +86,21 @@ public class SiteminderAuthenticationProcessingFilterTests extends TestCase {
|
||||
filter.setContinueChainBeforeSuccessfulAuthentication(true);
|
||||
assertTrue(filter.isContinueChainBeforeSuccessfulAuthentication());
|
||||
|
||||
filter.setDefaultTargetUrl("/bar");
|
||||
assertEquals("/bar", filter.getDefaultTargetUrl());
|
||||
filter.setDefaultTargetUrl("bar");
|
||||
assertEquals("bar", filter.getDefaultTargetUrl());
|
||||
|
||||
filter.setFilterProcessesUrl("foobar");
|
||||
assertEquals("foobar", filter.getFilterProcessesUrl());
|
||||
|
||||
filter.setFormPasswordParameterKey("passwordParamKey");
|
||||
assertEquals("passwordParamKey", filter.getFormPasswordParameterKey());
|
||||
|
||||
filter.setFormUsernameParameterKey("usernameParamKey");
|
||||
assertEquals("usernameParamKey", filter.getFormUsernameParameterKey());
|
||||
|
||||
filter.setSiteminderPasswordHeaderKey("passwordHeaderKey");
|
||||
assertEquals("passwordHeaderKey", filter.getSiteminderPasswordHeaderKey());
|
||||
|
||||
filter.setSiteminderUsernameHeaderKey("usernameHeaderKey");
|
||||
assertEquals("usernameHeaderKey", filter.getSiteminderUsernameHeaderKey());
|
||||
}
|
||||
@@ -122,7 +131,8 @@ public class SiteminderAuthenticationProcessingFilterTests extends TestCase {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testFormNullPasswordHandledGracefully() throws Exception {
|
||||
public void testFormNullPasswordHandledGracefully()
|
||||
throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addParameter(SiteminderAuthenticationProcessingFilter.ACEGI_SECURITY_FORM_USERNAME_KEY, "marissa");
|
||||
|
||||
@@ -141,7 +151,8 @@ public class SiteminderAuthenticationProcessingFilterTests extends TestCase {
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testFormNullUsernameHandledGracefully() throws Exception {
|
||||
public void testFormNullUsernameHandledGracefully()
|
||||
throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addParameter(SiteminderAuthenticationProcessingFilter.ACEGI_SECURITY_FORM_PASSWORD_KEY, "koala");
|
||||
|
||||
@@ -175,6 +186,7 @@ public class SiteminderAuthenticationProcessingFilterTests extends TestCase {
|
||||
filter.setAuthenticationManager(authMgrThatGrantsAccess);
|
||||
|
||||
filter.setSiteminderUsernameHeaderKey("SM_USER");
|
||||
filter.setSiteminderPasswordHeaderKey("SM_USER");
|
||||
filter.init(null);
|
||||
|
||||
// Requests for an unknown URL should NOT require (re)authentication
|
||||
@@ -208,6 +220,7 @@ public class SiteminderAuthenticationProcessingFilterTests extends TestCase {
|
||||
SiteminderAuthenticationProcessingFilter filter = new SiteminderAuthenticationProcessingFilter();
|
||||
filter.setAuthenticationManager(authMgr);
|
||||
filter.setSiteminderUsernameHeaderKey("SM_USER");
|
||||
filter.setSiteminderPasswordHeaderKey("SM_USER");
|
||||
filter.init(null);
|
||||
|
||||
Authentication result = filter.attemptAuthentication(request);
|
||||
|
||||
@@ -79,17 +79,4 @@ public class LdapUserDetailsMapperTests extends TestCase {
|
||||
|
||||
assertEquals(0, user.getGrantedAuthorities().length);
|
||||
}
|
||||
|
||||
public void testPasswordAttributeIsMappedCorrectly() throws Exception {
|
||||
LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();
|
||||
|
||||
mapper.setPasswordAttributeName("myappsPassword");
|
||||
BasicAttributes attrs = new BasicAttributes();
|
||||
attrs.put(new BasicAttribute("myappsPassword", "mypassword".getBytes()));
|
||||
|
||||
LdapUserDetails user =
|
||||
((LdapUserDetailsImpl.Essence) mapper.mapAttributes("cn=someName", attrs)).createUserDetails();
|
||||
|
||||
assertEquals("mypassword", user.getPassword());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed 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.acegisecurity.util;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.acegisecurity.util.EncryptionUtils.EncryptionException;
|
||||
|
||||
/**
|
||||
* JUnit tests for EncryptionUtils.
|
||||
*
|
||||
* @author Alan Stewart
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class EncryptionUtilsTests extends TestCase {
|
||||
private final static String STRING_TO_ENCRYPT = "Alan K Stewart";
|
||||
private final static String ENCRYPTION_KEY = "123456789012345678901234567890";
|
||||
|
||||
public void testEncryptsUsingDESEde() throws EncryptionException {
|
||||
final String encryptedString = EncryptionUtils.encrypt(ENCRYPTION_KEY, STRING_TO_ENCRYPT);
|
||||
assertEquals("3YIE8sIbaEoqGZZrHamFGQ==", encryptedString);
|
||||
}
|
||||
|
||||
public void testEncryptionKeyCanContainLetters() throws EncryptionException {
|
||||
final String encryptedString = EncryptionUtils.encrypt("ASDF asdf 1234 8983 jklasdf J2Jaf8", STRING_TO_ENCRYPT);
|
||||
assertEquals("v4+DQoClx6qm5tJwBcRrkw==", encryptedString);
|
||||
}
|
||||
|
||||
public void testDecryptsUsingDESEde() throws EncryptionException {
|
||||
final String encryptedString = "3YIE8sIbaEoqGZZrHamFGQ==";
|
||||
final String decryptedString = EncryptionUtils.decrypt(ENCRYPTION_KEY, encryptedString);
|
||||
assertEquals(STRING_TO_ENCRYPT, decryptedString);
|
||||
}
|
||||
|
||||
public void testCantEncryptWithNullEncryptionKey() throws EncryptionException {
|
||||
try {
|
||||
EncryptionUtils.encrypt(null, "");
|
||||
fail("Should have thrown IAE");
|
||||
} catch (final IllegalArgumentException e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCantEncryptWithEmptyEncryptionKey() throws EncryptionException {
|
||||
try {
|
||||
EncryptionUtils.encrypt("", "");
|
||||
fail("Should have thrown IAE");
|
||||
} catch (final IllegalArgumentException e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCantEncryptWithShortEncryptionKey() throws EncryptionException {
|
||||
try {
|
||||
EncryptionUtils.encrypt("01234567890123456789012", "");
|
||||
fail("Should have thrown IAE");
|
||||
} catch (final IllegalArgumentException e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCantDecryptWithEmptyString() throws EncryptionException {
|
||||
try {
|
||||
EncryptionUtils.decrypt(ENCRYPTION_KEY, "");
|
||||
fail("Should have thrown IAE");
|
||||
} catch (final IllegalArgumentException e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCantEncryptWithEmptyString() throws EncryptionException {
|
||||
try {
|
||||
EncryptionUtils.encrypt(ENCRYPTION_KEY, "");
|
||||
fail("Should have thrown IAE");
|
||||
} catch (final IllegalArgumentException e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCantEncryptWithNullString() throws EncryptionException {
|
||||
try {
|
||||
EncryptionUtils.encrypt(ENCRYPTION_KEY, null);
|
||||
fail("Should have thrown IAE");
|
||||
} catch (final IllegalArgumentException e) {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void testEncryptAndDecrypt() throws EncryptionException {
|
||||
final String stringToEncrypt = "Alan Stewart";
|
||||
final String encryptedString = EncryptionUtils.encrypt(ENCRYPTION_KEY, stringToEncrypt);
|
||||
final String decryptedString = EncryptionUtils.decrypt(ENCRYPTION_KEY, encryptedString);
|
||||
assertEquals(stringToEncrypt, decryptedString);
|
||||
}
|
||||
}
|
||||
@@ -21,17 +21,23 @@ import org.acegisecurity.AuthorizationServiceException;
|
||||
import org.acegisecurity.ConfigAttributeDefinition;
|
||||
import org.acegisecurity.MockAclManager;
|
||||
import org.acegisecurity.SecurityConfig;
|
||||
|
||||
import org.acegisecurity.acl.AclEntry;
|
||||
import org.acegisecurity.acl.AclManager;
|
||||
import org.acegisecurity.acl.basic.MockAclObjectIdentity;
|
||||
import org.acegisecurity.acl.basic.SimpleAclEntry;
|
||||
|
||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.acegisecurity.util.SimpleMethodInvocation;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link BasicAclEntryVoter}.
|
||||
*
|
||||
@@ -445,40 +451,6 @@ public class BasicAclEntryVoterTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetRequirePermissionFromString() {
|
||||
assertPermission("NOTHING", SimpleAclEntry.NOTHING);
|
||||
assertPermission("ADMINISTRATION", SimpleAclEntry.ADMINISTRATION);
|
||||
assertPermission("READ", SimpleAclEntry.READ);
|
||||
assertPermission("WRITE", SimpleAclEntry.WRITE);
|
||||
assertPermission("CREATE", SimpleAclEntry.CREATE);
|
||||
assertPermission("DELETE", SimpleAclEntry.DELETE);
|
||||
assertPermission(new String[] { "WRITE", "CREATE" }, new int[] { SimpleAclEntry.WRITE, SimpleAclEntry.CREATE });
|
||||
}
|
||||
|
||||
public void testSetRequirePermissionFromStringWrongValues() {
|
||||
BasicAclEntryVoter voter = new BasicAclEntryVoter();
|
||||
try {
|
||||
voter.setRequirePermissionFromString(new String[] { "X" });
|
||||
fail(IllegalArgumentException.class.getName() + " must have been thrown.");
|
||||
} catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private void assertPermission(String text, int value) {
|
||||
assertPermission(new String[] { text }, new int[] { value });
|
||||
}
|
||||
|
||||
private void assertPermission(String[] text, int[] value) {
|
||||
BasicAclEntryVoter voter = new BasicAclEntryVoter();
|
||||
voter.setRequirePermissionFromString(text);
|
||||
assertEquals("Test incorreclty coded", value.length, text.length);
|
||||
assertEquals(value.length, voter.getRequirePermission().length);
|
||||
for (int i = 0; i < value.length; i++) {
|
||||
assertEquals(value[i], voter.getRequirePermission()[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
private class MockAclEntry implements AclEntry {
|
||||
|
||||
+64
-50
@@ -26,7 +26,7 @@
|
||||
|
||||
<subtitle>Reference Documentation</subtitle>
|
||||
|
||||
<releaseinfo>1.0.2</releaseinfo>
|
||||
<releaseinfo>1.0.0</releaseinfo>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
@@ -117,6 +117,19 @@
|
||||
<chapter id="introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<sect1 id="before-you-begin">
|
||||
<title>Before You Begin</title>
|
||||
|
||||
<para>For your security, each official release JAR of Acegi Security
|
||||
has been signed by the project leader. This does not in any way alter
|
||||
the liability disclaimer contained in the License, but it does ensure
|
||||
you are using a properly reviewed, official build of Acegi Security.
|
||||
Please refer to the <literal>readme.txt</literal> file in the root of
|
||||
the release distribution for instructions on how to validate the JARs
|
||||
are correctly signed, and which certificate has been used to sign
|
||||
them.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="what-is-acegi-security">
|
||||
<title>What is Acegi Security?</title>
|
||||
|
||||
@@ -1294,15 +1307,6 @@ if (obj instanceof UserDetails) {
|
||||
wired up by default to many Acegi Security beans. Please refer to the
|
||||
JavaDocs for <literal>PortResolverImpl</literal> for further
|
||||
details.</para>
|
||||
|
||||
<para>You should note that using a secure channel is recommended if
|
||||
usernames and passwords are to be kept secure during the login
|
||||
process. If you do decide to use
|
||||
<literal>ChannelProcessingFilter</literal> with form-based login,
|
||||
please ensure that your login page is set to
|
||||
<literal>REQUIRES_SECURE_CHANNEL</literal>, and that the
|
||||
<literal>AuthenticationProcessingFilterEntryPoint.forceHttps</literal>
|
||||
property is <literal>true</literal>.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="channel-security-conclusion">
|
||||
@@ -1369,7 +1373,7 @@ if (obj instanceof UserDetails) {
|
||||
<literal>web.xml</literal>:</para>
|
||||
|
||||
<para><programlisting><taglib>
|
||||
<taglib-uri>http://acegisecurity.org/authz</taglib-uri>
|
||||
<taglib-uri>http://acegisecurity.sf.net/authz</taglib-uri>
|
||||
<taglib-location>/WEB-INF/authz.tld</taglib-location>
|
||||
</taglib> </programlisting></para>
|
||||
</sect1>
|
||||
@@ -1416,7 +1420,7 @@ if (obj instanceof UserDetails) {
|
||||
this:</para>
|
||||
|
||||
<para><programlisting><filter>
|
||||
<filter-name>Acegi Filter Chain Proxy</filter-name>
|
||||
<filter-name>Acegi HTTP Request Security Filter</filter-name>
|
||||
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
|
||||
<init-param>
|
||||
<param-name>targetClass</param-name>
|
||||
@@ -1786,11 +1790,9 @@ if (obj instanceof UserDetails) {
|
||||
<para>In addition, you will need to add the
|
||||
<literal>org.acegisecurity.concurrent.ConcurrentSessionFilter</literal>
|
||||
to your <literal>FilterChainProxy</literal>. The
|
||||
ConcurrentSessionFilter requires two properties,
|
||||
ConcurrentSessionFilter requires only one property,
|
||||
<literal>sessionRegistry</literal>, which generally points to an
|
||||
instance of <literal>SessionRegistryImpl</literal>, and
|
||||
<literal>expiredUrl</literal>, which points to the page to display
|
||||
when a session has expired.</para>
|
||||
instance of <literal>SessionRegistryImpl</literal>.</para>
|
||||
|
||||
<para>The <literal>web.xml</literal>
|
||||
<literal>HttpSessionEventPublisher</literal> causes an
|
||||
@@ -2118,8 +2120,7 @@ if (obj instanceof UserDetails) {
|
||||
Associates.</para>
|
||||
|
||||
<para>Acegi Security provides a filter,
|
||||
<literal>SiteminderAuthenticationProcessingFilter</literal> and
|
||||
provider, <literal>SiteminderAuthenticationProvider</literal> that can
|
||||
<literal>SiteminderAuthenticationProcessingFilter</literal>) that can
|
||||
be used to process requests that have been pre-authenticated by
|
||||
Siteminder. This filter assumes that you're using Siteminder for
|
||||
<emphasis>authentication</emphasis>, and that you're using Acegi
|
||||
@@ -2127,14 +2128,13 @@ if (obj instanceof UserDetails) {
|
||||
for <emphasis>authorization</emphasis> is not yet directly supported
|
||||
by Acegi Security.</para>
|
||||
|
||||
<para>When using Siteminder, an agent is setup on your web server to
|
||||
intercept a principal's first call to your application. The agent
|
||||
redirects the web request to a single sign-on login page, and once
|
||||
authenticated, your application receives the request. Inside the HTTP
|
||||
request is a header - such as <literal>SM_USER</literal> - which
|
||||
identifies the authenticated principal (please refer to your
|
||||
organization's "single sign-on" group for header details in your
|
||||
particular configuration).</para>
|
||||
<para>In Siteminder, an agent is setup on your web server to intercept
|
||||
a principal's first call to your application. The agent redirect the
|
||||
web request to a single sign on login page, and then your application
|
||||
receives the request. Inside the HTTP headers is a header - such as
|
||||
<literal>SM_USER</literal> - which identifies the authenticated
|
||||
principal. Please refer to your organization's "single sign-on" group
|
||||
for header details in your particular configuration.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="siteminder-config">
|
||||
@@ -2142,9 +2142,9 @@ if (obj instanceof UserDetails) {
|
||||
|
||||
<para>The first step in setting up Acegi Security's Siteminder support
|
||||
is to define the authentication mechanism that will inspect the HTTP
|
||||
header discussed earlier. It will be responsible for generating a
|
||||
<literal>UsernamePasswordAuthenticationToken</literal> that is later
|
||||
sent to the <literal>SiteminderAuthenticationProvider</literal>. Let's
|
||||
header discussed earlier. It will then generate a
|
||||
<literal>UsernamePasswordAuthenticationToken</literal> that can later
|
||||
on be sent to the <literal>DaoAuthenticationProvider</literal>. Let's
|
||||
look at an example:</para>
|
||||
|
||||
<para><programlisting><bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.SiteminderAuthenticationProcessingFilter">
|
||||
@@ -2153,37 +2153,51 @@ if (obj instanceof UserDetails) {
|
||||
<property name="defaultTargetUrl"><value>/security.do?method=getMainMenu</value></property>
|
||||
<property name="filterProcessesUrl"><value>/j_acegi_security_check</value></property>
|
||||
<property name="siteminderUsernameHeaderKey"><value>SM_USER</value></property>
|
||||
<property name="formUsernameParameterKey"><value>j_username</value></property>
|
||||
<property name="siteminderPasswordHeaderKey"><value>SM_USER</value></property>
|
||||
</bean></programlisting></para>
|
||||
|
||||
<para>In our example above, the bean is being provided an
|
||||
<literal>AuthenticationManager</literal>, as is normally needed by
|
||||
authentication mechanisms. Several URLs are also specified, with the
|
||||
values being self-explanatory. It's important to also specify the HTTP
|
||||
header that Acegi Security should inspect. If you additionally want to
|
||||
support form-based authentication (i.e. in your development
|
||||
environment where Siteminder is not installed), specify the form's
|
||||
username parameter as well - just don't do this in production!</para>
|
||||
headers that Acegi Security should inspect. Most people won't need the
|
||||
password value since Siteminder has already authenticated the user, so
|
||||
it's typical to use the same header for both.</para>
|
||||
|
||||
<para>Note that you'll need a
|
||||
<literal><literal>SiteminderAuthenticationProvider</literal></literal>
|
||||
<literal><literal>DaoAuthenticationProvider</literal></literal>
|
||||
configured against your <literal>ProviderManager</literal> in order to
|
||||
use the Siteminder authentication mechanism. Normally an
|
||||
<literal>AuthenticationProvider</literal> expects the password
|
||||
use the Siteminder authentication mechanism. Normally a
|
||||
<literal>DaoAuthenticationProvider</literal> expects the password
|
||||
property to match what it retrieves from the
|
||||
<literal>UserDetailsSource</literal>, but in this case, authentication
|
||||
has already been handled by Siteminder, so password property is not
|
||||
even relevant. This may sound like a security weakness, but remember
|
||||
that users have to authenticate with Siteminder before your
|
||||
application ever receives the requests, so the purpose of your custom
|
||||
<literal>UserDetailsService</literal> should simply be to build the
|
||||
complete <literal>Authentication</literal> object (ie with suitable
|
||||
<literal>UserDetailsSource</literal>. In this case, authentication has
|
||||
already been handled by Siteminder and you've specified the same HTTP
|
||||
header for both username and password. As such, you must modify the
|
||||
code of <literal>DaoAuthenticationProvider</literal> to simply make
|
||||
sure the username and password values match. This may sound like a
|
||||
security weakness, but remember that users have to authenticate with
|
||||
Siteminder before your application ever receives the requests, so the
|
||||
purpose of your custom <literal>DaoAuthenticationProvider</literal>
|
||||
should simply be to build the complete
|
||||
<literal>Authentication</literal> object (ie with suitable
|
||||
<literal>GrantedAuthority[]</literal>s).</para>
|
||||
|
||||
<para>Advanced tip and word to the wise: If you additionally want to
|
||||
support form-based authentication in your development environment
|
||||
(where Siteminder is typically not installed), specify the form's
|
||||
username parameter as well. Just don't do this in production!</para>
|
||||
<para>Advanced tip and word to the wise: the
|
||||
<literal>SiteminderAuthenticationProcessingFilter</literal> actually
|
||||
extends <literal>AuthenticationProcessingFilter</literal> and thus
|
||||
additionally supports form validation. If you configure the filter to
|
||||
support both, and code your
|
||||
<literal>daoAuthenticationProvider</literal> to match the username and
|
||||
passwords as described above, you'll potentially defeat any security
|
||||
you have in place if the web server's Siteminder agent is deactivated.
|
||||
Don't do this, especially in production!</para>
|
||||
|
||||
<para>TODO: We should write a dedicated
|
||||
<literal>AuthenticationProvider</literal> rather than require users to
|
||||
modify their <literal>DaoAuthenticationProvider</literal>. Also review
|
||||
the mixed use of SiteminderAuthenticationProcessingFilter, as it's
|
||||
inconsistent with the rest of Acegi Security's authentication
|
||||
mechanisms which are high cohesion.</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
@@ -3126,14 +3140,14 @@ key: A private key to prevent modification of the remember-me token
|
||||
<para>A typical configuration, using some of the beans we've discussed
|
||||
above, might look like this: <programlisting>
|
||||
<bean id="initialDirContextFactory"
|
||||
class="org.acegisecurity.ldap.DefaultInitialDirContextFactory">
|
||||
class="org.acegisecurity.providers.ldap.DefaultInitialDirContextFactory">
|
||||
<constructor-arg value="ldap://monkeymachine:389/dc=acegisecurity,dc=org"/>
|
||||
<property name="managerDn"><value>cn=manager,dc=acegisecurity,dc=org</value></property>
|
||||
<property name="managerPassword"><value>password</value></property>
|
||||
</bean>
|
||||
|
||||
<bean id="userSearch"
|
||||
class="org.acegisecurity.ldap.search.FilterBasedLdapUserSearch">
|
||||
class="org.acegisecurity.providers.ldap.search.FilterBasedLdapUserSearch">
|
||||
<constructor-arg index="0">
|
||||
<value></value>
|
||||
</constructor-arg>
|
||||
|
||||
@@ -37,9 +37,6 @@
|
||||
<li><b><a href="mail-lists.html">Acegi Security Mailing Lists</a></b>:
|
||||
If you'd like to discuss development of the project.<br><br>
|
||||
</li>
|
||||
<li><b><a href="powering.html">Numerous frameworks using Acegi Security</a></b>:
|
||||
Look here first for how to integrate with major third-party frameworks...<br><br>
|
||||
</li>
|
||||
<li><b><a href="http://weblog.morosystems.cz/spring/Spring-Acegi-JCaptcha-integration">Acegi Security and Captcha Layer</a></b>:
|
||||
How to use Acegi Security with JCaptcha.<br><br>
|
||||
</li>
|
||||
@@ -118,7 +115,7 @@
|
||||
Matt Raible is including Acegi Security in Chapter 12 of his popular ebook.<br><br>
|
||||
</li>
|
||||
<li><b><a href="http://www.china-pub.com/computers/common/info.asp?id=24483">Mastering Spring (Chinese) Book</a></b>:
|
||||
Acegi Security is included in Chapter 17 of this book.<br><br>
|
||||
Acegi Security is included in Chapter 6 of this book.<br><br>
|
||||
</li>
|
||||
<li><b><a href="http://www.manning.com/walls2">Spring In Action</a></b>:
|
||||
Craig Walls has also written another popular Spring book, which includes Acegi Security in Chapter 11.<br><br>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<p>Often people reading this document just want to see if Acegi Security will work
|
||||
for their projects. They want to deploy a sample application, and that's about it
|
||||
(after all, all the reference documentation can be read online at
|
||||
<a href="http://acegisecurity.org">http://acegisecurity.org</a>).
|
||||
<a href="http://acegisecurity.sourceforge.net">http://acegisecurity.sourceforge.net</a>).
|
||||
In this case, execute:</p>
|
||||
<ol>
|
||||
<pre>cd $ACEGI_SECURITY/core (or cd %ACEGI_SECURITY%/core on Windows)</pre>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<item name="Contacts HTTPS" href="multiproject/acegi-security-sample-contacts/ssl/howto.txt"/>
|
||||
<item name="Project Policies" href="policies.html"/>
|
||||
<item name="Acegi Security JIRA" href="http://opensource.atlassian.com/projects/spring/secure/BrowseProject.jspa?id=10040"/>
|
||||
<item name="Blog" href="http://blog.interface21.com/main/author/bena/"/>
|
||||
<item name="Blog" href="http://blog.springframework.com/ben.alex/"/>
|
||||
</menu>
|
||||
|
||||
<menu name="Projects">
|
||||
|
||||
@@ -55,11 +55,6 @@
|
||||
<li><b><a href="https://atleap.dev.java.net/">Blandware AtLeap</a></b>: Multilingal free Java CMS.<br><br></li>
|
||||
<li><b><a href="http://photostructure.com/">PhotoStructure</a></b>: A photo management solution.<br><br></li>
|
||||
<li><b><a href="http://app.ess.ch/tudu/welcome.action">Tudu Lists</a></b>: AJAX and RSS powered to-do list manager.<br><br></li>
|
||||
<li><b><a href="http://trails.dev.java.net/">Trails</a></b>: Native Java Ruby-On-Rails-like framework. <a href="http://os.inspiring.nl/confluence/display/trails/Using+Security">Integration details</a>.<br><br></li>
|
||||
<li><b><a href="http://grails.codehaus.org/">Grails</a></b>: Native Java and Groovy Ruby-On-Rails-like framework. <a href="http://bbweblog.kevinhooke.com/BBWeblog/viewPost.do?entryID=803&instanceID=1&categoryID=111&action=detail">Integration details</a>.<br><br></li>
|
||||
<li><b><a href="http://tapestry.apache.org/">Tapestry</a></b>: The original Java event-driven web framework. <a href="http://www.carmanconsulting.com/tapestry-acegi">Integration details</a>.<br><br></li>
|
||||
<li><b><a href="http://jtrac.info/">JTrac</a></b>: A Java-based issue management system. <a href="http://jtrac.info/doc/html/faq.html">Integration details</a>.<br><br></li>
|
||||
<li><b><a href="http://plazma.sourceforge.net/">Plazma</a></b>: Swing-based ERP and CRM system for SMEs.<br><br></li>
|
||||
</ul>
|
||||
|
||||
<h2>Commercial Deployments</h2>
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>org.acegisecurity</groupId>
|
||||
<artifactId>acegi-security-parent</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.0.1</version>
|
||||
</parent>
|
||||
<artifactId>acegi-security-domain</artifactId>
|
||||
<name>Acegi Security System for Spring - Domain Object Support</name>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user