1
0
mirror of synced 2026-07-10 05:10:03 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Carlos Sanchez 1bc1196baa [maven-scm] copy for tag release_1_0_1 2006-06-22 17:28:18 +00:00
176 changed files with 2548 additions and 4157 deletions
+2 -1
View File
@@ -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"/>
+1 -1
View File
@@ -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>
+1 -1
View File
@@ -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>
+1 -1
View File
@@ -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>
+1 -1
View File
@@ -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
View File
@@ -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>
+1 -1
View File
@@ -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>
+1 -1
View File
@@ -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
View File
@@ -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>
+1 -1
View File
@@ -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
View File
@@ -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;
@@ -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();
}
}
@@ -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;
@@ -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);
}
}
}
@@ -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);
@@ -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}&lt;{@link String}>
*/
public void setConfigAttributes(List roles) {
this.configAttributes = roles;
}
/**
*
* @return {@link List}&lt;{@link String}>
*/
public List getConfigAttributes() {
return configAttributes;
}
/**
* Add a {@link ConfigAttribute} as {@link String}
*
* @param configAttribute
*/
public void addConfigAttribute(String configAttribute) {
configAttributes.add(configAttribute);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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}&lt;{@link String}>
*/
public void setConfigAttributes(List roles) {
this.configAttributes = roles;
}
/**
*
* @return {@link List}&lt;{@link String}>
*/
public List getConfigAttributes() {
return configAttributes;
}
/**
* Add a {@link ConfigAttribute} as {@link String}
*
* @param configAttribute
*/
public void addConfigAttribute(String configAttribute) {
configAttributes.add(configAttribute);
}
}
@@ -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()) {
@@ -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;
@@ -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;
@@ -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;
@@ -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;
}
}
@@ -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 ===================================================================================================
@@ -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);
@@ -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;
}
@@ -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);
}
}
}
@@ -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;
}
@@ -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);
@@ -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;
@@ -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;
}
}
@@ -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} &lt;{@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} &lt;{@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} &lt;{@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]);
}
}
@@ -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);
@@ -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();
@@ -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());
}
}
@@ -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 {
@@ -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;
}
}
@@ -24,7 +24,7 @@ import java.util.Vector;
/**
* Mock for {@link FilterInvocationDefinitionSource}
* DOCUMENT ME!
*
* @author Ben Alex
* @version $Id$
@@ -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());
}
}
@@ -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);
}
@@ -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);
@@ -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() {
@@ -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) {
}
}
}
@@ -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 {
@@ -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]);
}
}
@@ -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
View File
@@ -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>&lt;taglib&gt;
&lt;taglib-uri&gt;http://acegisecurity.org/authz&lt;/taglib-uri&gt;
&lt;taglib-uri&gt;http://acegisecurity.sf.net/authz&lt;/taglib-uri&gt;
&lt;taglib-location&gt;/WEB-INF/authz.tld&lt;/taglib-location&gt;
&lt;/taglib&gt; </programlisting></para>
</sect1>
@@ -1416,7 +1420,7 @@ if (obj instanceof UserDetails) {
this:</para>
<para><programlisting>&lt;filter&gt;
&lt;filter-name&gt;Acegi Filter Chain Proxy&lt;/filter-name&gt;
&lt;filter-name&gt;Acegi HTTP Request Security Filter&lt;/filter-name&gt;
&lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
&lt;init-param&gt;
&lt;param-name&gt;targetClass&lt;/param-name&gt;
@@ -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>&lt;bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.SiteminderAuthenticationProcessingFilter"&gt;
@@ -2153,37 +2153,51 @@ if (obj instanceof UserDetails) {
&lt;property name="defaultTargetUrl"&gt;&lt;value&gt;/security.do?method=getMainMenu&lt;/value&gt;&lt;/property&gt;
&lt;property name="filterProcessesUrl"&gt;&lt;value&gt;/j_acegi_security_check&lt;/value&gt;&lt;/property&gt;
&lt;property name="siteminderUsernameHeaderKey"&gt;&lt;value&gt;SM_USER&lt;/value&gt;&lt;/property&gt;
&lt;property name="formUsernameParameterKey"&gt;&lt;value&gt;j_username&lt;/value&gt;&lt;/property&gt;
&lt;property name="siteminderPasswordHeaderKey"&gt;&lt;value&gt;SM_USER&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;</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>
&lt;bean id="initialDirContextFactory"
class="org.acegisecurity.ldap.DefaultInitialDirContextFactory"&gt;
class="org.acegisecurity.providers.ldap.DefaultInitialDirContextFactory"&gt;
&lt;constructor-arg value="ldap://monkeymachine:389/dc=acegisecurity,dc=org"/&gt;
&lt;property name="managerDn"&gt;&lt;value&gt;cn=manager,dc=acegisecurity,dc=org&lt;/value&gt;&lt;/property&gt;
&lt;property name="managerPassword"&gt;&lt;value&gt;password&lt;/value&gt;&lt;/property&gt;
&lt;/bean&gt;
&lt;bean id="userSearch"
class="org.acegisecurity.ldap.search.FilterBasedLdapUserSearch"&gt;
class="org.acegisecurity.providers.ldap.search.FilterBasedLdapUserSearch"&gt;
&lt;constructor-arg index="0"&gt;
&lt;value&gt;&lt;/value&gt;
&lt;/constructor-arg&gt;
+1 -4
View File
@@ -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>
+1 -1
View File
@@ -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>
+1 -1
View File
@@ -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">
-5
View File
@@ -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
View File
@@ -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