SEC-56: Add localisation support.

This commit is contained in:
Ben Alex 2005-11-26 05:11:53 +00:00
parent f4c3e2ff8c
commit fddcd6112e
44 changed files with 2403 additions and 1862 deletions

View File

@ -29,6 +29,8 @@ import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.support.JdbcDaoSupport; import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery; import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.util.Assert;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Types; import java.sql.Types;
@ -51,9 +53,6 @@ import javax.sql.DataSource;
* the {@link MappingSqlQuery} instance used, via the {@link * the {@link MappingSqlQuery} instance used, via the {@link
* #initMappingSqlQueries()} extension point. * #initMappingSqlQueries()} extension point.
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao { public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
@ -79,113 +78,6 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
//~ Methods ================================================================ //~ Methods ================================================================
/**
* Returns the ACLs associated with the requested
* <code>AclObjectIdentity</code>.
*
* <P>
* The {@link BasicAclEntry}s returned by this method will have
* <code>String</code>-based recipients. This will not be a problem if you
* are using the <code>GrantedAuthorityEffectiveAclsResolver</code>, which
* is the default configured against <code>BasicAclProvider</code>.
* </p>
*
* <P>
* This method will only return ACLs for requests where the
* <code>AclObjectIdentity</code> is of type {@link
* NamedEntityObjectIdentity}. Of course, you can subclass or replace this
* class and support your own custom <code>AclObjectIdentity</code> types.
* </p>
*
* @param aclObjectIdentity for which ACL information is required (cannot
* be <code>null</code> and must be an instance of
* <code>NamedEntityObjectIdentity</code>)
*
* @return the ACLs that apply (without any <code>null</code>s inside the
* array), or <code>null</code> if not found or if an incompatible
* <code>AclObjectIdentity</code> was requested
*/
public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) {
String aclObjectIdentityString;
try {
aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
} catch (IllegalArgumentException unsupported) {
return null; // pursuant to contract described in JavaDocs above
}
// Lookup the object's main properties from the RDBMS (guaranteed no nulls)
List objects = objectProperties.execute(aclObjectIdentityString);
if (objects.size() == 0) {
// this is an unknown object identity string
return null;
}
// Cast to an object properties holder (there should only be one record)
AclDetailsHolder propertiesInformation = (AclDetailsHolder) objects.get(0);
// Lookup the object's ACLs from RDBMS (guaranteed no nulls)
List acls = aclsByObjectIdentity.execute(propertiesInformation
.getForeignKeyId());
if (acls.size() == 0) {
// return merely an inheritence marker (as we know about the object but it has no related ACLs)
return new BasicAclEntry[] {createBasicAclEntry(propertiesInformation,
null)};
} else {
// return the individual ACL instances
AclDetailsHolder[] aclHolders = (AclDetailsHolder[]) acls.toArray(new AclDetailsHolder[] {});
List toReturnAcls = new Vector();
for (int i = 0; i < aclHolders.length; i++) {
toReturnAcls.add(createBasicAclEntry(propertiesInformation,
aclHolders[i]));
}
return (BasicAclEntry[]) toReturnAcls.toArray(new BasicAclEntry[] {});
}
}
public void setAclsByObjectIdentity(
MappingSqlQuery aclsByObjectIdentityQuery) {
this.aclsByObjectIdentity = aclsByObjectIdentityQuery;
}
public MappingSqlQuery getAclsByObjectIdentity() {
return aclsByObjectIdentity;
}
/**
* Allows the default query string used to retrieve ACLs based on object
* identity to be overriden, if default table or column names need to be
* changed. The default query is {@link
* #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying this query, ensure
* that all returned columns are mapped back to the same column names as
* in the default query.
*
* @param queryString The query string to set
*/
public void setAclsByObjectIdentityQuery(String queryString) {
aclsByObjectIdentityQuery = queryString;
}
public String getAclsByObjectIdentityQuery() {
return aclsByObjectIdentityQuery;
}
public void setObjectProperties(MappingSqlQuery objectPropertiesQuery) {
this.objectProperties = objectPropertiesQuery;
}
public void setObjectPropertiesQuery(String queryString) {
objectPropertiesQuery = queryString;
}
public String getObjectPropertiesQuery() {
return objectPropertiesQuery;
}
/** /**
* Responsible for covering a <code>AclObjectIdentity</code> to a * Responsible for covering a <code>AclObjectIdentity</code> to a
* <code>String</code> that can be located in the RDBMS. * <code>String</code> that can be located in the RDBMS.
@ -193,17 +85,13 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
* @param aclObjectIdentity to locate * @param aclObjectIdentity to locate
* *
* @return the object identity as a <code>String</code> * @return the object identity as a <code>String</code>
*
* @throws IllegalArgumentException DOCUMENT ME!
*/ */
protected String convertAclObjectIdentityToString( protected String convertAclObjectIdentityToString(
AclObjectIdentity aclObjectIdentity) { AclObjectIdentity aclObjectIdentity) {
// Ensure we can process this type of AclObjectIdentity // Ensure we can process this type of AclObjectIdentity
if (!(aclObjectIdentity instanceof NamedEntityObjectIdentity)) { Assert.isInstanceOf(NamedEntityObjectIdentity.class, aclObjectIdentity,
throw new IllegalArgumentException(
"Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: " "Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: "
+ aclObjectIdentity + ")"); + aclObjectIdentity + ")");
}
NamedEntityObjectIdentity neoi = (NamedEntityObjectIdentity) aclObjectIdentity; NamedEntityObjectIdentity neoi = (NamedEntityObjectIdentity) aclObjectIdentity;
@ -211,19 +99,6 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
return neoi.getClassname() + ":" + neoi.getId(); return neoi.getClassname() + ":" + neoi.getId();
} }
protected void initDao() throws ApplicationContextException {
initMappingSqlQueries();
}
/**
* Extension point to allow other MappingSqlQuery objects to be substituted
* in a subclass
*/
protected void initMappingSqlQueries() {
setAclsByObjectIdentity(new AclsByObjectIdentityMapping(getDataSource()));
setObjectProperties(new ObjectPropertiesMapping(getDataSource()));
}
/** /**
* Constructs an individual <code>BasicAclEntry</code> from the passed * Constructs an individual <code>BasicAclEntry</code> from the passed
* <code>AclDetailsHolder</code>s. * <code>AclDetailsHolder</code>s.
@ -278,21 +153,150 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
return entry; return entry;
} }
//~ Inner Classes ==========================================================
/** /**
* Used to hold details of a domain object instance's properties, or an * Returns the ACLs associated with the requested
* individual ACL entry. * <code>AclObjectIdentity</code>.
* *
* <P> * <P>
* Not all properties will be set. The actual properties set will depend on * The {@link BasicAclEntry}s returned by this method will have
* which <code>MappingSqlQuery</code> creates the object. * <code>String</code>-based recipients. This will not be a problem if
* you are using the
* <code>GrantedAuthorityEffectiveAclsResolver</code>, which is the
* default configured against <code>BasicAclProvider</code>.
* </p> * </p>
* *
* <P> * <P>
* Does not enforce <code>null</code>s or empty <code>String</code>s as * This method will only return ACLs for requests where the
* this is performed by the <code>MappingSqlQuery</code> objects (or * <code>AclObjectIdentity</code> is of type {@link
* preferably the backend RDBMS via schema constraints). * NamedEntityObjectIdentity}. Of course, you can subclass or replace
* this class and support your own custom
* <code>AclObjectIdentity</code> types.
* </p>
*
* @param aclObjectIdentity for which ACL information is required
* (cannot be <code>null</code> and must be an instance of
* <code>NamedEntityObjectIdentity</code>)
*
* @return the ACLs that apply (without any <code>null</code>s inside
* the array), or <code>null</code> if not found or if an
* incompatible <code>AclObjectIdentity</code> was requested
*/
public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) {
String aclObjectIdentityString;
try {
aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
} catch (IllegalArgumentException unsupported) {
return null; // pursuant to contract described in JavaDocs above
}
// Lookup the object's main properties from the RDBMS (guaranteed no nulls)
List objects = objectProperties.execute(aclObjectIdentityString);
if (objects.size() == 0) {
// this is an unknown object identity string
return null;
}
// Cast to an object properties holder (there should only be one record)
AclDetailsHolder propertiesInformation = (AclDetailsHolder) objects
.get(0);
// Lookup the object's ACLs from RDBMS (guaranteed no nulls)
List acls = aclsByObjectIdentity.execute(propertiesInformation
.getForeignKeyId());
if (acls.size() == 0) {
// return merely an inheritence marker (as we know about the object but it has no related ACLs)
return new BasicAclEntry[] {createBasicAclEntry(propertiesInformation,
null)};
} else {
// return the individual ACL instances
AclDetailsHolder[] aclHolders = (AclDetailsHolder[]) acls
.toArray(new AclDetailsHolder[] {});
List toReturnAcls = new Vector();
for (int i = 0; i < aclHolders.length; i++) {
toReturnAcls.add(createBasicAclEntry(
propertiesInformation, aclHolders[i]));
}
return (BasicAclEntry[]) toReturnAcls.toArray(new BasicAclEntry[] {});
}
}
public MappingSqlQuery getAclsByObjectIdentity() {
return aclsByObjectIdentity;
}
public String getAclsByObjectIdentityQuery() {
return aclsByObjectIdentityQuery;
}
public String getObjectPropertiesQuery() {
return objectPropertiesQuery;
}
protected void initDao() throws ApplicationContextException {
initMappingSqlQueries();
}
/**
* Extension point to allow other MappingSqlQuery objects to be
* substituted in a subclass
*/
protected void initMappingSqlQueries() {
setAclsByObjectIdentity(new AclsByObjectIdentityMapping(
getDataSource()));
setObjectProperties(new ObjectPropertiesMapping(
getDataSource()));
}
public void setAclsByObjectIdentity(
MappingSqlQuery aclsByObjectIdentityQuery) {
this.aclsByObjectIdentity = aclsByObjectIdentityQuery;
}
/**
* Allows the default query string used to retrieve ACLs based
* on object identity to be overriden, if default table or
* column names need to be changed. The default query is
* {@link #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying
* this query, ensure that all returned columns are mapped
* back to the same column names as in the default query.
*
* @param queryString The query string to set
*/
public void setAclsByObjectIdentityQuery(String queryString) {
aclsByObjectIdentityQuery = queryString;
}
public void setObjectProperties(
MappingSqlQuery objectPropertiesQuery) {
this.objectProperties = objectPropertiesQuery;
}
public void setObjectPropertiesQuery(String queryString) {
objectPropertiesQuery = queryString;
}
//~ Inner Classes ==========================================================
/**
* Used to hold details of a domain object instance's
* properties, or an individual ACL entry.
*
* <P>
* Not all properties will be set. The actual properties set
* will depend on which <code>MappingSqlQuery</code> creates
* the object.
* </p>
*
* <P>
* Does not enforce <code>null</code>s or empty
* <code>String</code>s as this is performed by the
* <code>MappingSqlQuery</code> objects (or preferably the
* backend RDBMS via schema constraints).
* </p> * </p>
*/ */
protected final class AclDetailsHolder { protected final class AclDetailsHolder {
@ -304,8 +308,8 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
private long foreignKeyId; private long foreignKeyId;
/** /**
* Record details of an individual ACL entry (usually from the * Record details of an individual ACL entry (usually from
* ACL_PERMISSION table) * the ACL_PERMISSION table)
* *
* @param recipient the recipient * @param recipient the recipient
* @param mask the integer to be masked * @param mask the integer to be masked
@ -316,23 +320,25 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
} }
/** /**
* Record details of a domain object instance's properties (usually * Record details of a domain object instance's properties
* from the ACL_OBJECT_IDENTITY table) * (usually from the ACL_OBJECT_IDENTITY table)
* *
* @param foreignKeyId used by the * @param foreignKeyId used by the
* <code>AclsByObjectIdentityMapping</code> to locate the * <code>AclsByObjectIdentityMapping</code> to
* individual ACL entries * locate the individual ACL entries
* @param aclObjectIdentity the object identity of the domain object * @param aclObjectIdentity the object identity of the
* instance * domain object instance
* @param aclObjectParentIdentity the object identity of the domain * @param aclObjectParentIdentity the object identity of
* object instance's parent * the domain object instance's parent
* @param aclClass the class of which a new instance which should be * @param aclClass the class of which a new instance which
* created for each individual ACL entry (or an inheritence * should be created for each individual ACL entry
* "holder" class if there are no ACL entries) * (or an inheritence "holder" class if there are
* no ACL entries)
*/ */
public AclDetailsHolder(long foreignKeyId, public AclDetailsHolder(long foreignKeyId,
AclObjectIdentity aclObjectIdentity, AclObjectIdentity aclObjectIdentity,
AclObjectIdentity aclObjectParentIdentity, Class aclClass) { AclObjectIdentity aclObjectParentIdentity,
Class aclClass) {
this.foreignKeyId = foreignKeyId; this.foreignKeyId = foreignKeyId;
this.aclObjectIdentity = aclObjectIdentity; this.aclObjectIdentity = aclObjectIdentity;
this.aclObjectParentIdentity = aclObjectParentIdentity; this.aclObjectParentIdentity = aclObjectParentIdentity;
@ -372,16 +378,18 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
* </p> * </p>
* *
* <P> * <P>
* Guarantees to never return <code>null</code> (exceptions are thrown in * Guarantees to never return <code>null</code> (exceptions are
* the event of any issues). * thrown in the event of any issues).
* </p> * </p>
* *
* <P> * <P>
* The executed SQL requires the following information be made available * The executed SQL requires the following information be made
* from the indicated placeholders: 1. RECIPIENT, 2. MASK. * available from the indicated placeholders: 1. RECIPIENT, 2.
* MASK.
* </p> * </p>
*/ */
protected class AclsByObjectIdentityMapping extends MappingSqlQuery { protected class AclsByObjectIdentityMapping
extends MappingSqlQuery {
protected AclsByObjectIdentityMapping(DataSource ds) { protected AclsByObjectIdentityMapping(DataSource ds) {
super(ds, aclsByObjectIdentityQuery); super(ds, aclsByObjectIdentityQuery);
declareParameter(new SqlParameter(Types.BIGINT)); declareParameter(new SqlParameter(Types.BIGINT));
@ -392,10 +400,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
throws SQLException { throws SQLException {
String recipient = rs.getString(1); String recipient = rs.getString(1);
int mask = rs.getInt(2); int mask = rs.getInt(2);
Assert.hasText(recipient, "recipient required");
if ((recipient == null) || "".equals(recipient)) {
throw new IllegalArgumentException("recipient required");
}
return new AclDetailsHolder(recipient, mask); return new AclDetailsHolder(recipient, mask);
} }
@ -409,14 +414,15 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
* </p> * </p>
* *
* <P> * <P>
* Guarantees to never return <code>null</code> (exceptions are thrown in * Guarantees to never return <code>null</code> (exceptions are
* the event of any issues). * thrown in the event of any issues).
* </p> * </p>
* *
* <P> * <P>
* The executed SQL requires the following information be made available * The executed SQL requires the following information be made
* from the indicated placeholders: 1. ID, 2. OBJECT_IDENTITY, 3. * available from the indicated placeholders: 1. ID, 2.
* ACL_CLASS and 4. PARENT_OBJECT_IDENTITY. * OBJECT_IDENTITY, 3. ACL_CLASS and 4.
* PARENT_OBJECT_IDENTITY.
* </p> * </p>
*/ */
protected class ObjectPropertiesMapping extends MappingSqlQuery { protected class ObjectPropertiesMapping extends MappingSqlQuery {
@ -426,32 +432,6 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
compile(); compile();
} }
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
long id = rs.getLong(1); // required
String objectIdentity = rs.getString(2); // required
String aclClass = rs.getString(3); // required
String parentObjectIdentity = rs.getString(4); // optional
if ((objectIdentity == null) || "".equals(objectIdentity)
|| (aclClass == null) || "".equals(aclClass)) {
// shouldn't happen if DB schema defined NOT NULL columns
throw new IllegalArgumentException(
"required DEF_OBJECT_PROPERTIES_QUERY value returned null or empty");
}
Class aclClazz;
try {
aclClazz = this.getClass().getClassLoader().loadClass(aclClass);
} catch (ClassNotFoundException cnf) {
throw new IllegalArgumentException(cnf.getMessage());
}
return new AclDetailsHolder(id, buildIdentity(objectIdentity),
buildIdentity(parentObjectIdentity), aclClazz);
}
private AclObjectIdentity buildIdentity(String identity) { private AclObjectIdentity buildIdentity(String identity) {
if (identity == null) { if (identity == null) {
// Must be an empty parent, so return null // Must be an empty parent, so return null
@ -464,5 +444,30 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
return new NamedEntityObjectIdentity(classname, id); return new NamedEntityObjectIdentity(classname, id);
} }
protected Object mapRow(ResultSet rs, int rownum)
throws SQLException {
long id = rs.getLong(1); // required
String objectIdentity = rs.getString(2); // required
String aclClass = rs.getString(3); // required
String parentObjectIdentity = rs.getString(4); // optional
Assert.hasText(objectIdentity,
"required DEF_OBJECT_PROPERTIES_QUERY value (objectIdentity) returned null or empty");
Assert.hasText(aclClass,
"required DEF_OBJECT_PROPERTIES_QUERY value (aclClass) returned null or empty");
Class aclClazz;
try {
aclClazz = this.getClass().getClassLoader()
.loadClass(aclClass);
} catch (ClassNotFoundException cnf) {
throw new IllegalArgumentException(cnf.getMessage());
}
return new AclDetailsHolder(id,
buildIdentity(objectIdentity),
buildIdentity(parentObjectIdentity), aclClazz);
}
}
} }
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,9 +18,15 @@ package org.acegisecurity.adapters;
import org.acegisecurity.Authentication; import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationException;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.AuthenticationProvider;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -38,28 +44,20 @@ import org.springframework.util.Assert;
* <P> * <P>
* If the key does not match, a <code>BadCredentialsException</code> is thrown. * If the key does not match, a <code>BadCredentialsException</code> is thrown.
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public class AuthByAdapterProvider implements InitializingBean, public class AuthByAdapterProvider implements InitializingBean,
AuthenticationProvider { AuthenticationProvider, MessageSourceAware {
//~ Instance fields ======================================================== //~ Instance fields ========================================================
protected MessageSourceAccessor messages;
private String key; private String key;
//~ Methods ================================================================ //~ Methods ================================================================
public void setKey(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.notNull(key, "A Key is required and should match that configured for the adapters"); Assert.notNull(key,
"A Key is required and should match that configured for the adapters");
Assert.notNull(messages, "A message source must be set");
} }
public Authentication authenticate(Authentication authentication) public Authentication authenticate(Authentication authentication)
@ -69,11 +67,24 @@ public class AuthByAdapterProvider implements InitializingBean,
if (token.getKeyHash() == key.hashCode()) { if (token.getKeyHash() == key.hashCode()) {
return authentication; return authentication;
} else { } else {
throw new BadCredentialsException( throw new BadCredentialsException(messages.getMessage(
"The presented AuthByAdapter implementation does not contain the expected key"); "AuthByAdapterProvider.incorrectKey",
"The presented AuthByAdapter implementation does not contain the expected key"));
} }
} }
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public boolean supports(Class authentication) { public boolean supports(Class authentication) {
if (AuthByAdapter.class.isAssignableFrom(authentication)) { if (AuthByAdapter.class.isAssignableFrom(authentication)) {
return true; return true;

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,6 +19,7 @@ import org.acegisecurity.AccessDeniedException;
import org.acegisecurity.Authentication; import org.acegisecurity.Authentication;
import org.acegisecurity.ConfigAttribute; import org.acegisecurity.ConfigAttribute;
import org.acegisecurity.ConfigAttributeDefinition; import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.acl.AclEntry; import org.acegisecurity.acl.AclEntry;
import org.acegisecurity.acl.AclManager; import org.acegisecurity.acl.AclManager;
import org.acegisecurity.acl.basic.BasicAclEntry; import org.acegisecurity.acl.basic.BasicAclEntry;
@ -28,6 +29,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import java.util.Iterator; import java.util.Iterator;
@ -45,9 +51,8 @@ import java.util.Iterator;
* (ACL) permissions associated with a domain object instance for the current * (ACL) permissions associated with a domain object instance for the current
* <code>Authentication</code> object. This class is designed to process * <code>Authentication</code> object. This class is designed to process
* {@link AclEntry}s that are subclasses of {@link * {@link AclEntry}s that are subclasses of {@link
* org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these * org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are
* are obtained by using the {@link * obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}.
* org.acegisecurity.acl.basic.BasicAclProvider}.
* </p> * </p>
* *
* <p> * <p>
@ -55,8 +60,8 @@ import java.util.Iterator;
* ConfigAttribute#getAttribute()} matches the {@link * ConfigAttribute#getAttribute()} matches the {@link
* #processConfigAttribute}. The provider will then lookup the ACLs from the * #processConfigAttribute}. The provider will then lookup the ACLs from the
* <code>AclManager</code> and ensure the principal is {@link * <code>AclManager</code> and ensure the principal is {@link
* org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for * org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least
* at least one of the {@link #requirePermission}s. * one of the {@link #requirePermission}s.
* </p> * </p>
* *
* <p> * <p>
@ -74,9 +79,8 @@ import java.util.Iterator;
* <p> * <p>
* The <code>AclManager</code> is allowed to return any implementations of * The <code>AclManager</code> is allowed to return any implementations of
* <code>AclEntry</code> it wishes. However, this provider will only be able * <code>AclEntry</code> it wishes. However, this provider will only be able
* to validate against <code>BasicAclEntry</code>s, and thus access * to validate against <code>BasicAclEntry</code>s, and thus access will be
* will be denied if no <code>AclEntry</code> is of type * denied if no <code>AclEntry</code> is of type <code>BasicAclEntry</code>.
* <code>BasicAclEntry</code>.
* </p> * </p>
* *
* <p> * <p>
@ -87,12 +91,9 @@ import java.util.Iterator;
* <p> * <p>
* All comparisons and prefixes are case sensitive. * All comparisons and prefixes are case sensitive.
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public class BasicAclEntryAfterInvocationProvider public class BasicAclEntryAfterInvocationProvider
implements AfterInvocationProvider, InitializingBean { implements AfterInvocationProvider, InitializingBean, MessageSourceAware {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationProvider.class); protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationProvider.class);
@ -100,41 +101,21 @@ public class BasicAclEntryAfterInvocationProvider
//~ Instance fields ======================================================== //~ Instance fields ========================================================
private AclManager aclManager; private AclManager aclManager;
protected MessageSourceAccessor messages;
private String processConfigAttribute = "AFTER_ACL_READ"; private String processConfigAttribute = "AFTER_ACL_READ";
private int[] requirePermission = {SimpleAclEntry.READ}; private int[] requirePermission = {SimpleAclEntry.READ};
//~ Methods ================================================================ //~ Methods ================================================================
public void setAclManager(AclManager aclManager) {
this.aclManager = aclManager;
}
public AclManager getAclManager() {
return aclManager;
}
public void setProcessConfigAttribute(String processConfigAttribute) {
this.processConfigAttribute = processConfigAttribute;
}
public String getProcessConfigAttribute() {
return processConfigAttribute;
}
public void setRequirePermission(int[] requirePermission) {
this.requirePermission = requirePermission;
}
public int[] getRequirePermission() {
return requirePermission;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory"); Assert.notNull(processConfigAttribute,
"A processConfigAttribute is mandatory");
Assert.notNull(aclManager, "An aclManager is mandatory"); Assert.notNull(aclManager, "An aclManager is mandatory");
Assert.notNull(messages, "A message source must be set");
if ((requirePermission == null) || (requirePermission.length == 0)) { if ((requirePermission == null) || (requirePermission.length == 0)) {
throw new IllegalArgumentException("One or more requirePermission entries is mandatory"); throw new IllegalArgumentException(
"One or more requirePermission entries is mandatory");
} }
} }
@ -162,10 +143,10 @@ public class BasicAclEntryAfterInvocationProvider
authentication); authentication);
if ((acls == null) || (acls.length == 0)) { if ((acls == null) || (acls.length == 0)) {
throw new AccessDeniedException("Authentication: " throw new AccessDeniedException(messages.getMessage(
+ authentication.toString() "BasicAclEntryAfterInvocationProvider.noPermission",
+ " has NO permissions at all to the domain object: " new Object[] {authentication.getName(), returnedObject},
+ returnedObject); "Authentication {0} has NO permissions at all to the domain object {1}"));
} }
for (int i = 0; i < acls.length; i++) { for (int i = 0; i < acls.length; i++) {
@ -190,16 +171,44 @@ public class BasicAclEntryAfterInvocationProvider
} }
// No permissions match // No permissions match
throw new AccessDeniedException("Authentication: " throw new AccessDeniedException(messages.getMessage(
+ authentication.toString() "BasicAclEntryAfterInvocationProvider.insufficientPermission",
+ " has ACL permissions to the domain object, but not the required ACL permission to the domain object: " new Object[] {authentication.getName(), returnedObject},
+ returnedObject); "Authentication {0} has ACL permissions to the domain object, but not the required ACL permission to the domain object {1}"));
} }
} }
return returnedObject; return returnedObject;
} }
public AclManager getAclManager() {
return aclManager;
}
public String getProcessConfigAttribute() {
return processConfigAttribute;
}
public int[] getRequirePermission() {
return requirePermission;
}
public void setAclManager(AclManager aclManager) {
this.aclManager = aclManager;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public void setProcessConfigAttribute(String processConfigAttribute) {
this.processConfigAttribute = processConfigAttribute;
}
public void setRequirePermission(int[] requirePermission) {
this.requirePermission = requirePermission;
}
public boolean supports(ConfigAttribute attribute) { public boolean supports(ConfigAttribute attribute) {
if ((attribute.getAttribute() != null) if ((attribute.getAttribute() != null)
&& attribute.getAttribute().equals(getProcessConfigAttribute())) { && attribute.getAttribute().equals(getProcessConfigAttribute())) {

View File

@ -19,6 +19,11 @@ import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationException;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -30,36 +35,61 @@ import org.springframework.util.Assert;
* By default uses {@link org.acegisecurity.concurrent.SessionRegistryImpl}, * By default uses {@link org.acegisecurity.concurrent.SessionRegistryImpl},
* although any <code>SessionRegistry</code> may be used. * although any <code>SessionRegistry</code> may be used.
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public class ConcurrentSessionControllerImpl public class ConcurrentSessionControllerImpl
implements ConcurrentSessionController, InitializingBean { implements ConcurrentSessionController, InitializingBean,
MessageSourceAware {
//~ Instance fields ======================================================== //~ Instance fields ========================================================
protected MessageSourceAccessor messages;
private SessionRegistry sessionRegistry = new SessionRegistryImpl(); private SessionRegistry sessionRegistry = new SessionRegistryImpl();
private int maximumSessions = 1;
private boolean exceptionIfMaximumExceeded = false; private boolean exceptionIfMaximumExceeded = false;
private int maximumSessions = 1;
//~ Methods ================================================================ //~ Methods ================================================================
public void setMaximumSessions(int maximumSessions) {
this.maximumSessions = maximumSessions;
}
public void setSessionRegistry(SessionRegistry sessionRegistry) {
this.sessionRegistry = sessionRegistry;
}
public void setExceptionIfMaximumExceeded(boolean exceptionIfMaximumExceeded) {
this.exceptionIfMaximumExceeded = exceptionIfMaximumExceeded;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.notNull(sessionRegistry, "SessionRegistry required"); Assert.notNull(sessionRegistry, "SessionRegistry required");
Assert.isTrue(maximumSessions != 0, Assert.isTrue(maximumSessions != 0,
"MaximumLogins must be either -1 to allow unlimited logins, or a positive integer to specify a maximum"); "MaximumLogins must be either -1 to allow unlimited logins, or a positive integer to specify a maximum");
Assert.notNull(this.messages, "A message source must be set");
}
/**
* Allows subclasses to customise behaviour when too many sessions are
* detected.
*
* @param sessionId the session ID of the present request
* @param sessions either <code>null</code> or all unexpired sessions
* associated with the principal
* @param allowableSessions DOCUMENT ME!
* @param registry an instance of the <code>SessionRegistry</code> for
* subclass use
*
* @throws ConcurrentLoginException DOCUMENT ME!
*/
protected void allowableSessionsExceeded(String sessionId,
SessionInformation[] sessions, int allowableSessions,
SessionRegistry registry) {
if (exceptionIfMaximumExceeded || (sessions == null)) {
throw new ConcurrentLoginException(messages.getMessage(
"ConcurrentSessionControllerImpl.exceededAllowed",
new Object[] {new Integer(allowableSessions)},
"Maximum sessions of {0} for this principal exceeded"));
}
// Determine least recently used session, and mark it for invalidation
SessionInformation leastRecentlyUsed = null;
for (int i = 0; i < sessions.length; i++) {
if ((leastRecentlyUsed == null)
|| sessions[i].getLastRequest()
.before(leastRecentlyUsed.getLastRequest())) {
leastRecentlyUsed = sessions[i];
}
}
leastRecentlyUsed.expireNow();
} }
public void checkAuthenticationAllowed(Authentication request) public void checkAuthenticationAllowed(Authentication request)
@ -95,35 +125,28 @@ public class ConcurrentSessionControllerImpl
} }
} }
allowableSessionsExceeded(sessionId, sessions, allowableSessions, sessionRegistry); allowableSessionsExceeded(sessionId, sessions,
allowableSessions, sessionRegistry);
} }
/** /**
* Allows subclasses to customise behaviour when too many sessions are * Method intended for use by subclasses to override the maximum
* detected. * number of sessions that are permitted for a particular
* authentication. The default implementation simply returns the
* <code>maximumSessions</code> value for the bean.
* *
* @param sessionId the session ID of the present request * @param authentication to determine the maximum sessions for
* @param sessions either <code>null</code> or all unexpired sessions associated with the principal *
* @param registry an instance of the <code>SessionRegistry</code> for subclass use * @return either -1 meaning unlimited, or a positive integer to
* limit (never zero)
*/ */
protected void allowableSessionsExceeded(String sessionId, SessionInformation[] sessions, int allowableSessions, SessionRegistry registry) { protected int getMaximumSessionsForThisUser(
if (exceptionIfMaximumExceeded || sessions == null) { Authentication authentication) {
throw new ConcurrentLoginException("Maximum sessions of " return maximumSessions;
+ allowableSessions + " for this principal exceeded");
} }
// Determine least recently used session, and mark it for invalidation public void registerSuccessfulAuthentication(
SessionInformation leastRecentlyUsed = null; Authentication authentication) {
for (int i = 0; i < sessions.length; i++) {
if (leastRecentlyUsed == null || sessions[i].getLastRequest().before(leastRecentlyUsed.getLastRequest())) {
leastRecentlyUsed = sessions[i];
}
}
leastRecentlyUsed.expireNow();
}
public void registerSuccessfulAuthentication(Authentication authentication) {
Assert.notNull(authentication, Assert.notNull(authentication,
"Authentication cannot be null (violation of interface contract)"); "Authentication cannot be null (violation of interface contract)");
@ -136,18 +159,21 @@ public class ConcurrentSessionControllerImpl
sessionRegistry.registerNewSession(sessionId, principal); sessionRegistry.registerNewSession(sessionId, principal);
} }
/** public void setExceptionIfMaximumExceeded(
* Method intended for use by subclasses to override the maximum number of boolean exceptionIfMaximumExceeded) {
* sessions that are permitted for a particular authentication. The this.exceptionIfMaximumExceeded = exceptionIfMaximumExceeded;
* default implementation simply returns the <code>maximumSessions</code> }
* value for the bean.
* public void setMaximumSessions(int maximumSessions) {
* @param authentication to determine the maximum sessions for this.maximumSessions = maximumSessions;
* }
* @return either -1 meaning unlimited, or a positive integer to limit
* (never zero) public void setMessageSource(MessageSource messageSource) {
*/ this.messages = new MessageSourceAccessor(messageSource);
protected int getMaximumSessionsForThisUser(Authentication authentication) { }
return maximumSessions;
public void setSessionRegistry(
SessionRegistry sessionRegistry) {
this.sessionRegistry = sessionRegistry;
}
} }
}

View File

@ -42,6 +42,9 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -135,12 +138,9 @@ import java.util.Set;
* </li> * </li>
* </ol> * </ol>
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public abstract class AbstractSecurityInterceptor implements InitializingBean, public abstract class AbstractSecurityInterceptor implements InitializingBean,
ApplicationEventPublisherAware { ApplicationEventPublisherAware, MessageSourceAware {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
protected static final Log logger = LogFactory.getLog(AbstractSecurityInterceptor.class); protected static final Log logger = LogFactory.getLog(AbstractSecurityInterceptor.class);
@ -151,6 +151,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
private AfterInvocationManager afterInvocationManager; private AfterInvocationManager afterInvocationManager;
private ApplicationEventPublisher eventPublisher; private ApplicationEventPublisher eventPublisher;
private AuthenticationManager authenticationManager; private AuthenticationManager authenticationManager;
protected MessageSourceAccessor messages;
private RunAsManager runAsManager = new NullRunAsManager(); private RunAsManager runAsManager = new NullRunAsManager();
private boolean alwaysReauthenticate = false; private boolean alwaysReauthenticate = false;
private boolean rejectPublicInvocations = false; private boolean rejectPublicInvocations = false;
@ -158,115 +159,49 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
//~ Methods ================================================================ //~ Methods ================================================================
public void setAfterInvocationManager(
AfterInvocationManager afterInvocationManager) {
this.afterInvocationManager = afterInvocationManager;
}
public AfterInvocationManager getAfterInvocationManager() {
return afterInvocationManager;
}
/** /**
* Indicates whether the <code>AbstractSecurityInterceptor</code> should * Completes the work of the <code>AbstractSecurityInterceptor</code> after
* ignore the {@link Authentication#isAuthenticated()} property. Defaults * the secure object invocation has been complete
* to <code>false</code>, meaning by default the
* <code>Authentication.isAuthenticated()</code> property is trusted and
* re-authentication will not occur if the principal has already been
* authenticated.
* *
* @param alwaysReauthenticate <code>true</code> to force * @param token as returned by the {@link #beforeInvocation(Object)}}
* <code>AbstractSecurityInterceptor</code> to disregard the value * method
* of <code>Authentication.isAuthenticated()</code> and always * @param returnedObject any object returned from the secure object
* re-authenticate the request (defaults to <code>false</code>). * invocation (may be<code>null</code>)
*/
public void setAlwaysReauthenticate(boolean alwaysReauthenticate) {
this.alwaysReauthenticate = alwaysReauthenticate;
}
public boolean isAlwaysReauthenticate() {
return alwaysReauthenticate;
}
public void setApplicationEventPublisher(
ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
/**
* Indicates the type of secure objects the subclass will be presenting to
* the abstract parent for processing. This is used to ensure
* collaborators wired to the <code>AbstractSecurityInterceptor</code> all
* support the indicated secure object class.
* *
* @return the type of secure object the subclass provides services for * @return the object the secure object invocation should ultimately return
* to its caller (may be <code>null</code>)
*/ */
public abstract Class getSecureObjectClass(); protected Object afterInvocation(InterceptorStatusToken token,
Object returnedObject) {
public abstract ObjectDefinitionSource obtainObjectDefinitionSource(); if (token == null) {
// public object
public void setAccessDecisionManager( return returnedObject;
AccessDecisionManager accessDecisionManager) {
this.accessDecisionManager = accessDecisionManager;
} }
public AccessDecisionManager getAccessDecisionManager() { if (token.isContextHolderRefreshRequired()) {
return accessDecisionManager; if (logger.isDebugEnabled()) {
logger.debug("Reverting to original Authentication: "
+ token.getAuthentication().toString());
} }
public void setAuthenticationManager(AuthenticationManager newManager) { SecurityContextHolder.getContext()
this.authenticationManager = newManager; .setAuthentication(token.getAuthentication());
} }
public AuthenticationManager getAuthenticationManager() { if (afterInvocationManager != null) {
return this.authenticationManager; returnedObject = afterInvocationManager.decide(token
.getAuthentication(), token.getSecureObject(),
token.getAttr(), returnedObject);
} }
/** return returnedObject;
* By rejecting public invocations (and setting this property to
* <code>true</code>), essentially you are ensuring that every secure
* object invocation advised by <code>AbstractSecurityInterceptor</code>
* has a configuration attribute defined. This is useful to ensure a "fail
* safe" mode where undeclared secure objects will be rejected and
* configuration omissions detected early. An
* <code>IllegalArgumentException</code> will be thrown by the
* <code>AbstractSecurityInterceptor</code> if you set this property to
* <code>true</code> and an attempt is made to invoke a secure object that
* has no configuration attributes.
*
* @param rejectPublicInvocations set to <code>true</code> to reject
* invocations of secure objects that have no configuration
* attributes (by default it is <code>true</code> which treats
* undeclared secure objects as "public" or unauthorized)
*/
public void setRejectPublicInvocations(boolean rejectPublicInvocations) {
this.rejectPublicInvocations = rejectPublicInvocations;
}
public boolean isRejectPublicInvocations() {
return rejectPublicInvocations;
}
public void setRunAsManager(RunAsManager runAsManager) {
this.runAsManager = runAsManager;
}
public RunAsManager getRunAsManager() {
return runAsManager;
}
public void setValidateConfigAttributes(boolean validateConfigAttributes) {
this.validateConfigAttributes = validateConfigAttributes;
}
public boolean isValidateConfigAttributes() {
return validateConfigAttributes;
} }
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.notNull(getSecureObjectClass(), Assert.notNull(getSecureObjectClass(),
"Subclass must provide a non-null response to getSecureObjectClass()"); "Subclass must provide a non-null response to getSecureObjectClass()");
Assert.notNull(this.messages, "A message source must be set");
Assert.notNull(this.authenticationManager, Assert.notNull(this.authenticationManager,
"An AuthenticationManager is required"); "An AuthenticationManager is required");
@ -278,7 +213,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
Assert.notNull(this.obtainObjectDefinitionSource(), Assert.notNull(this.obtainObjectDefinitionSource(),
"An ObjectDefinitionSource is required"); "An ObjectDefinitionSource is required");
if (!this.obtainObjectDefinitionSource().supports(getSecureObjectClass())) { if (!this.obtainObjectDefinitionSource()
.supports(getSecureObjectClass())) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"ObjectDefinitionSource does not support secure object class: " "ObjectDefinitionSource does not support secure object class: "
+ getSecureObjectClass()); + getSecureObjectClass());
@ -346,47 +282,10 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
} }
} }
/**
* Completes the work of the <code>AbstractSecurityInterceptor</code> after
* the secure object invocation has been complete
*
* @param token as returned by the {@link #beforeInvocation(Object)}}
* method
* @param returnedObject any object returned from the secure object
* invocation (may be<code>null</code>)
*
* @return the object the secure object invocation should ultimately return
* to its caller (may be <code>null</code>)
*/
protected Object afterInvocation(InterceptorStatusToken token,
Object returnedObject) {
if (token == null) {
// public object
return returnedObject;
}
if (token.isContextHolderRefreshRequired()) {
if (logger.isDebugEnabled()) {
logger.debug("Reverting to original Authentication: "
+ token.getAuthentication().toString());
}
SecurityContextHolder.getContext().setAuthentication(token
.getAuthentication());
}
if (afterInvocationManager != null) {
returnedObject = afterInvocationManager.decide(token
.getAuthentication(), token.getSecureObject(),
token.getAttr(), returnedObject);
}
return returnedObject;
}
protected InterceptorStatusToken beforeInvocation(Object object) { protected InterceptorStatusToken beforeInvocation(Object object) {
Assert.notNull(object, "Object was null"); Assert.notNull(object, "Object was null");
Assert.isTrue(getSecureObjectClass().isAssignableFrom(object.getClass()), Assert.isTrue(getSecureObjectClass()
.isAssignableFrom(object.getClass()),
"Security invocation attempted for object " "Security invocation attempted for object "
+ object.getClass().getName() + object.getClass().getName()
+ " but AbstractSecurityInterceptor only configured to support secure objects of type: " + " but AbstractSecurityInterceptor only configured to support secure objects of type: "
@ -409,7 +308,9 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
// We check for just the property we're interested in (we do // We check for just the property we're interested in (we do
// not call Context.validate() like the ContextInterceptor) // not call Context.validate() like the ContextInterceptor)
if (SecurityContextHolder.getContext().getAuthentication() == null) { if (SecurityContextHolder.getContext().getAuthentication() == null) {
credentialsNotFound("Authentication credentials were not found in the SecurityContext", credentialsNotFound(messages.getMessage(
"AbstractSecurityInterceptor.authenticationNotFound",
"An Authentication object was not found in the SecurityContext"),
object, attr); object, attr);
} }
@ -432,7 +333,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
+ authenticated.toString()); + authenticated.toString());
} }
SecurityContextHolder.getContext().setAuthentication(authenticated); SecurityContextHolder.getContext()
.setAuthentication(authenticated);
} else { } else {
authenticated = SecurityContextHolder.getContext() authenticated = SecurityContextHolder.getContext()
.getAuthentication(); .getAuthentication();
@ -445,7 +347,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
// Attempt authorization // Attempt authorization
try { try {
this.accessDecisionManager.decide(authenticated, object, attr); this.accessDecisionManager.decide(authenticated, object,
attr);
} catch (AccessDeniedException accessDeniedException) { } catch (AccessDeniedException accessDeniedException) {
AuthorizationFailureEvent event = new AuthorizationFailureEvent(object, AuthorizationFailureEvent event = new AuthorizationFailureEvent(object,
attr, authenticated, accessDeniedException); attr, authenticated, accessDeniedException);
@ -472,8 +375,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
"RunAsManager did not change Authentication object"); "RunAsManager did not change Authentication object");
} }
return new InterceptorStatusToken(authenticated, false, attr, return new InterceptorStatusToken(authenticated, false,
object); // no further work post-invocation attr, object); // no further work post-invocation
} else { } else {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Switching to RunAs Authentication: " logger.debug("Switching to RunAs Authentication: "
@ -482,23 +385,24 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
SecurityContextHolder.getContext().setAuthentication(runAs); SecurityContextHolder.getContext().setAuthentication(runAs);
return new InterceptorStatusToken(authenticated, true, attr, return new InterceptorStatusToken(authenticated, true,
object); // revert to token.Authenticated post-invocation attr, object); // revert to token.Authenticated post-invocation
} }
} else { } else {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Public object - authentication not attempted"); logger.debug("Public object - authentication not attempted");
} }
this.eventPublisher.publishEvent(new PublicInvocationEvent(object)); this.eventPublisher.publishEvent(new PublicInvocationEvent(
object));
return null; // no further work post-invocation return null; // no further work post-invocation
} }
} }
/** /**
* Helper method which generates an exception containing the passed reason, * Helper method which generates an exception containing the passed
* and publishes an event to the application context. * reason, and publishes an event to the application context.
* *
* <p> * <p>
* Always throws an exception. * Always throws an exception.
@ -518,4 +422,115 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
throw exception; throw exception;
} }
}
public AccessDecisionManager getAccessDecisionManager() {
return accessDecisionManager;
}
public AfterInvocationManager getAfterInvocationManager() {
return afterInvocationManager;
}
public AuthenticationManager getAuthenticationManager() {
return this.authenticationManager;
}
public RunAsManager getRunAsManager() {
return runAsManager;
}
/**
* Indicates the type of secure objects the subclass will be presenting
* to the abstract parent for processing. This is used to ensure
* collaborators wired to the <code>AbstractSecurityInterceptor</code>
* all support the indicated secure object class.
*
* @return the type of secure object the subclass provides services for
*/
public abstract Class getSecureObjectClass();
public boolean isAlwaysReauthenticate() {
return alwaysReauthenticate;
}
public boolean isRejectPublicInvocations() {
return rejectPublicInvocations;
}
public boolean isValidateConfigAttributes() {
return validateConfigAttributes;
}
public abstract ObjectDefinitionSource obtainObjectDefinitionSource();
public void setAccessDecisionManager(
AccessDecisionManager accessDecisionManager) {
this.accessDecisionManager = accessDecisionManager;
}
public void setAfterInvocationManager(
AfterInvocationManager afterInvocationManager) {
this.afterInvocationManager = afterInvocationManager;
}
/**
* Indicates whether the <code>AbstractSecurityInterceptor</code>
* should ignore the {@link Authentication#isAuthenticated()}
* property. Defaults to <code>false</code>, meaning by default the
* <code>Authentication.isAuthenticated()</code> property is trusted
* and re-authentication will not occur if the principal has already
* been authenticated.
*
* @param alwaysReauthenticate <code>true</code> to force
* <code>AbstractSecurityInterceptor</code> to disregard the
* value of <code>Authentication.isAuthenticated()</code> and
* always re-authenticate the request (defaults to
* <code>false</code>).
*/
public void setAlwaysReauthenticate(boolean alwaysReauthenticate) {
this.alwaysReauthenticate = alwaysReauthenticate;
}
public void setApplicationEventPublisher(
ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void setAuthenticationManager(AuthenticationManager newManager) {
this.authenticationManager = newManager;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
/**
* By rejecting public invocations (and setting this property to
* <code>true</code>), essentially you are ensuring that every secure
* object invocation advised by
* <code>AbstractSecurityInterceptor</code> has a configuration
* attribute defined. This is useful to ensure a "fail safe" mode
* where undeclared secure objects will be rejected and configuration
* omissions detected early. An <code>IllegalArgumentException</code>
* will be thrown by the <code>AbstractSecurityInterceptor</code> if
* you set this property to <code>true</code> and an attempt is made
* to invoke a secure object that has no configuration attributes.
*
* @param rejectPublicInvocations set to <code>true</code> to reject
* invocations of secure objects that have no configuration
* attributes (by default it is <code>true</code> which treats
* undeclared secure objects as "public" or unauthorized)
*/
public void setRejectPublicInvocations(boolean rejectPublicInvocations) {
this.rejectPublicInvocations = rejectPublicInvocations;
}
public void setRunAsManager(RunAsManager runAsManager) {
this.runAsManager = runAsManager;
}
public void setValidateConfigAttributes(
boolean validateConfigAttributes) {
this.validateConfigAttributes = validateConfigAttributes;
}
}

View File

@ -0,0 +1,39 @@
AuthByAdapterProvider.incorrectKey=The presented AuthByAdapter implementation does not contain the expected key
BasicAclEntryAfterInvocationProvider.noPermission=Authentication {0} has NO permissions at all to the domain object {1}
BasicAclEntryAfterInvocationProvider.insufficientPermission=Authentication {0} has ACL permissions to the domain object, but not the required ACL permission to the domain object {1}
ConcurrentSessionControllerImpl.exceededAllowed=Maximum sessions of {0} for this principal exceeded
ProviderManager.providerNotFound=No AuthenticationProvider found for {0}
AnonymousAuthenticationProvider.incorrectKey=The presented AnonymousAuthenticationToken does not contain the expected key
CasAuthenticationProvider.incorrectKey=The presented CasAuthenticationToken does not contain the expected key
CasAuthenticationProvider.noServiceTicket=Failed to provide a CAS service ticket to validate
NamedCasProxyDecider.untrusted=Nearest proxy {0} is untrusted
RejectProxyTickets.reject=Proxy tickets are rejected
AbstractSecurityInterceptor.authenticationNotFound=An Authentication object was not found in the SecurityContext
AbstractUserDetailsAuthenticationProvider.onlySupports=Only UsernamePasswordAuthenticationToken is supported
AbstractUserDetailsAuthenticationProvider.locked=User account is locked
AbstractUserDetailsAuthenticationProvider.disabled=User is disabled
AbstractUserDetailsAuthenticationProvider.expired=User account has expired
AbstractUserDetailsAuthenticationProvider.credentialsExpired=User credentials have expired
AbstractUserDetailsAuthenticationProvider.badCredentials=Bad credentials
X509AuthenticationProvider.certificateNull=Certificate is null
DaoX509AuthoritiesPopulator.noMatching=No matching pattern was found in subjectDN: {0}
RememberMeAuthenticationProvider.incorrectKey=The presented RememberMeAuthenticationToken does not contain the expected key
RunAsImplAuthenticationProvider.incorrectKey=The presented RunAsUserToken does not contain the expected key
DigestProcessingFilter.missingMandatory=Missing mandatory digest value; received header {0}
DigestProcessingFilter.missingAuth=Missing mandatory digest value for 'auth' QOP; received header {0}
DigestProcessingFilter.incorrectRealm=Response realm name {0} does not match system realm name of {1}
DigestProcessingFilter.nonceExpired=Nonce has expired/timed out
DigestProcessingFilter.nonceEncoding=Nonce is not encoded in Base64; received nonce {0}
DigestProcessingFilter.nonceNotTwoTokens=Nonce should have yielded two tokens but was {0}
DigestProcessingFilter.nonceNotNumeric=Nonce token should have yielded a numeric first token, but was {0}
DigestProcessingFilter.nonceCompromised=Nonce token compromised {0}
DigestProcessingFilter.usernameNotFound=Username {0} not found
DigestProcessingFilter.incorrectResponse=Incorrect response
SwitchUserProcessingFilter.noCurrentUser=No current user associated with this request
SwitchUserProcessingFilter.noOriginalAuthentication=Could not find original Authentication object
SwitchUserProcessingFilter.usernameNotFound=Username {0} not found
SwitchUserProcessingFilter.locked=User account is locked
SwitchUserProcessingFilter.disabled=User is disabled
SwitchUserProcessingFilter.expired=User account has expired
SwitchUserProcessingFilter.credentialsExpired=User credentials have expired
AbstractAccessDecisionManager.accessDenied=Access is denied

View File

@ -24,9 +24,11 @@ import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.CredentialsExpiredException; import org.acegisecurity.CredentialsExpiredException;
import org.acegisecurity.DisabledException; import org.acegisecurity.DisabledException;
import org.acegisecurity.LockedException; import org.acegisecurity.LockedException;
import org.acegisecurity.concurrent.ConcurrentLoginException; import org.acegisecurity.concurrent.ConcurrentLoginException;
import org.acegisecurity.concurrent.ConcurrentSessionController; import org.acegisecurity.concurrent.ConcurrentSessionController;
import org.acegisecurity.concurrent.NullConcurrentSessionController; import org.acegisecurity.concurrent.NullConcurrentSessionController;
import org.acegisecurity.event.authentication.AbstractAuthenticationEvent; import org.acegisecurity.event.authentication.AbstractAuthenticationEvent;
import org.acegisecurity.event.authentication.AuthenticationFailureBadCredentialsEvent; import org.acegisecurity.event.authentication.AuthenticationFailureBadCredentialsEvent;
import org.acegisecurity.event.authentication.AuthenticationFailureConcurrentLoginEvent; import org.acegisecurity.event.authentication.AuthenticationFailureConcurrentLoginEvent;
@ -38,6 +40,7 @@ import org.acegisecurity.event.authentication.AuthenticationFailureProviderNotFo
import org.acegisecurity.event.authentication.AuthenticationFailureProxyUntrustedEvent; import org.acegisecurity.event.authentication.AuthenticationFailureProxyUntrustedEvent;
import org.acegisecurity.event.authentication.AuthenticationFailureServiceExceptionEvent; import org.acegisecurity.event.authentication.AuthenticationFailureServiceExceptionEvent;
import org.acegisecurity.event.authentication.AuthenticationSuccessEvent; import org.acegisecurity.event.authentication.AuthenticationSuccessEvent;
import org.acegisecurity.providers.cas.ProxyUntrustedException; import org.acegisecurity.providers.cas.ProxyUntrustedException;
import org.acegisecurity.providers.dao.UsernameNotFoundException; import org.acegisecurity.providers.dao.UsernameNotFoundException;
@ -48,6 +51,9 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -85,8 +91,8 @@ import java.util.Properties;
* If a valid <code>Authentication</code> is returned by an * If a valid <code>Authentication</code> is returned by an
* <code>AuthenticationProvider</code>, the <code>ProviderManager</code> will * <code>AuthenticationProvider</code>, the <code>ProviderManager</code> will
* publish an {@link * publish an {@link
* org.acegisecurity.event.authentication.AuthenticationSuccessEvent}. If * org.acegisecurity.event.authentication.AuthenticationSuccessEvent}. If an
* an <code>AuthenticationException</code> is detected, the final * <code>AuthenticationException</code> is detected, the final
* <code>AuthenticationException</code> thrown will be used to publish an * <code>AuthenticationException</code> thrown will be used to publish an
* appropriate failure event. By default <code>ProviderManager</code> maps * appropriate failure event. By default <code>ProviderManager</code> maps
* common exceptions to events, but this can be fine-tuned by providing a new * common exceptions to events, but this can be fine-tuned by providing a new
@ -98,15 +104,11 @@ import java.util.Properties;
* and provides its constructor. * and provides its constructor.
* </p> * </p>
* *
* @author Ben Alex
* @author Wesley Hall
* @author Ray Krueger
* @version $Id$
*
* @see ConcurrentSessionController * @see ConcurrentSessionController
*/ */
public class ProviderManager extends AbstractAuthenticationManager public class ProviderManager extends AbstractAuthenticationManager
implements InitializingBean, ApplicationEventPublisherAware { implements InitializingBean, ApplicationEventPublisherAware,
MessageSourceAware {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(ProviderManager.class); private static final Log logger = LogFactory.getLog(ProviderManager.class);
@ -116,74 +118,14 @@ public class ProviderManager extends AbstractAuthenticationManager
private ApplicationEventPublisher applicationEventPublisher; private ApplicationEventPublisher applicationEventPublisher;
private ConcurrentSessionController sessionController = new NullConcurrentSessionController(); private ConcurrentSessionController sessionController = new NullConcurrentSessionController();
private List providers; private List providers;
protected MessageSourceAccessor messages;
private Properties exceptionMappings; private Properties exceptionMappings;
//~ Methods ================================================================ //~ Methods ================================================================
public void setApplicationEventPublisher(
ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
/**
* Sets the {@link AuthenticationProvider} objects to be used for
* authentication.
*
* @param newList
*
* @throws IllegalArgumentException DOCUMENT ME!
*/
public void setProviders(List newList) {
checkIfValidList(newList);
Iterator iter = newList.iterator();
while (iter.hasNext()) {
Object currentObject = null;
try {
currentObject = iter.next();
AuthenticationProvider attemptToCast = (AuthenticationProvider) currentObject;
} catch (ClassCastException cce) {
throw new IllegalArgumentException("AuthenticationProvider "
+ currentObject.getClass().getName()
+ " must implement AuthenticationProvider");
}
}
this.providers = newList;
}
public List getProviders() {
return this.providers;
}
/**
* Set the {@link ConcurrentSessionController} to be used for limiting
* user's sessions. The {@link NullConcurrentSessionController} is used
* by default
*
* @param sessionController {@link ConcurrentSessionController}
*/
public void setSessionController(
ConcurrentSessionController sessionController) {
this.sessionController = sessionController;
}
/**
* The configured {@link ConcurrentSessionController} is returned or the
* {@link NullConcurrentSessionController} if a specific one has not been
* set.
*
* @return {@link ConcurrentSessionController} instance
*/
public ConcurrentSessionController getSessionController() {
return sessionController;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
checkIfValidList(this.providers); checkIfValidList(this.providers);
Assert.notNull(this.messages, "A message source must be set");
if (exceptionMappings == null) { if (exceptionMappings == null) {
exceptionMappings = new Properties(); exceptionMappings = new Properties();
@ -211,6 +153,23 @@ public class ProviderManager extends AbstractAuthenticationManager
} }
} }
private void checkIfValidList(List listToCheck) {
if ((listToCheck == null) || (listToCheck.size() == 0)) {
throw new IllegalArgumentException(
"A list of AuthenticationManagers is required");
}
}
/**
* Provided so subclasses can add extra exception mappings during startup
* if no exception mappings are injected by the IoC container.
*
* @param exceptionMappings the properties object, which already has
* entries in it
*/
protected void doAddExtraDefaultExceptionMappings(
Properties exceptionMappings) {}
/** /**
* Attempts to authenticate the passed {@link Authentication} object. * Attempts to authenticate the passed {@link Authentication} object.
* *
@ -244,8 +203,7 @@ public class ProviderManager extends AbstractAuthenticationManager
AuthenticationException lastException = null; AuthenticationException lastException = null;
while (iter.hasNext()) { while (iter.hasNext()) {
AuthenticationProvider provider = (AuthenticationProvider) iter AuthenticationProvider provider = (AuthenticationProvider) iter.next();
.next();
if (provider.supports(toTest)) { if (provider.supports(toTest)) {
logger.debug("Authentication attempt using " logger.debug("Authentication attempt using "
@ -272,8 +230,10 @@ public class ProviderManager extends AbstractAuthenticationManager
} }
if (lastException == null) { if (lastException == null) {
lastException = new ProviderNotFoundException( lastException = new ProviderNotFoundException(messages.getMessage(
"No authentication provider for " + toTest.getName()); "ProviderManager.providerNotFound",
new Object[] {toTest.getName()},
"No AuthenticationProvider found for {0}"));
} }
// Publish the event // Publish the event
@ -309,20 +269,69 @@ public class ProviderManager extends AbstractAuthenticationManager
throw lastException; throw lastException;
} }
/** public List getProviders() {
* Provided so subclasses can add extra exception mappings during startup return this.providers;
* if no exception mappings are injected by the IoC container.
*
* @param exceptionMappings the properties object, which already has
* entries in it
*/
protected void doAddExtraDefaultExceptionMappings(
Properties exceptionMappings) {}
private void checkIfValidList(List listToCheck) {
if ((listToCheck == null) || (listToCheck.size() == 0)) {
throw new IllegalArgumentException(
"A list of AuthenticationManagers is required");
} }
/**
* The configured {@link ConcurrentSessionController} is returned or the
* {@link NullConcurrentSessionController} if a specific one has not been
* set.
*
* @return {@link ConcurrentSessionController} instance
*/
public ConcurrentSessionController getSessionController() {
return sessionController;
}
public void setApplicationEventPublisher(
ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
/**
* Sets the {@link AuthenticationProvider} objects to be used for
* authentication.
*
* @param newList
*
* @throws IllegalArgumentException DOCUMENT ME!
*/
public void setProviders(List newList) {
checkIfValidList(newList);
Iterator iter = newList.iterator();
while (iter.hasNext()) {
Object currentObject = null;
try {
currentObject = iter.next();
AuthenticationProvider attemptToCast = (AuthenticationProvider) currentObject;
} catch (ClassCastException cce) {
throw new IllegalArgumentException("AuthenticationProvider "
+ currentObject.getClass().getName()
+ " must implement AuthenticationProvider");
}
}
this.providers = newList;
}
/**
* Set the {@link ConcurrentSessionController} to be used for limiting
* user's sessions. The {@link NullConcurrentSessionController} is used
* by default
*
* @param sessionController {@link ConcurrentSessionController}
*/
public void setSessionController(
ConcurrentSessionController sessionController) {
this.sessionController = sessionController;
} }
} }

View File

@ -18,6 +18,7 @@ package org.acegisecurity.providers.anonymous;
import org.acegisecurity.Authentication; import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationException;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.AuthenticationProvider;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -25,6 +26,10 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -37,32 +42,23 @@ import org.springframework.util.Assert;
* org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken#getKeyHash()} * org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken#getKeyHash()}
* must match this class' {@link #getKey()}. * must match this class' {@link #getKey()}.
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public class AnonymousAuthenticationProvider implements AuthenticationProvider, public class AnonymousAuthenticationProvider implements AuthenticationProvider,
InitializingBean { InitializingBean, MessageSourceAware {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(AnonymousAuthenticationProvider.class); private static final Log logger = LogFactory.getLog(AnonymousAuthenticationProvider.class);
//~ Instance fields ======================================================== //~ Instance fields ========================================================
protected MessageSourceAccessor messages;
private String key; private String key;
//~ Methods ================================================================ //~ Methods ================================================================
public void setKey(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.hasLength(key); Assert.hasLength(key, "A Key is required");
Assert.notNull(this.messages, "A message source must be set");
} }
public Authentication authenticate(Authentication authentication) public Authentication authenticate(Authentication authentication)
@ -73,13 +69,26 @@ public class AnonymousAuthenticationProvider implements AuthenticationProvider,
if (this.key.hashCode() != ((AnonymousAuthenticationToken) authentication) if (this.key.hashCode() != ((AnonymousAuthenticationToken) authentication)
.getKeyHash()) { .getKeyHash()) {
throw new BadCredentialsException( throw new BadCredentialsException(messages.getMessage(
"The presented AnonymousAuthenticationToken does not contain the expected key"); "AnonymousAuthenticationProvider.incorrectKey",
"The presented AnonymousAuthenticationToken does not contain the expected key"));
} }
return authentication; return authentication;
} }
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public boolean supports(Class authentication) { public boolean supports(Class authentication) {
return (AnonymousAuthenticationToken.class.isAssignableFrom(authentication)); return (AnonymousAuthenticationToken.class.isAssignableFrom(authentication));
} }

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,14 +19,21 @@ import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationException;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.UserDetails; import org.acegisecurity.UserDetails;
import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.AuthenticationProvider;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.cas.CasProcessingFilter; import org.acegisecurity.ui.cas.CasProcessingFilter;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -42,12 +49,9 @@ import org.springframework.util.Assert;
* CasProcessingFilter#CAS_STATELESS_IDENTIFIER}. It can also validate a * CasProcessingFilter#CAS_STATELESS_IDENTIFIER}. It can also validate a
* previously created {@link CasAuthenticationToken}. * previously created {@link CasAuthenticationToken}.
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public class CasAuthenticationProvider implements AuthenticationProvider, public class CasAuthenticationProvider implements AuthenticationProvider,
InitializingBean { InitializingBean, MessageSourceAware {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(CasAuthenticationProvider.class); private static final Log logger = LogFactory.getLog(CasAuthenticationProvider.class);
@ -56,60 +60,23 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
private CasAuthoritiesPopulator casAuthoritiesPopulator; private CasAuthoritiesPopulator casAuthoritiesPopulator;
private CasProxyDecider casProxyDecider; private CasProxyDecider casProxyDecider;
protected MessageSourceAccessor messages;
private StatelessTicketCache statelessTicketCache; private StatelessTicketCache statelessTicketCache;
private String key; private String key;
private TicketValidator ticketValidator; private TicketValidator ticketValidator;
//~ Methods ================================================================ //~ Methods ================================================================
public void setCasAuthoritiesPopulator(
CasAuthoritiesPopulator casAuthoritiesPopulator) {
this.casAuthoritiesPopulator = casAuthoritiesPopulator;
}
public CasAuthoritiesPopulator getCasAuthoritiesPopulator() {
return casAuthoritiesPopulator;
}
public void setCasProxyDecider(CasProxyDecider casProxyDecider) {
this.casProxyDecider = casProxyDecider;
}
public CasProxyDecider getCasProxyDecider() {
return casProxyDecider;
}
public void setKey(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public void setStatelessTicketCache(
StatelessTicketCache statelessTicketCache) {
this.statelessTicketCache = statelessTicketCache;
}
public StatelessTicketCache getStatelessTicketCache() {
return statelessTicketCache;
}
public void setTicketValidator(TicketValidator ticketValidator) {
this.ticketValidator = ticketValidator;
}
public TicketValidator getTicketValidator() {
return ticketValidator;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.notNull(this.casAuthoritiesPopulator, "A casAuthoritiesPopulator must be set"); Assert.notNull(this.casAuthoritiesPopulator,
"A casAuthoritiesPopulator must be set");
Assert.notNull(this.ticketValidator, "A ticketValidator must be set"); Assert.notNull(this.ticketValidator, "A ticketValidator must be set");
Assert.notNull(this.casProxyDecider, "A casProxyDecider must be set"); Assert.notNull(this.casProxyDecider, "A casProxyDecider must be set");
Assert.notNull(this.statelessTicketCache, "A statelessTicketCache must be set"); Assert.notNull(this.statelessTicketCache,
Assert.notNull(key, "A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated"); "A statelessTicketCache must be set");
Assert.notNull(key,
"A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated");
Assert.notNull(this.messages, "A message source must be set");
} }
public Authentication authenticate(Authentication authentication) public Authentication authenticate(Authentication authentication)
@ -133,16 +100,18 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
.getKeyHash()) { .getKeyHash()) {
return authentication; return authentication;
} else { } else {
throw new BadCredentialsException( throw new BadCredentialsException(messages.getMessage(
"The presented CasAuthenticationToken does not contain the expected key"); "CasAuthenticationProvider.incorrectKey",
"The presented CasAuthenticationToken does not contain the expected key"));
} }
} }
// Ensure credentials are presented // Ensure credentials are presented
if ((authentication.getCredentials() == null) if ((authentication.getCredentials() == null)
|| "".equals(authentication.getCredentials())) { || "".equals(authentication.getCredentials())) {
throw new BadCredentialsException( throw new BadCredentialsException(messages.getMessage(
"Failed to provide a CAS service ticket to validate"); "CasAuthenticationProvider.noServiceTicket",
"Failed to provide a CAS service ticket to validate"));
} }
boolean stateless = false; boolean stateless = false;
@ -173,17 +142,6 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
return result; return result;
} }
public boolean supports(Class authentication) {
if (UsernamePasswordAuthenticationToken.class.isAssignableFrom(
authentication)) {
return true;
} else if (CasAuthenticationToken.class.isAssignableFrom(authentication)) {
return true;
} else {
return false;
}
}
private CasAuthenticationToken authenticateNow( private CasAuthenticationToken authenticateNow(
Authentication authentication) throws AuthenticationException { Authentication authentication) throws AuthenticationException {
// Validate // Validate
@ -203,4 +161,61 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
userDetails, response.getProxyList(), userDetails, response.getProxyList(),
response.getProxyGrantingTicketIou()); response.getProxyGrantingTicketIou());
} }
public CasAuthoritiesPopulator getCasAuthoritiesPopulator() {
return casAuthoritiesPopulator;
}
public CasProxyDecider getCasProxyDecider() {
return casProxyDecider;
}
public String getKey() {
return key;
}
public StatelessTicketCache getStatelessTicketCache() {
return statelessTicketCache;
}
public TicketValidator getTicketValidator() {
return ticketValidator;
}
public void setCasAuthoritiesPopulator(
CasAuthoritiesPopulator casAuthoritiesPopulator) {
this.casAuthoritiesPopulator = casAuthoritiesPopulator;
}
public void setCasProxyDecider(CasProxyDecider casProxyDecider) {
this.casProxyDecider = casProxyDecider;
}
public void setKey(String key) {
this.key = key;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public void setStatelessTicketCache(
StatelessTicketCache statelessTicketCache) {
this.statelessTicketCache = statelessTicketCache;
}
public void setTicketValidator(TicketValidator ticketValidator) {
this.ticketValidator = ticketValidator;
}
public boolean supports(Class authentication) {
if (UsernamePasswordAuthenticationToken.class.isAssignableFrom(
authentication)) {
return true;
} else if (CasAuthenticationToken.class.isAssignableFrom(authentication)) {
return true;
} else {
return false;
}
}
} }

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,6 +22,11 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import java.util.List; import java.util.List;
@ -35,11 +40,9 @@ import java.util.List;
* Also accepts the request if there was no proxy (ie the user directly * Also accepts the request if there was no proxy (ie the user directly
* authenticated against this service). * authenticated against this service).
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean { public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean,
MessageSourceAware {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(NamedCasProxyDecider.class); private static final Log logger = LogFactory.getLog(NamedCasProxyDecider.class);
@ -47,19 +50,13 @@ public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean {
//~ Instance fields ======================================================== //~ Instance fields ========================================================
private List validProxies; private List validProxies;
protected MessageSourceAccessor messages;
//~ Methods ================================================================ //~ Methods ================================================================
public void setValidProxies(List validProxies) {
this.validProxies = validProxies;
}
public List getValidProxies() {
return validProxies;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.notNull(this.validProxies, "A validProxies list must be set"); Assert.notNull(this.validProxies, "A validProxies list must be set");
Assert.notNull(this.messages, "A message source must be set");
} }
public void confirmProxyListTrusted(List proxyList) public void confirmProxyListTrusted(List proxyList)
@ -76,8 +73,22 @@ public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean {
} }
if (!validProxies.contains(proxyList.get(0))) { if (!validProxies.contains(proxyList.get(0))) {
throw new ProxyUntrustedException("Nearest proxy '" throw new ProxyUntrustedException(messages.getMessage(
+ proxyList.get(0) + "' is untrusted"); "NamedCasProxyDecider.untrusted",
new Object[] {proxyList.get(0)},
"Nearest proxy {0} is untrusted"));
} }
} }
public List getValidProxies() {
return validProxies;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public void setValidProxies(List validProxies) {
this.validProxies = validProxies;
}
} }

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,6 +20,13 @@ import org.acegisecurity.providers.cas.ProxyUntrustedException;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import java.util.List; import java.util.List;
@ -32,17 +39,23 @@ import java.util.List;
* This class should be used if only service tickets wish to be accepted (ie no * This class should be used if only service tickets wish to be accepted (ie no
* proxy tickets at all). * proxy tickets at all).
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public class RejectProxyTickets implements CasProxyDecider { public class RejectProxyTickets implements CasProxyDecider, MessageSourceAware,
InitializingBean {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(RejectProxyTickets.class); private static final Log logger = LogFactory.getLog(RejectProxyTickets.class);
//~ Instance fields ========================================================
protected MessageSourceAccessor messages;
//~ Methods ================================================================ //~ Methods ================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.messages, "A message source must be set");
}
public void confirmProxyListTrusted(List proxyList) public void confirmProxyListTrusted(List proxyList)
throws ProxyUntrustedException { throws ProxyUntrustedException {
Assert.notNull(proxyList, "proxyList cannot be null"); Assert.notNull(proxyList, "proxyList cannot be null");
@ -57,6 +70,11 @@ public class RejectProxyTickets implements CasProxyDecider {
+ proxyList.toString()); + proxyList.toString());
} }
throw new ProxyUntrustedException("Proxy tickets are rejected"); throw new ProxyUntrustedException(messages.getMessage(
"RejectProxyTickets.reject", "Proxy tickets are rejected"));
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
} }
} }

View File

@ -22,12 +22,17 @@ import org.acegisecurity.CredentialsExpiredException;
import org.acegisecurity.DisabledException; import org.acegisecurity.DisabledException;
import org.acegisecurity.LockedException; import org.acegisecurity.LockedException;
import org.acegisecurity.UserDetails; import org.acegisecurity.UserDetails;
import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.AuthenticationProvider;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.dao.cache.NullUserCache; import org.acegisecurity.providers.dao.cache.NullUserCache;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -62,110 +67,17 @@ import org.springframework.util.Assert;
* incorrect password, the {@link AuthenticationDao} will be queried to * incorrect password, the {@link AuthenticationDao} will be queried to
* confirm the most up-to-date password was used for comparison. * confirm the most up-to-date password was used for comparison.
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public abstract class AbstractUserDetailsAuthenticationProvider public abstract class AbstractUserDetailsAuthenticationProvider
implements AuthenticationProvider, InitializingBean { implements AuthenticationProvider, InitializingBean, MessageSourceAware {
//~ Instance fields ======================================================== //~ Instance fields ========================================================
protected MessageSourceAccessor messages;
private UserCache userCache = new NullUserCache(); private UserCache userCache = new NullUserCache();
private boolean forcePrincipalAsString = false; private boolean forcePrincipalAsString = false;
//~ Methods ================================================================ //~ Methods ================================================================
public void setForcePrincipalAsString(boolean forcePrincipalAsString) {
this.forcePrincipalAsString = forcePrincipalAsString;
}
public boolean isForcePrincipalAsString() {
return forcePrincipalAsString;
}
public void setUserCache(UserCache userCache) {
this.userCache = userCache;
}
public UserCache getUserCache() {
return userCache;
}
public final void afterPropertiesSet() throws Exception {
Assert.notNull(this.userCache, "A user cache must be set");
doAfterPropertiesSet();
}
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class,
authentication,
"Only UsernamePasswordAuthenticationToken is supported");
// Determine username
String username = (authentication.getPrincipal() == null)
? "NONE_PROVIDED" : authentication.getName();
boolean cacheWasUsed = true;
UserDetails user = this.userCache.getUserFromCache(username);
if (user == null) {
cacheWasUsed = false;
user = retrieveUser(username,
(UsernamePasswordAuthenticationToken) authentication);
Assert.notNull(user,
"retrieveUser returned null - a violation of the interface contract");
}
if (!user.isAccountNonLocked()) {
throw new LockedException("User account is locked");
}
if (!user.isEnabled()) {
throw new DisabledException("User is disabled");
}
if (!user.isAccountNonExpired()) {
throw new AccountExpiredException("User account has expired");
}
// This check must come here, as we don't want to tell users
// about account status unless they presented the correct credentials
try {
additionalAuthenticationChecks(user,
(UsernamePasswordAuthenticationToken) authentication);
} catch (AuthenticationException 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()) {
throw new CredentialsExpiredException(
"User credentials have expired");
}
if (!cacheWasUsed) {
this.userCache.putUserInCache(user);
}
Object principalToReturn = user;
if (forcePrincipalAsString) {
principalToReturn = user.getUsername();
}
return createSuccessAuthentication(principalToReturn, authentication,
user);
}
public boolean supports(Class authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
}
/** /**
* Allows subclasses to perform any additional checks of a returned (or * Allows subclasses to perform any additional checks of a returned (or
* cached) <code>UserDetails</code> for a given authentication request. * cached) <code>UserDetails</code> for a given authentication request.
@ -190,8 +102,132 @@ public abstract class AbstractUserDetailsAuthenticationProvider
UsernamePasswordAuthenticationToken authentication) UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException; throws AuthenticationException;
public final void afterPropertiesSet() throws Exception {
Assert.notNull(this.userCache, "A user cache must be set");
Assert.notNull(this.messages, "A message source must be set");
doAfterPropertiesSet();
}
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class,
authentication,
messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.onlySupports",
"Only UsernamePasswordAuthenticationToken is supported"));
// Determine username
String username = (authentication.getPrincipal() == null)
? "NONE_PROVIDED" : authentication.getName();
boolean cacheWasUsed = true;
UserDetails user = this.userCache.getUserFromCache(username);
if (user == null) {
cacheWasUsed = false;
user = retrieveUser(username,
(UsernamePasswordAuthenticationToken) authentication);
Assert.notNull(user,
"retrieveUser returned null - a violation of the interface contract");
}
if (!user.isAccountNonLocked()) {
throw new LockedException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.locked",
"User account is locked"));
}
if (!user.isEnabled()) {
throw new DisabledException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.disabled",
"User is disabled"));
}
if (!user.isAccountNonExpired()) {
throw new AccountExpiredException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.expired",
"User account has expired"));
}
// This check must come here, as we don't want to tell users
// about account status unless they presented the correct credentials
try {
additionalAuthenticationChecks(user,
(UsernamePasswordAuthenticationToken) authentication);
} catch (AuthenticationException 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()) {
throw new CredentialsExpiredException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.credentialsExpired",
"User credentials have expired"));
}
if (!cacheWasUsed) {
this.userCache.putUserInCache(user);
}
Object principalToReturn = user;
if (forcePrincipalAsString) {
principalToReturn = user.getUsername();
}
return createSuccessAuthentication(principalToReturn, authentication,
user);
}
/**
* Creates a successful {@link Authentication} object.
*
* <P>
* Protected so subclasses can override.
* </p>
*
* <P>
* Subclasses will usually store the original credentials the user supplied
* (not salted or encoded passwords) in the returned
* <code>Authentication</code> object.
* </p>
*
* @param principal that should be the principal in the returned object
* (defined by the {@link #isForcePrincipalAsString()} method)
* @param authentication that was presented to the
* <code>DaoAuthenticationProvider</code> for validation
* @param user that was loaded by the <code>AuthenticationDao</code>
*
* @return the successful authentication token
*/
protected Authentication createSuccessAuthentication(Object principal,
Authentication authentication, UserDetails user) {
// Ensure we return the original credentials the user supplied,
// so subsequent attempts are successful even with encoded passwords.
// Also ensure we return the original getDetails(), so that future
// authentication events after cache expiry contain the details
UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(principal,
authentication.getCredentials(), user.getAuthorities());
result.setDetails((authentication.getDetails() != null)
? authentication.getDetails() : null);
return result;
}
protected void doAfterPropertiesSet() throws Exception {} protected void doAfterPropertiesSet() throws Exception {}
public UserCache getUserCache() {
return userCache;
}
public boolean isForcePrincipalAsString() {
return forcePrincipalAsString;
}
/** /**
* Allows subclasses to actually retrieve the <code>UserDetails</code> from * Allows subclasses to actually retrieve the <code>UserDetails</code> from
* an implementation-specific location, with the option of throwing an * an implementation-specific location, with the option of throwing an
@ -243,38 +279,19 @@ public abstract class AbstractUserDetailsAuthenticationProvider
UsernamePasswordAuthenticationToken authentication) UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException; throws AuthenticationException;
/** public void setForcePrincipalAsString(boolean forcePrincipalAsString) {
* Creates a successful {@link Authentication} object. this.forcePrincipalAsString = forcePrincipalAsString;
* }
* <P>
* Protected so subclasses can override.
* </p>
*
* <P>
* Subclasses will usually store the original credentials the user supplied
* (not salted or encoded passwords) in the returned
* <code>Authentication</code> object.
* </p>
*
* @param principal that should be the principal in the returned object
* (defined by the {@link #isForcePrincipalAsString()} method)
* @param authentication that was presented to the
* <code>DaoAuthenticationProvider</code> for validation
* @param user that was loaded by the <code>AuthenticationDao</code>
*
* @return the successful authentication token
*/
protected Authentication createSuccessAuthentication(Object principal,
Authentication authentication, UserDetails user) {
// Ensure we return the original credentials the user supplied,
// so subsequent attempts are successful even with encoded passwords.
// Also ensure we return the original getDetails(), so that future
// authentication events after cache expiry contain the details
UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(principal,
authentication.getCredentials(), user.getAuthorities());
result.setDetails((authentication.getDetails() != null)
? authentication.getDetails() : null);
return result; public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public void setUserCache(UserCache userCache) {
this.userCache = userCache;
}
public boolean supports(Class authentication) {
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
} }
} }

View File

@ -19,6 +19,7 @@ import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationServiceException; import org.acegisecurity.AuthenticationServiceException;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.UserDetails; import org.acegisecurity.UserDetails;
import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.AuthenticationProvider;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.encoding.PasswordEncoder; import org.acegisecurity.providers.encoding.PasswordEncoder;
@ -32,9 +33,6 @@ import org.springframework.util.Assert;
/** /**
* An {@link AuthenticationProvider} implementation that retrieves user details * An {@link AuthenticationProvider} implementation that retrieves user details
* from an {@link AuthenticationDao}. * from an {@link AuthenticationDao}.
*
* @author Ben Alex
* @version $Id$
*/ */
public class DaoAuthenticationProvider public class DaoAuthenticationProvider
extends AbstractUserDetailsAuthenticationProvider { extends AbstractUserDetailsAuthenticationProvider {
@ -47,68 +45,6 @@ public class DaoAuthenticationProvider
//~ Methods ================================================================ //~ Methods ================================================================
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
this.authenticationDao = authenticationDao;
}
public AuthenticationDao getAuthenticationDao() {
return authenticationDao;
}
/**
* By default the <code>DaoAuthenticationProvider</code> throws a
* <code>BadCredentialsException</code> if a username is not found or the
* password is incorrect. Setting this property to <code>false</code> will
* cause <code>UsernameNotFoundException</code>s to be thrown instead for
* the former. Note this is considered less secure than throwing
* <code>BadCredentialsException</code> for both exceptions.
*
* @param hideUserNotFoundExceptions set to <code>false</code> if you wish
* <code>UsernameNotFoundException</code>s to be thrown instead of
* the non-specific <code>BadCredentialsException</code> (defaults
* to <code>true</code>)
*/
public void setHideUserNotFoundExceptions(
boolean hideUserNotFoundExceptions) {
this.hideUserNotFoundExceptions = hideUserNotFoundExceptions;
}
public boolean isHideUserNotFoundExceptions() {
return hideUserNotFoundExceptions;
}
/**
* Sets the PasswordEncoder instance to be used to encode and validate
* passwords. If not set, {@link PlaintextPasswordEncoder} will be used by
* default.
*
* @param passwordEncoder The passwordEncoder to use
*/
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
public PasswordEncoder getPasswordEncoder() {
return passwordEncoder;
}
/**
* The source of salts to use when decoding passwords. <code>null</code>
* is a valid value, meaning the <code>DaoAuthenticationProvider</code>
* will present <code>null</code> to the relevant
* <code>PasswordEncoder</code>.
*
* @param saltSource to use when attempting to decode passwords via the
* <code>PasswordEncoder</code>
*/
public void setSaltSource(SaltSource saltSource) {
this.saltSource = saltSource;
}
public SaltSource getSaltSource() {
return saltSource;
}
protected void additionalAuthenticationChecks(UserDetails userDetails, protected void additionalAuthenticationChecks(UserDetails userDetails,
UsernamePasswordAuthenticationToken authentication) UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException { throws AuthenticationException {
@ -120,7 +56,9 @@ public class DaoAuthenticationProvider
if (!passwordEncoder.isPasswordValid(userDetails.getPassword(), if (!passwordEncoder.isPasswordValid(userDetails.getPassword(),
authentication.getCredentials().toString(), salt)) { authentication.getCredentials().toString(), salt)) {
throw new BadCredentialsException("Bad credentials", userDetails); throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials",
"Bad credentials"), userDetails);
} }
} }
@ -129,6 +67,22 @@ public class DaoAuthenticationProvider
"An Authentication DAO must be set"); "An Authentication DAO must be set");
} }
public AuthenticationDao getAuthenticationDao() {
return authenticationDao;
}
public PasswordEncoder getPasswordEncoder() {
return passwordEncoder;
}
public SaltSource getSaltSource() {
return saltSource;
}
public boolean isHideUserNotFoundExceptions() {
return hideUserNotFoundExceptions;
}
protected final UserDetails retrieveUser(String username, protected final UserDetails retrieveUser(String username,
UsernamePasswordAuthenticationToken authentication) UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException { throws AuthenticationException {
@ -138,7 +92,9 @@ public class DaoAuthenticationProvider
loadedUser = this.authenticationDao.loadUserByUsername(username); loadedUser = this.authenticationDao.loadUserByUsername(username);
} catch (UsernameNotFoundException notFound) { } catch (UsernameNotFoundException notFound) {
if (hideUserNotFoundExceptions) { if (hideUserNotFoundExceptions) {
throw new BadCredentialsException("Bad credentials presented"); throw new BadCredentialsException(messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials",
"Bad credentials"));
} else { } else {
throw notFound; throw notFound;
} }
@ -154,4 +110,52 @@ public class DaoAuthenticationProvider
return loadedUser; return loadedUser;
} }
}
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
this.authenticationDao = authenticationDao;
}
/**
* By default the <code>DaoAuthenticationProvider</code> throws a
* <code>BadCredentialsException</code> if a username is not found or
* the password is incorrect. Setting this property to
* <code>false</code> will cause
* <code>UsernameNotFoundException</code>s to be thrown instead for
* the former. Note this is considered less secure than throwing
* <code>BadCredentialsException</code> for both exceptions.
*
* @param hideUserNotFoundExceptions set to <code>false</code> if you
* wish <code>UsernameNotFoundException</code>s to be thrown
* instead of the non-specific
* <code>BadCredentialsException</code> (defaults to
* <code>true</code>)
*/
public void setHideUserNotFoundExceptions(
boolean hideUserNotFoundExceptions) {
this.hideUserNotFoundExceptions = hideUserNotFoundExceptions;
}
/**
* Sets the PasswordEncoder instance to be used to encode and validate
* passwords. If not set, {@link PlaintextPasswordEncoder} will be
* used by default.
*
* @param passwordEncoder The passwordEncoder to use
*/
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
/**
* The source of salts to use when decoding passwords.
* <code>null</code> is a valid value, meaning the
* <code>DaoAuthenticationProvider</code> will present
* <code>null</code> to the relevant <code>PasswordEncoder</code>.
*
* @param saltSource to use when attempting to decode passwords via the
* <code>PasswordEncoder</code>
*/
public void setSaltSource(SaltSource saltSource) {
this.saltSource = saltSource;
}
}

View File

@ -18,6 +18,7 @@ package org.acegisecurity.providers.rememberme;
import org.acegisecurity.Authentication; import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationException;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.AuthenticationProvider;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -25,6 +26,10 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -37,32 +42,23 @@ import org.springframework.util.Assert;
* org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken#getKeyHash()} * org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken#getKeyHash()}
* must match this class' {@link #getKey()}. * must match this class' {@link #getKey()}.
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public class RememberMeAuthenticationProvider implements AuthenticationProvider, public class RememberMeAuthenticationProvider implements AuthenticationProvider,
InitializingBean { InitializingBean, MessageSourceAware {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(RememberMeAuthenticationProvider.class); private static final Log logger = LogFactory.getLog(RememberMeAuthenticationProvider.class);
//~ Instance fields ======================================================== //~ Instance fields ========================================================
protected MessageSourceAccessor messages;
private String key; private String key;
//~ Methods ================================================================ //~ Methods ================================================================
public void setKey(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.hasLength(key); Assert.hasLength(key);
Assert.notNull(this.messages, "A message source must be set");
} }
public Authentication authenticate(Authentication authentication) public Authentication authenticate(Authentication authentication)
@ -73,13 +69,26 @@ public class RememberMeAuthenticationProvider implements AuthenticationProvider,
if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication) if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication)
.getKeyHash()) { .getKeyHash()) {
throw new BadCredentialsException( throw new BadCredentialsException(messages.getMessage(
"The presented RememberMeAuthenticationToken does not contain the expected key"); "RememberMeAuthenticationProvider.incorrectKey",
"The presented RememberMeAuthenticationToken does not contain the expected key"));
} }
return authentication; return authentication;
} }
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public boolean supports(Class authentication) { public boolean supports(Class authentication) {
return (RememberMeAuthenticationToken.class.isAssignableFrom(authentication)); return (RememberMeAuthenticationToken.class.isAssignableFrom(authentication));
} }

View File

@ -15,71 +15,81 @@
package org.acegisecurity.providers.x509; package org.acegisecurity.providers.x509;
import org.acegisecurity.providers.AuthenticationProvider;
import org.acegisecurity.providers.x509.cache.NullX509UserCache;
import org.acegisecurity.Authentication; import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationException;
import org.acegisecurity.UserDetails;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.springframework.beans.factory.InitializingBean; import org.acegisecurity.UserDetails;
import org.springframework.util.Assert;
import org.acegisecurity.providers.AuthenticationProvider;
import org.acegisecurity.providers.x509.cache.NullX509UserCache;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
/** /**
* Processes an X.509 authentication request. * Processes an X.509 authentication request.
* <p>
* The request will typically originate from
* {@link org.acegisecurity.ui.x509.X509ProcessingFilter}).
* </p>
* *
* @author Luke Taylor * <p>
* @version $Id$ * The request will typically originate from {@link
* org.acegisecurity.ui.x509.X509ProcessingFilter}).
* </p>
*/ */
public class X509AuthenticationProvider implements AuthenticationProvider, public class X509AuthenticationProvider implements AuthenticationProvider,
InitializingBean { InitializingBean, MessageSourceAware {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(X509AuthenticationProvider.class); private static final Log logger = LogFactory.getLog(X509AuthenticationProvider.class);
//~ Instance fields ======================================================== //~ Instance fields ========================================================
protected MessageSourceAccessor messages;
private X509AuthoritiesPopulator x509AuthoritiesPopulator; private X509AuthoritiesPopulator x509AuthoritiesPopulator;
private X509UserCache userCache = new NullX509UserCache(); private X509UserCache userCache = new NullX509UserCache();
//~ Methods ================================================================ //~ Methods ================================================================
public void setX509AuthoritiesPopulator(X509AuthoritiesPopulator x509AuthoritiesPopulator) {
this.x509AuthoritiesPopulator = x509AuthoritiesPopulator;
}
public void setX509UserCache(X509UserCache cache) {
this.userCache = cache;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.notNull(userCache, "An x509UserCache must be set"); Assert.notNull(userCache, "An x509UserCache must be set");
Assert.notNull(x509AuthoritiesPopulator, "An X509AuthoritiesPopulator must be set"); Assert.notNull(x509AuthoritiesPopulator,
"An X509AuthoritiesPopulator must be set");
Assert.notNull(this.messages, "A message source must be set");
} }
/** /**
* If the supplied authentication token contains a certificate then this will be passed * If the supplied authentication token contains a certificate then this
* to the configured {@link X509AuthoritiesPopulator} * will be passed to the configured {@link X509AuthoritiesPopulator} to
* to obtain the user details and authorities for the user identified by the certificate. * obtain the user details and authorities for the user identified by the
* certificate.
*
* <p> * <p>
* If no certificate is present (for example, if the filter is applied to an HttpRequest for which * If no certificate is present (for example, if the filter is applied to
* client authentication hasn't been configured in the container) then a BadCredentialsException will be raised. * an HttpRequest for which client authentication hasn't been configured
* in the container) then a BadCredentialsException will be raised.
* </p> * </p>
* *
* @param authentication the authentication request. * @param authentication the authentication request.
* @return an X509AuthenticationToken containing the authorities of the principal represented by the *
* certificate. * @return an X509AuthenticationToken containing the authorities of the
* @throws AuthenticationException if the {@link X509AuthoritiesPopulator} rejects the certficate. * principal represented by the certificate.
* @throws BadCredentialsException if no certificate was presented in the authentication request. *
* @throws AuthenticationException if the {@link X509AuthoritiesPopulator}
* rejects the certficate.
* @throws BadCredentialsException if no certificate was presented in the
* authentication request.
*/ */
public Authentication authenticate(Authentication authentication) throws AuthenticationException { public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
if (!supports(authentication.getClass())) { if (!supports(authentication.getClass())) {
return null; return null;
} }
@ -88,25 +98,42 @@ public class X509AuthenticationProvider implements AuthenticationProvider,
logger.debug("X509 authentication request: " + authentication); logger.debug("X509 authentication request: " + authentication);
} }
X509Certificate clientCertificate = (X509Certificate)authentication.getCredentials(); X509Certificate clientCertificate = (X509Certificate) authentication
.getCredentials();
if(clientCertificate == null) { if (clientCertificate == null) {
throw new BadCredentialsException("Certificate is null."); throw new BadCredentialsException(messages.getMessage(
"X509AuthenticationProvider.certificateNull",
"Certificate is null"));
} }
UserDetails user = userCache.getUserFromCache(clientCertificate); UserDetails user = userCache.getUserFromCache(clientCertificate);
if(user == null) { if (user == null) {
logger.debug("Authenticating with certificate " + clientCertificate); logger.debug("Authenticating with certificate "
+ clientCertificate);
user = x509AuthoritiesPopulator.getUserDetails(clientCertificate); user = x509AuthoritiesPopulator.getUserDetails(clientCertificate);
userCache.putUserInCache(clientCertificate, user); userCache.putUserInCache(clientCertificate, user);
} }
return new X509AuthenticationToken(user, clientCertificate, user.getAuthorities()); return new X509AuthenticationToken(user, clientCertificate,
user.getAuthorities());
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public void setX509AuthoritiesPopulator(
X509AuthoritiesPopulator x509AuthoritiesPopulator) {
this.x509AuthoritiesPopulator = x509AuthoritiesPopulator;
}
public void setX509UserCache(X509UserCache cache) {
this.userCache = cache;
} }
public boolean supports(Class authentication) { public boolean supports(Class authentication) {
return X509AuthenticationToken.class.isAssignableFrom(authentication); return X509AuthenticationToken.class.isAssignableFrom(authentication);
} }
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,29 +16,34 @@
package org.acegisecurity.providers.x509.populator; package org.acegisecurity.providers.x509.populator;
import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationException;
import org.acegisecurity.UserDetails;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.UserDetails;
import org.acegisecurity.providers.dao.AuthenticationDao; import org.acegisecurity.providers.dao.AuthenticationDao;
import org.acegisecurity.providers.x509.X509AuthoritiesPopulator; import org.acegisecurity.providers.x509.X509AuthoritiesPopulator;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.oro.text.regex.*; import org.apache.oro.text.regex.*;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
/** /**
* Populates the X509 authorities via an {@link org.acegisecurity.providers.dao.AuthenticationDao}. * Populates the X509 authorities via an {@link
* * org.acegisecurity.providers.dao.AuthenticationDao}.
* @author Luke Taylor
* @version $Id$
*/ */
public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator, public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator,
InitializingBean { InitializingBean, MessageSourceAware {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(DaoX509AuthoritiesPopulator.class); private static final Log logger = LogFactory.getLog(DaoX509AuthoritiesPopulator.class);
@ -46,18 +51,64 @@ public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator,
//~ Instance fields ======================================================== //~ Instance fields ========================================================
private AuthenticationDao authenticationDao; private AuthenticationDao authenticationDao;
private String subjectDNRegex = "CN=(.*?),"; protected MessageSourceAccessor messages;
private Pattern subjectDNPattern; private Pattern subjectDNPattern;
private String subjectDNRegex = "CN=(.*?),";
//~ Methods ================================================================ //~ Methods ================================================================
public void afterPropertiesSet() throws Exception {
Assert.notNull(authenticationDao, "An authenticationDao must be set");
Assert.notNull(this.messages, "A message source must be set");
Perl5Compiler compiler = new Perl5Compiler();
try {
subjectDNPattern = compiler.compile(subjectDNRegex,
Perl5Compiler.READ_ONLY_MASK
| Perl5Compiler.CASE_INSENSITIVE_MASK);
} catch (MalformedPatternException mpe) {
throw new IllegalArgumentException("Malformed regular expression: "
+ subjectDNRegex);
}
}
public UserDetails getUserDetails(X509Certificate clientCert)
throws AuthenticationException {
String subjectDN = clientCert.getSubjectDN().getName();
PatternMatcher matcher = new Perl5Matcher();
if (!matcher.contains(subjectDN, subjectDNPattern)) {
throw new BadCredentialsException(messages.getMessage(
"DaoX509AuthoritiesPopulator.noMatching",
new Object[] {subjectDN},
"No matching pattern was found in subjectDN: {0}"));
}
MatchResult match = matcher.getMatch();
if (match.groups() != 2) { // 2 = 1 + the entire match
throw new IllegalArgumentException(
"Regular expression must contain a single group ");
}
String userName = match.group(1);
return this.authenticationDao.loadUserByUsername(userName);
}
public void setAuthenticationDao(AuthenticationDao authenticationDao) { public void setAuthenticationDao(AuthenticationDao authenticationDao) {
this.authenticationDao = authenticationDao; this.authenticationDao = authenticationDao;
} }
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
/** /**
* Sets the regular expression which will by used to extract the user name * Sets the regular expression which will by used to extract the user name
* from the certificate's Subject DN. * from the certificate's Subject DN.
*
* <p> * <p>
* It should contain a single group; for example the default expression * It should contain a single group; for example the default expression
* "CN=(.*?)," matches the common name field. So "CN=Jimi Hendrix, OU=..." * "CN=(.*?)," matches the common name field. So "CN=Jimi Hendrix, OU=..."
@ -73,36 +124,4 @@ public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator,
public void setSubjectDNRegex(String subjectDNRegex) { public void setSubjectDNRegex(String subjectDNRegex) {
this.subjectDNRegex = subjectDNRegex; this.subjectDNRegex = subjectDNRegex;
} }
public UserDetails getUserDetails(X509Certificate clientCert)
throws AuthenticationException {
String subjectDN = clientCert.getSubjectDN().getName();
PatternMatcher matcher = new Perl5Matcher();
if(!matcher.contains(subjectDN , subjectDNPattern)) {
throw new BadCredentialsException("No matching pattern was found in subjectDN: " + subjectDN);
}
MatchResult match = matcher.getMatch();
if(match.groups() != 2) { // 2 = 1 + the entire match
throw new IllegalArgumentException("Regular expression must contain a single group ");
}
String userName = match.group(1);
return this.authenticationDao.loadUserByUsername(userName);
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(authenticationDao, "An authenticationDao must be set");
Perl5Compiler compiler = new Perl5Compiler();
try {
subjectDNPattern = compiler.compile(subjectDNRegex,
Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.CASE_INSENSITIVE_MASK);
} catch (MalformedPatternException mpe) {
throw new IllegalArgumentException("Malformed regular expression: " + subjectDNRegex);
}
}
} }

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,9 +18,15 @@ package org.acegisecurity.runas;
import org.acegisecurity.Authentication; import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationException;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.providers.AuthenticationProvider; import org.acegisecurity.providers.AuthenticationProvider;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -38,28 +44,19 @@ import org.springframework.util.Assert;
* <P> * <P>
* If the key does not match, a <code>BadCredentialsException</code> is thrown. * If the key does not match, a <code>BadCredentialsException</code> is thrown.
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public class RunAsImplAuthenticationProvider implements InitializingBean, public class RunAsImplAuthenticationProvider implements InitializingBean,
AuthenticationProvider { AuthenticationProvider, MessageSourceAware {
//~ Instance fields ======================================================== //~ Instance fields ========================================================
protected MessageSourceAccessor messages;
private String key; private String key;
//~ Methods ================================================================ //~ Methods ================================================================
public void setKey(String key) {
this.key = key;
}
public String getKey() {
return key;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.notNull(key, "A Key is required and should match that configured for the RunAsManagerImpl"); Assert.notNull(key,
"A Key is required and should match that configured for the RunAsManagerImpl");
} }
public Authentication authenticate(Authentication authentication) public Authentication authenticate(Authentication authentication)
@ -69,11 +66,24 @@ public class RunAsImplAuthenticationProvider implements InitializingBean,
if (token.getKeyHash() == key.hashCode()) { if (token.getKeyHash() == key.hashCode()) {
return authentication; return authentication;
} else { } else {
throw new BadCredentialsException( throw new BadCredentialsException(messages.getMessage(
"The presented RunAsUserToken does not contain the expected key"); "RunAsImplAuthenticationProvider.incorrectKey",
"The presented RunAsUserToken does not contain the expected key"));
} }
} }
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public boolean supports(Class authentication) { public boolean supports(Class authentication) {
if (RunAsUserToken.class.isAssignableFrom(authentication)) { if (RunAsUserToken.class.isAssignableFrom(authentication)) {
return true; return true;

View File

@ -15,7 +15,32 @@
package org.acegisecurity.ui; package org.acegisecurity.ui;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationManager;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent;
import org.acegisecurity.ui.rememberme.NullRememberMeServices;
import org.acegisecurity.ui.rememberme.RememberMeServices;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert;
import java.io.IOException; import java.io.IOException;
import java.util.Properties; import java.util.Properties;
import javax.servlet.Filter; import javax.servlet.Filter;
@ -27,21 +52,6 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; 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.event.authentication.InteractiveAuthenticationSuccessEvent;
import org.acegisecurity.ui.rememberme.NullRememberMeServices;
import org.acegisecurity.ui.rememberme.RememberMeServices;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.util.Assert;
/** /**
* Abstract processor of browser-based HTTP-based authentication requests. * Abstract processor of browser-based HTTP-based authentication requests.
@ -115,20 +125,16 @@ import org.springframework.util.Assert;
* *
* <p> * <p>
* If authentication is successful, an {@link * If authentication is successful, an {@link
* org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} will be * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent}
* published to the application context. No events will be published if * will be published to the application context. No events will be published
* authentication was unsuccessful, because this would generally be recorded * if authentication was unsuccessful, because this would generally be
* via an <code>AuthenticationManager</code>-specific application event. * recorded via an <code>AuthenticationManager</code>-specific application
* event.
* </p> * </p>
*
* @author Ben Alex
* @author colin sampaleanu
* @author Ray Krueger
* @version $Id$
*/ */
public abstract class AbstractProcessingFilter implements Filter, public abstract class AbstractProcessingFilter implements Filter,
InitializingBean, ApplicationEventPublisherAware { InitializingBean, ApplicationEventPublisherAware, MessageSourceAware {
//~ Static fields/initializersApplicationContextAware ============================================= //~ Static fields/initializers =============================================
public static final String ACEGI_SECURITY_TARGET_URL_KEY = "ACEGI_SECURITY_TARGET_URL"; public static final String ACEGI_SECURITY_TARGET_URL_KEY = "ACEGI_SECURITY_TARGET_URL";
public static final String ACEGI_SECURITY_LAST_EXCEPTION_KEY = "ACEGI_SECURITY_LAST_EXCEPTION"; public static final String ACEGI_SECURITY_LAST_EXCEPTION_KEY = "ACEGI_SECURITY_LAST_EXCEPTION";
@ -138,6 +144,7 @@ public abstract class AbstractProcessingFilter implements Filter,
private ApplicationEventPublisher eventPublisher; private ApplicationEventPublisher eventPublisher;
private AuthenticationManager authenticationManager; private AuthenticationManager authenticationManager;
protected MessageSourceAccessor messages;
private Properties exceptionMappings = new Properties(); private Properties exceptionMappings = new Properties();
private RememberMeServices rememberMeServices = new NullRememberMeServices(); private RememberMeServices rememberMeServices = new NullRememberMeServices();
@ -173,65 +180,15 @@ public abstract class AbstractProcessingFilter implements Filter,
//~ Methods ================================================================ //~ Methods ================================================================
public void setAlwaysUseDefaultTargetUrl(boolean alwaysUseDefaultTargetUrl) { public void afterPropertiesSet() throws Exception {
this.alwaysUseDefaultTargetUrl = alwaysUseDefaultTargetUrl; Assert.hasLength(filterProcessesUrl,
} "filterProcessesUrl must be specified");
Assert.hasLength(defaultTargetUrl, "defaultTargetUrl must be specified");
public boolean isAlwaysUseDefaultTargetUrl() { Assert.hasLength(authenticationFailureUrl,
return alwaysUseDefaultTargetUrl; "authenticationFailureUrl must be specified");
} Assert.notNull(authenticationManager,
"authenticationManager must be specified");
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) { Assert.notNull(this.rememberMeServices);
this.eventPublisher = eventPublisher;
}
public void setContinueChainBeforeSuccessfulAuthentication(
boolean continueChainBeforeSuccessfulAuthentication) {
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
}
public boolean isContinueChainBeforeSuccessfulAuthentication() {
return continueChainBeforeSuccessfulAuthentication;
}
/**
* Specifies the default <code>filterProcessesUrl</code> for the
* implementation.
*
* @return the default <code>filterProcessesUrl</code>
*/
public abstract String getDefaultFilterProcessesUrl();
public void setDefaultTargetUrl(String defaultTargetUrl) {
this.defaultTargetUrl = defaultTargetUrl;
}
public String getDefaultTargetUrl() {
return defaultTargetUrl;
}
public void setExceptionMappings(Properties exceptionMappings) {
this.exceptionMappings = exceptionMappings;
}
public Properties getExceptionMappings() {
return new Properties(exceptionMappings);
}
public void setFilterProcessesUrl(String filterProcessesUrl) {
this.filterProcessesUrl = filterProcessesUrl;
}
public String getFilterProcessesUrl() {
return filterProcessesUrl;
}
public void setRememberMeServices(RememberMeServices rememberMeServices) {
this.rememberMeServices = rememberMeServices;
}
public RememberMeServices getRememberMeServices() {
return rememberMeServices;
} }
/** /**
@ -247,34 +204,6 @@ public abstract class AbstractProcessingFilter implements Filter,
public abstract Authentication attemptAuthentication( public abstract Authentication attemptAuthentication(
HttpServletRequest request) throws AuthenticationException; HttpServletRequest request) throws AuthenticationException;
public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
this.authenticationFailureUrl = authenticationFailureUrl;
}
public String getAuthenticationFailureUrl() {
return authenticationFailureUrl;
}
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
public AuthenticationManager getAuthenticationManager() {
return authenticationManager;
}
public void afterPropertiesSet() throws Exception {
Assert.hasLength(filterProcessesUrl,
"filterProcessesUrl must be specified");
Assert.hasLength(defaultTargetUrl, "defaultTargetUrl must be specified");
Assert.hasLength(authenticationFailureUrl,
"authenticationFailureUrl must be specified");
Assert.notNull(authenticationManager,
"authenticationManager must be specified");
Assert.notNull(this.rememberMeServices);
}
/** /**
* Does nothing. We use IoC container lifecycle services instead. * Does nothing. We use IoC container lifecycle services instead.
*/ */
@ -324,6 +253,38 @@ public abstract class AbstractProcessingFilter implements Filter,
chain.doFilter(request, response); chain.doFilter(request, response);
} }
public String getAuthenticationFailureUrl() {
return authenticationFailureUrl;
}
public AuthenticationManager getAuthenticationManager() {
return authenticationManager;
}
/**
* Specifies the default <code>filterProcessesUrl</code> for the
* implementation.
*
* @return the default <code>filterProcessesUrl</code>
*/
public abstract String getDefaultFilterProcessesUrl();
public String getDefaultTargetUrl() {
return defaultTargetUrl;
}
public Properties getExceptionMappings() {
return new Properties(exceptionMappings);
}
public String getFilterProcessesUrl() {
return filterProcessesUrl;
}
public RememberMeServices getRememberMeServices() {
return rememberMeServices;
}
/** /**
* Does nothing. We use IoC container lifecycle services instead. * Does nothing. We use IoC container lifecycle services instead.
* *
@ -333,6 +294,14 @@ public abstract class AbstractProcessingFilter implements Filter,
*/ */
public void init(FilterConfig arg0) throws ServletException {} public void init(FilterConfig arg0) throws ServletException {}
public boolean isAlwaysUseDefaultTargetUrl() {
return alwaysUseDefaultTargetUrl;
}
public boolean isContinueChainBeforeSuccessfulAuthentication() {
return continueChainBeforeSuccessfulAuthentication;
}
protected void onPreAuthentication(HttpServletRequest request, protected void onPreAuthentication(HttpServletRequest request,
HttpServletResponse response) throws IOException {} HttpServletResponse response) throws IOException {}
@ -380,6 +349,49 @@ public abstract class AbstractProcessingFilter implements Filter,
return uri.endsWith(request.getContextPath() + filterProcessesUrl); return uri.endsWith(request.getContextPath() + filterProcessesUrl);
} }
public void setAlwaysUseDefaultTargetUrl(boolean alwaysUseDefaultTargetUrl) {
this.alwaysUseDefaultTargetUrl = alwaysUseDefaultTargetUrl;
}
public void setApplicationEventPublisher(
ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
this.authenticationFailureUrl = authenticationFailureUrl;
}
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
public void setContinueChainBeforeSuccessfulAuthentication(
boolean continueChainBeforeSuccessfulAuthentication) {
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
}
public void setDefaultTargetUrl(String defaultTargetUrl) {
this.defaultTargetUrl = defaultTargetUrl;
}
public void setExceptionMappings(Properties exceptionMappings) {
this.exceptionMappings = exceptionMappings;
}
public void setFilterProcessesUrl(String filterProcessesUrl) {
this.filterProcessesUrl = filterProcessesUrl;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public void setRememberMeServices(RememberMeServices rememberMeServices) {
this.rememberMeServices = rememberMeServices;
}
protected void successfulAuthentication(HttpServletRequest request, protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response, Authentication authResult) HttpServletResponse response, Authentication authResult)
throws IOException { throws IOException {
@ -395,7 +407,8 @@ public abstract class AbstractProcessingFilter implements Filter,
+ authResult + "'"); + authResult + "'");
} }
String targetUrl = (String) request.getSession().getAttribute(ACEGI_SECURITY_TARGET_URL_KEY); String targetUrl = (String) request.getSession()
.getAttribute(ACEGI_SECURITY_TARGET_URL_KEY);
request.getSession().removeAttribute(ACEGI_SECURITY_TARGET_URL_KEY); request.getSession().removeAttribute(ACEGI_SECURITY_TARGET_URL_KEY);
if (alwaysUseDefaultTargetUrl == true) { if (alwaysUseDefaultTargetUrl == true) {
@ -444,8 +457,8 @@ public abstract class AbstractProcessingFilter implements Filter,
} }
try { try {
request.getSession().setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY, request.getSession()
failed); .setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed);
} catch (Exception ignored) {} } catch (Exception ignored) {}
onUnsuccessfulAuthentication(request, response); onUnsuccessfulAuthentication(request, response);

View File

@ -19,13 +19,17 @@ import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationServiceException; import org.acegisecurity.AuthenticationServiceException;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.UserDetails; import org.acegisecurity.UserDetails;
import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.dao.AuthenticationDao; import org.acegisecurity.providers.dao.AuthenticationDao;
import org.acegisecurity.providers.dao.UserCache; import org.acegisecurity.providers.dao.UserCache;
import org.acegisecurity.providers.dao.UsernameNotFoundException; import org.acegisecurity.providers.dao.UsernameNotFoundException;
import org.acegisecurity.providers.dao.cache.NullUserCache; import org.acegisecurity.providers.dao.cache.NullUserCache;
import org.acegisecurity.ui.WebAuthenticationDetails; import org.acegisecurity.ui.WebAuthenticationDetails;
import org.acegisecurity.util.StringSplitUtils; import org.acegisecurity.util.StringSplitUtils;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
@ -35,6 +39,10 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -72,19 +80,22 @@ import javax.servlet.http.HttpServletResponse;
* <p> * <p>
* This Digest implementation has been designed to avoid needing to store * This Digest implementation has been designed to avoid needing to store
* session state between invocations. All session management information is * session state between invocations. All session management information is
* stored in the "nonce" that is sent to the client by the {@link DigestProcessingFilterEntryPoint}. * stored in the "nonce" that is sent to the client by the {@link
* DigestProcessingFilterEntryPoint}.
* </p> * </p>
* *
* <P> * <P>
* If authentication is successful, the resulting {@link org.acegisecurity.Authentication Authentication} * If authentication is successful, the resulting {@link
* object will be placed into the <code>SecurityContextHolder</code>. * org.acegisecurity.Authentication Authentication} object will be placed into
* the <code>SecurityContextHolder</code>.
* </p> * </p>
* *
* <p> * <p>
* If authentication fails, an * If authentication fails, an {@link
* {@link org.acegisecurity.intercept.web.AuthenticationEntryPoint AuthenticationEntryPoint} * org.acegisecurity.intercept.web.AuthenticationEntryPoint
* implementation is called. This must always be {@link DigestProcessingFilterEntryPoint}, * AuthenticationEntryPoint} implementation is called. This must always be
* which will prompt the user to authenticate again via Digest authentication. * {@link DigestProcessingFilterEntryPoint}, which will prompt the user to
* authenticate again via Digest authentication.
* </p> * </p>
* *
* <P> * <P>
@ -100,11 +111,9 @@ import javax.servlet.http.HttpServletResponse;
* <code>web.xml</code> to use the {@link * <code>web.xml</code> to use the {@link
* org.acegisecurity.util.FilterToBeanProxy}. * org.acegisecurity.util.FilterToBeanProxy}.
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public class DigestProcessingFilter implements Filter, InitializingBean { public class DigestProcessingFilter implements Filter, InitializingBean,
MessageSourceAware {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(DigestProcessingFilter.class); private static final Log logger = LogFactory.getLog(DigestProcessingFilter.class);
@ -113,32 +122,12 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
private AuthenticationDao authenticationDao; private AuthenticationDao authenticationDao;
private DigestProcessingFilterEntryPoint authenticationEntryPoint; private DigestProcessingFilterEntryPoint authenticationEntryPoint;
protected MessageSourceAccessor messages;
private UserCache userCache = new NullUserCache(); private UserCache userCache = new NullUserCache();
private boolean passwordAlreadyEncoded = false; private boolean passwordAlreadyEncoded = false;
//~ Methods ================================================================ //~ Methods ================================================================
public void setPasswordAlreadyEncoded(boolean passwordAlreadyEncoded) {
this.passwordAlreadyEncoded = passwordAlreadyEncoded;
}
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
this.authenticationDao = authenticationDao;
}
public AuthenticationDao getAuthenticationDao() {
return authenticationDao;
}
public void setAuthenticationEntryPoint(
DigestProcessingFilterEntryPoint authenticationEntryPoint) {
this.authenticationEntryPoint = authenticationEntryPoint;
}
public DigestProcessingFilterEntryPoint getAuthenticationEntryPoint() {
return authenticationEntryPoint;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.notNull(authenticationDao, "An AuthenticationDao is required"); Assert.notNull(authenticationDao, "An AuthenticationDao is required");
Assert.notNull(authenticationEntryPoint, Assert.notNull(authenticationEntryPoint,
@ -169,8 +158,7 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
if ((header != null) && header.startsWith("Digest ")) { if ((header != null) && header.startsWith("Digest ")) {
String section212response = header.substring(7); String section212response = header.substring(7);
String[] headerEntries = StringUtils String[] headerEntries = StringUtils.commaDelimitedListToStringArray(section212response);
.commaDelimitedListToStringArray(section212response);
Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries, Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries,
"=", "\""); "=", "\"");
@ -194,9 +182,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
} }
fail(request, response, fail(request, response,
new BadCredentialsException( new BadCredentialsException(messages.getMessage(
"Missing mandatory digest value; received header '" "DigestProcessingFilter.missingMandatory",
+ section212response + "'")); new Object[] {section212response},
"Missing mandatory digest value; received header {0}")));
return; return;
} }
@ -210,9 +199,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
} }
fail(request, response, fail(request, response,
new BadCredentialsException( new BadCredentialsException(messages.getMessage(
"Missing mandatory digest value for 'auth' QOP; received header '" "DigestProcessingFilter.missingAuth",
+ section212response + "'")); new Object[] {section212response},
"Missing mandatory digest value; received header {0}")));
return; return;
} }
@ -221,10 +211,11 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
// Check realm name equals what we expected // Check realm name equals what we expected
if (!this.getAuthenticationEntryPoint().getRealmName().equals(realm)) { if (!this.getAuthenticationEntryPoint().getRealmName().equals(realm)) {
fail(request, response, fail(request, response,
new BadCredentialsException("Response realm name '" + realm new BadCredentialsException(messages.getMessage(
+ "' does not match system realm name of '" "DigestProcessingFilter.incorrectRealm",
+ this.getAuthenticationEntryPoint().getRealmName() new Object[] {realm, this.getAuthenticationEntryPoint()
+ "'")); .getRealmName()},
"Response realm name '{0}' does not match system realm name of '{1}'")));
return; return;
} }
@ -232,9 +223,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
// Check nonce was a Base64 encoded (as sent by DigestProcessingFilterEntryPoint) // Check nonce was a Base64 encoded (as sent by DigestProcessingFilterEntryPoint)
if (!Base64.isArrayByteBase64(nonce.getBytes())) { if (!Base64.isArrayByteBase64(nonce.getBytes())) {
fail(request, response, fail(request, response,
new BadCredentialsException( new BadCredentialsException(messages.getMessage(
"Nonce is not encoded in Base64; received nonce: '" "DigestProcessingFilter.nonceEncoding",
+ nonce + "'")); new Object[] {nonce},
"Nonce is not encoded in Base64; received nonce {0}")));
return; return;
} }
@ -249,9 +241,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
if (nonceTokens.length != 2) { if (nonceTokens.length != 2) {
fail(request, response, fail(request, response,
new BadCredentialsException( new BadCredentialsException(messages.getMessage(
"Nonce should have yielded two tokens but was: '" "DigestProcessingFilter.nonceNotTwoTokens",
+ nonceAsPlainText + "'")); new Object[] {nonceAsPlainText},
"Nonce should have yielded two tokens but was {0}")));
return; return;
} }
@ -263,9 +256,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
nonceExpiryTime = new Long(nonceTokens[0]).longValue(); nonceExpiryTime = new Long(nonceTokens[0]).longValue();
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
fail(request, response, fail(request, response,
new BadCredentialsException( new BadCredentialsException(messages.getMessage(
"Nonce token should have yielded a numeric first token, but was: '" "DigestProcessingFilter.nonceNotNumeric",
+ nonceAsPlainText + "'")); new Object[] {nonceAsPlainText},
"Nonce token should have yielded a numeric first token, but was {0}")));
return; return;
} }
@ -276,14 +270,17 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
if (!expectedNonceSignature.equals(nonceTokens[1])) { if (!expectedNonceSignature.equals(nonceTokens[1])) {
fail(request, response, fail(request, response,
new BadCredentialsException("Nonce token compromised: '" new BadCredentialsException(messages.getMessage(
+ nonceAsPlainText + "'")); "DigestProcessingFilter.nonceCompromised",
new Object[] {nonceAsPlainText},
"Nonce token compromised {0}")));
return; return;
} }
// Lookup password for presented username // Lookup password for presented username
// NB: DAO-provided password MUST be clear text - not encoded/salted // NB: DAO-provided password MUST be clear text - not encoded/salted
// (unless this instance's passwordAlreadyEncoded property is 'false')
boolean loadedFromDao = false; boolean loadedFromDao = false;
UserDetails user = userCache.getUserFromCache(username); UserDetails user = userCache.getUserFromCache(username);
@ -294,8 +291,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
user = authenticationDao.loadUserByUsername(username); user = authenticationDao.loadUserByUsername(username);
} catch (UsernameNotFoundException notFound) { } catch (UsernameNotFoundException notFound) {
fail(request, response, fail(request, response,
new BadCredentialsException("Username '" + username new BadCredentialsException(messages.getMessage(
+ "' not known")); "DigestProcessingFilter.usernameNotFound",
new Object[] {username},
"Username {0} not found")));
return; return;
} }
@ -312,8 +311,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
String serverDigestMd5; String serverDigestMd5;
// Don't catch IllegalArgumentException (already checked validity) // Don't catch IllegalArgumentException (already checked validity)
serverDigestMd5 = generateDigest(passwordAlreadyEncoded, username, realm, serverDigestMd5 = generateDigest(passwordAlreadyEncoded, username,
user.getPassword(), realm, user.getPassword(),
((HttpServletRequest) request).getMethod(), uri, qop, ((HttpServletRequest) request).getMethod(), uri, qop,
nonce, nc, cnonce); nonce, nc, cnonce);
@ -329,15 +328,17 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
} catch (UsernameNotFoundException notFound) { } catch (UsernameNotFoundException notFound) {
// Would very rarely happen, as user existed earlier // Would very rarely happen, as user existed earlier
fail(request, response, fail(request, response,
new BadCredentialsException("Username '" + username new BadCredentialsException(messages.getMessage(
+ "' not known")); "DigestProcessingFilter.usernameNotFound",
new Object[] {username},
"Username {0} not found")));
} }
userCache.putUserInCache(user); userCache.putUserInCache(user);
// Don't catch IllegalArgumentException (already checked validity) // Don't catch IllegalArgumentException (already checked validity)
serverDigestMd5 = generateDigest(passwordAlreadyEncoded, username, realm, serverDigestMd5 = generateDigest(passwordAlreadyEncoded,
user.getPassword(), username, realm, user.getPassword(),
((HttpServletRequest) request).getMethod(), uri, qop, ((HttpServletRequest) request).getMethod(), uri, qop,
nonce, nc, cnonce); nonce, nc, cnonce);
} }
@ -351,7 +352,9 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
} }
fail(request, response, fail(request, response,
new BadCredentialsException("Incorrect response")); new BadCredentialsException(messages.getMessage(
"DigestProcessingFilter.incorrectResponse",
"Incorrect response")));
return; return;
} }
@ -362,7 +365,9 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
// but the request was otherwise appearing to be valid // but the request was otherwise appearing to be valid
if (nonceExpiryTime < System.currentTimeMillis()) { if (nonceExpiryTime < System.currentTimeMillis()) {
fail(request, response, fail(request, response,
new NonceExpiredException("Nonce has expired/timed out")); new NonceExpiredException(messages.getMessage(
"DigestProcessingFilter.nonceExpired",
"Nonce has expired/timed out")));
return; return;
} }
@ -382,18 +387,32 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
chain.doFilter(request, response); chain.doFilter(request, response);
} }
public static String encodePasswordInA1Format(String username, String realm, String password) { public static String encodePasswordInA1Format(String username,
String realm, String password) {
String a1 = username + ":" + realm + ":" + password; String a1 = username + ":" + realm + ":" + password;
String a1Md5 = new String(DigestUtils.md5Hex(a1)); String a1Md5 = new String(DigestUtils.md5Hex(a1));
return a1Md5; return a1Md5;
} }
private void fail(ServletRequest request, ServletResponse response,
AuthenticationException failed) throws IOException, ServletException {
SecurityContextHolder.getContext().setAuthentication(null);
if (logger.isDebugEnabled()) {
logger.debug(failed);
}
authenticationEntryPoint.commence(request, response, failed);
}
/** /**
* Computes the <code>response</code> portion of a Digest authentication * Computes the <code>response</code> portion of a Digest authentication
* header. Both the server and user agent should compute the * header. Both the server and user agent should compute the
* <code>response</code> independently. Provided as a static method to * <code>response</code> independently. Provided as a static method to
* simplify the coding of user agents. * simplify the coding of user agents.
* *
* @param passwordAlreadyEncoded DOCUMENT ME!
* @param username DOCUMENT ME! * @param username DOCUMENT ME!
* @param realm DOCUMENT ME! * @param realm DOCUMENT ME!
* @param password DOCUMENT ME! * @param password DOCUMENT ME!
@ -408,9 +427,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
* *
* @throws IllegalArgumentException DOCUMENT ME! * @throws IllegalArgumentException DOCUMENT ME!
*/ */
public static String generateDigest(boolean passwordAlreadyEncoded, String username, String realm, public static String generateDigest(boolean passwordAlreadyEncoded,
String password, String httpMethod, String uri, String qop, String username, String realm, String password, String httpMethod,
String nonce, String nc, String cnonce) throws IllegalArgumentException { String uri, String qop, String nonce, String nc, String cnonce)
throws IllegalArgumentException {
String a1Md5 = null; String a1Md5 = null;
String a2 = httpMethod + ":" + uri; String a2 = httpMethod + ":" + uri;
String a2Md5 = new String(DigestUtils.md5Hex(a2)); String a2Md5 = new String(DigestUtils.md5Hex(a2));
@ -440,8 +460,12 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
return digestMd5; return digestMd5;
} }
public void setUserCache(UserCache userCache) { public AuthenticationDao getAuthenticationDao() {
this.userCache = userCache; return authenticationDao;
}
public DigestProcessingFilterEntryPoint getAuthenticationEntryPoint() {
return authenticationEntryPoint;
} }
public UserCache getUserCache() { public UserCache getUserCache() {
@ -450,14 +474,24 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
public void init(FilterConfig ignored) throws ServletException {} public void init(FilterConfig ignored) throws ServletException {}
private void fail(ServletRequest request, ServletResponse response, public void setAuthenticationDao(AuthenticationDao authenticationDao) {
AuthenticationException failed) throws IOException, ServletException { this.authenticationDao = authenticationDao;
SecurityContextHolder.getContext().setAuthentication(null);
if (logger.isDebugEnabled()) {
logger.debug(failed);
} }
authenticationEntryPoint.commence(request, response, failed); public void setAuthenticationEntryPoint(
DigestProcessingFilterEntryPoint authenticationEntryPoint) {
this.authenticationEntryPoint = authenticationEntryPoint;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
public void setPasswordAlreadyEncoded(boolean passwordAlreadyEncoded) {
this.passwordAlreadyEncoded = passwordAlreadyEncoded;
}
public void setUserCache(UserCache userCache) {
this.userCache = userCache;
} }
} }

View File

@ -22,12 +22,17 @@ import org.acegisecurity.AuthenticationException;
import org.acegisecurity.CredentialsExpiredException; import org.acegisecurity.CredentialsExpiredException;
import org.acegisecurity.DisabledException; import org.acegisecurity.DisabledException;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.LockedException;
import org.acegisecurity.UserDetails; import org.acegisecurity.UserDetails;
import org.acegisecurity.context.SecurityContextHolder; import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.event.authentication.AuthenticationSwitchUserEvent; import org.acegisecurity.event.authentication.AuthenticationSwitchUserEvent;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.dao.AuthenticationDao; import org.acegisecurity.providers.dao.AuthenticationDao;
import org.acegisecurity.providers.dao.UsernameNotFoundException; import org.acegisecurity.providers.dao.UsernameNotFoundException;
import org.acegisecurity.ui.WebAuthenticationDetails; import org.acegisecurity.ui.WebAuthenticationDetails;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -36,8 +41,11 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -80,8 +88,8 @@ import javax.servlet.http.HttpServletResponse;
* <p> * <p>
* On successful switch, the user's <code>SecurityContextHolder</code> will be * On successful switch, the user's <code>SecurityContextHolder</code> will be
* updated to reflect the specified user and will also contain an additinal * updated to reflect the specified user and will also contain an additinal
* {@link org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority } * {@link org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority } which
* which contains the original user. * contains the original user.
* </p> * </p>
* *
* <p> * <p>
@ -104,13 +112,10 @@ import javax.servlet.http.HttpServletResponse;
* </pre> * </pre>
* </p> * </p>
* *
* @author Mark St.Godard
* @version $Id$
*
* @see org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority * @see org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority
*/ */
public class SwitchUserProcessingFilter implements Filter, InitializingBean, public class SwitchUserProcessingFilter implements Filter, InitializingBean,
ApplicationEventPublisherAware { ApplicationEventPublisherAware, MessageSourceAware {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(SwitchUserProcessingFilter.class); private static final Log logger = LogFactory.getLog(SwitchUserProcessingFilter.class);
@ -127,105 +132,21 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
// ~ Instance fields // ~ Instance fields
// ======================================================== // ========================================================
private AuthenticationDao authenticationDao; private AuthenticationDao authenticationDao;
protected MessageSourceAccessor messages;
private String exitUserUrl = "/j_acegi_exit_user"; private String exitUserUrl = "/j_acegi_exit_user";
private String switchUserUrl = "/j_acegi_switch_user"; private String switchUserUrl = "/j_acegi_switch_user";
private String targetUrl; private String targetUrl;
//~ Methods ================================================================ //~ Methods ================================================================
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher)
throws BeansException {
this.eventPublisher = eventPublisher;
}
/**
* Sets the authentication data access object.
*
* @param authenticationDao The authentication dao
*/
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
this.authenticationDao = authenticationDao;
}
/**
* Set the URL to respond to exit user processing.
*
* @param exitUserUrl The exit user URL.
*/
public void setExitUserUrl(String exitUserUrl) {
this.exitUserUrl = exitUserUrl;
}
/**
* Set the URL to respond to switch user processing.
*
* @param switchUserUrl The switch user URL.
*/
public void setSwitchUserUrl(String switchUserUrl) {
this.switchUserUrl = switchUserUrl;
}
/**
* Sets the URL to go to after a successful switch / exit user request.
*
* @param targetUrl The target url.
*/
public void setTargetUrl(String targetUrl) {
this.targetUrl = targetUrl;
}
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
Assert.hasLength(switchUserUrl, "switchUserUrl must be specified"); Assert.hasLength(switchUserUrl, "switchUserUrl must be specified");
Assert.hasLength(exitUserUrl, "exitUserUrl must be specified"); Assert.hasLength(exitUserUrl, "exitUserUrl must be specified");
Assert.hasLength(targetUrl, "targetUrl must be specified"); Assert.hasLength(targetUrl, "targetUrl must be specified");
Assert.notNull(authenticationDao, "authenticationDao must be specified"); Assert.notNull(authenticationDao, "authenticationDao must be specified");
Assert.notNull(messages, "A message source must be set");
} }
public void destroy() {}
/**
* @see javax.servlet.Filter#doFilter
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
Assert.isInstanceOf(HttpServletRequest.class, request);
Assert.isInstanceOf(HttpServletResponse.class, response);
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// check for switch or exit request
if (requiresSwitchUser(httpRequest)) {
// if set, attempt switch and store original
Authentication targetUser = attemptSwitchUser(httpRequest);
// update the current context to the new target user
SecurityContextHolder.getContext().setAuthentication(targetUser);
// redirect to target url
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest
.getContextPath() + targetUrl));
return;
} else if (requiresExitUser(httpRequest)) {
// get the original authentication object (if exists)
Authentication originalUser = attemptExitUser(httpRequest);
// update the current context back to the original user
SecurityContextHolder.getContext().setAuthentication(originalUser);
// redirect to target url
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest
.getContextPath() + targetUrl));
return;
}
chain.doFilter(request, response);
}
public void init(FilterConfig ignored) throws ServletException {}
/** /**
* Attempt to exit from an already switched user. * Attempt to exit from an already switched user.
* *
@ -244,8 +165,9 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
.getAuthentication(); .getAuthentication();
if (null == current) { if (null == current) {
throw new AuthenticationCredentialsNotFoundException( throw new AuthenticationCredentialsNotFoundException(messages
"No current user associated with this request!"); .getMessage("SwitchUserProcessingFilter.noCurrentUser",
"No current user associated with this request"));
} }
// check to see if the current user did actual switch to another user // check to see if the current user did actual switch to another user
@ -253,9 +175,12 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
Authentication original = getSourceAuthentication(current); Authentication original = getSourceAuthentication(current);
if (original == null) { if (original == null) {
logger.error("Could not find original user Authentication object!"); logger.error(
throw new AuthenticationCredentialsNotFoundException( "Could not find original user Authentication object!");
"Could not find original Authentication object!"); throw new AuthenticationCredentialsNotFoundException(messages
.getMessage(
"SwitchUserProcessingFilter.noOriginalAuthentication",
"Could not find original Authentication object"));
} }
// get the source user details // get the source user details
@ -268,31 +193,35 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
// publish event // publish event
if (this.eventPublisher != null) { if (this.eventPublisher != null) {
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(current, eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
originalUser)); current, originalUser));
} }
return original; return original;
} }
/** /**
* Attempt to switch to another user. If the user does not exist or is not * Attempt to switch to another user. If the user does not exist or
* active, return null. * is not active, return null.
* *
* @param request The http request * @param request The http request
* *
* @return The new <code>Authentication</code> request if successfully * @return The new <code>Authentication</code> request if
* switched to another user, <code>null</code> otherwise. * successfully switched to another user,
* <code>null</code> otherwise.
* *
* @throws AuthenticationException * @throws AuthenticationException
* @throws UsernameNotFoundException If the target user is not found. * @throws UsernameNotFoundException If the target user is not
* found.
* @throws LockedException DOCUMENT ME!
* @throws DisabledException If the target user is disabled. * @throws DisabledException If the target user is disabled.
* @throws AccountExpiredException If the target user account is expired. * @throws AccountExpiredException If the target user account is
* @throws CredentialsExpiredException If the target user credentials are
* expired. * expired.
* @throws CredentialsExpiredException If the target user
* credentials are expired.
*/ */
protected Authentication attemptSwitchUser(HttpServletRequest request) protected Authentication attemptSwitchUser(
throws AuthenticationException { HttpServletRequest request) throws AuthenticationException {
UsernamePasswordAuthenticationToken targetUserRequest = null; UsernamePasswordAuthenticationToken targetUserRequest = null;
String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY); String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
@ -306,126 +235,66 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
} }
// load the user by name // load the user by name
UserDetails targetUser = this.authenticationDao.loadUserByUsername(username); UserDetails targetUser = this.authenticationDao
.loadUserByUsername(username);
// user not found // user not found
if (targetUser == null) { if (targetUser == null) {
throw new UsernameNotFoundException("User [" + username throw new UsernameNotFoundException(messages.getMessage(
+ "] cannot be found!"); "SwitchUserProcessingFilter.usernameNotFound",
new Object[] {username},
"Username {0} not found"));
}
// account is expired
if (!targetUser.isAccountNonLocked()) {
throw new LockedException(messages.getMessage(
"SwitchUserProcessingFilter.locked",
"User account is locked"));
} }
// user is disabled // user is disabled
if (!targetUser.isEnabled()) { if (!targetUser.isEnabled()) {
throw new DisabledException("User is disabled"); throw new DisabledException(messages.getMessage(
"SwitchUserProcessingFilter.disabled",
"User is disabled"));
} }
// account is expired // account is expired
if (!targetUser.isAccountNonExpired()) { if (!targetUser.isAccountNonExpired()) {
throw new AccountExpiredException("User account has expired"); throw new AccountExpiredException(messages.getMessage(
"SwitchUserProcessingFilter.expired",
"User account has expired"));
} }
// credentials expired // credentials expired
if (!targetUser.isCredentialsNonExpired()) { if (!targetUser.isCredentialsNonExpired()) {
throw new CredentialsExpiredException("User credentials expired"); throw new CredentialsExpiredException(messages
.getMessage(
"SwitchUserProcessingFilter.credentialsExpired",
"User credentials have expired"));
} }
// ok, create the switch user token // ok, create the switch user token
targetUserRequest = createSwitchUserToken(request, username, targetUser); targetUserRequest = createSwitchUserToken(request,
username, targetUser);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Switch User Token [" + targetUserRequest + "]"); logger.debug("Switch User Token ["
+ targetUserRequest + "]");
} }
// publish event // publish event
if (this.eventPublisher != null) { if (this.eventPublisher != null) {
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent( eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
SecurityContextHolder.getContext().getAuthentication(), SecurityContextHolder.getContext()
.getAuthentication(),
targetUser)); targetUser));
} }
return targetUserRequest; return targetUserRequest;
} }
/**
* Checks the request URI for the presence of <tt>exitUserUrl</tt>.
*
* @param request The http servlet request
*
* @return <code>true</code> if the request requires a exit user,
* <code>false</code> otherwise.
*
* @see SwitchUserProcessingFilter#exitUserUrl
*/
protected boolean requiresExitUser(HttpServletRequest request) {
String uri = stripUri(request);
return uri.endsWith(request.getContextPath() + exitUserUrl);
}
/**
* Checks the request URI for the presence of <tt>switchUserUrl</tt>.
*
* @param request The http servlet request
*
* @return <code>true</code> if the request requires a switch,
* <code>false</code> otherwise.
*
* @see SwitchUserProcessingFilter#switchUserUrl
*/
protected boolean requiresSwitchUser(HttpServletRequest request) {
String uri = stripUri(request);
return uri.endsWith(request.getContextPath() + switchUserUrl);
}
/**
* Strips any content after the ';' in the request URI
*
* @param request The http request
*
* @return The stripped uri
*/
private static String stripUri(HttpServletRequest request) {
String uri = request.getRequestURI();
int idx = uri.indexOf(';');
if (idx > 0) {
uri = uri.substring(0, idx);
}
return uri;
}
/**
* Find the original <code>Authentication</code> object from the current
* user's granted authorities. A successfully switched user should have a
* <code>SwitchUserGrantedAuthority</code> that contains the original
* source user <code>Authentication</code> object.
*
* @param current The current <code>Authentication</code> object
*
* @return The source user <code>Authentication</code> object or
* <code>null</code> otherwise.
*/
private Authentication getSourceAuthentication(Authentication current) {
Authentication original = null;
// iterate over granted authorities and find the 'switch user' authority
GrantedAuthority[] authorities = current.getAuthorities();
for (int i = 0; i < authorities.length; i++) {
// check for switch user type of authority
if (authorities[i] instanceof SwitchUserGrantedAuthority) {
original = ((SwitchUserGrantedAuthority) authorities[i])
.getSource();
logger.debug("Found original switch user granted authority ["
+ original + "]");
}
}
return original;
}
/** /**
* Create a switch user token that contains an additional * Create a switch user token that contains an additional
* <tt>GrantedAuthority</tt> that contains the original * <tt>GrantedAuthority</tt> that contains the original
@ -440,7 +309,8 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
* @see SwitchUserGrantedAuthority * @see SwitchUserGrantedAuthority
*/ */
private UsernamePasswordAuthenticationToken createSwitchUserToken( private UsernamePasswordAuthenticationToken createSwitchUserToken(
HttpServletRequest request, String username, UserDetails targetUser) { HttpServletRequest request, String username,
UserDetails targetUser) {
UsernamePasswordAuthenticationToken targetUserRequest; UsernamePasswordAuthenticationToken targetUserRequest;
// grant an additional authority that contains the original Authentication object // grant an additional authority that contains the original Authentication object
@ -465,8 +335,227 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
targetUser.getPassword(), authorities); targetUser.getPassword(), authorities);
// set details // set details
targetUserRequest.setDetails(new WebAuthenticationDetails(request)); targetUserRequest.setDetails(new WebAuthenticationDetails(
request));
return targetUserRequest; return targetUserRequest;
} }
}
public void destroy() {}
/**
* @see javax.servlet.Filter#doFilter
*/
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
Assert.isInstanceOf(HttpServletRequest.class, request);
Assert.isInstanceOf(HttpServletResponse.class, response);
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// check for switch or exit request
if (requiresSwitchUser(httpRequest)) {
// if set, attempt switch and store original
Authentication targetUser = attemptSwitchUser(httpRequest);
// update the current context to the new target user
SecurityContextHolder.getContext()
.setAuthentication(targetUser);
// redirect to target url
httpResponse.sendRedirect(httpResponse
.encodeRedirectURL(httpRequest
.getContextPath() + targetUrl));
return;
} else if (requiresExitUser(httpRequest)) {
// get the original authentication object (if exists)
Authentication originalUser = attemptExitUser(httpRequest);
// update the current context back to the original user
SecurityContextHolder.getContext()
.setAuthentication(originalUser);
// redirect to target url
httpResponse.sendRedirect(httpResponse
.encodeRedirectURL(httpRequest
.getContextPath()
+ targetUrl));
return;
}
chain.doFilter(request, response);
}
/**
* Find the original
* <code>Authentication</code> object from
* the current user's granted authorities.
* A successfully switched user should
* have a
* <code>SwitchUserGrantedAuthority</code>
* that contains the original source user
* <code>Authentication</code> object.
*
* @param current The current
* <code>Authentication</code>
* object
*
* @return The source user
* <code>Authentication</code>
* object or <code>null</code>
* otherwise.
*/
private Authentication getSourceAuthentication(
Authentication current) {
Authentication original = null;
// iterate over granted authorities and find the 'switch user' authority
GrantedAuthority[] authorities = current
.getAuthorities();
for (int i = 0; i < authorities.length;
i++) {
// check for switch user type of authority
if (authorities[i] instanceof SwitchUserGrantedAuthority) {
original = ((SwitchUserGrantedAuthority) authorities[i])
.getSource();
logger.debug(
"Found original switch user granted authority ["
+ original + "]");
}
}
return original;
}
public void init(FilterConfig ignored)
throws ServletException {}
/**
* Checks the request URI for the presence
* of <tt>exitUserUrl</tt>.
*
* @param request The http servlet request
*
* @return <code>true</code> if the request
* requires a exit user,
* <code>false</code> otherwise.
*
* @see SwitchUserProcessingFilter#exitUserUrl
*/
protected boolean requiresExitUser(
HttpServletRequest request) {
String uri = stripUri(request);
return uri.endsWith(request
.getContextPath() + exitUserUrl);
}
/**
* Checks the request URI for the
* presence of <tt>switchUserUrl</tt>.
*
* @param request The http servlet
* request
*
* @return <code>true</code> if the
* request requires a switch,
* <code>false</code>
* otherwise.
*
* @see SwitchUserProcessingFilter#switchUserUrl
*/
protected boolean requiresSwitchUser(
HttpServletRequest request) {
String uri = stripUri(request);
return uri.endsWith(request
.getContextPath()
+ switchUserUrl);
}
public void setApplicationEventPublisher(
ApplicationEventPublisher eventPublisher)
throws BeansException {
this.eventPublisher = eventPublisher;
}
/**
* Sets the authentication data
* access object.
*
* @param authenticationDao The
* authentication dao
*/
public void setAuthenticationDao(
AuthenticationDao authenticationDao) {
this.authenticationDao = authenticationDao;
}
/**
* Set the URL to respond to exit
* user processing.
*
* @param exitUserUrl The exit user
* URL.
*/
public void setExitUserUrl(
String exitUserUrl) {
this.exitUserUrl = exitUserUrl;
}
public void setMessageSource(
MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
/**
* Set the URL to respond to switch
* user processing.
*
* @param switchUserUrl The switch
* user URL.
*/
public void setSwitchUserUrl(
String switchUserUrl) {
this.switchUserUrl = switchUserUrl;
}
/**
* Sets the URL to go to after a
* successful switch / exit user
* request.
*
* @param targetUrl The target url.
*/
public void setTargetUrl(
String targetUrl) {
this.targetUrl = targetUrl;
}
/**
* Strips any content after the ';'
* in the request URI
*
* @param request The http request
*
* @return The stripped uri
*/
private static String stripUri(
HttpServletRequest request) {
String uri = request
.getRequestURI();
int idx = uri.indexOf(';');
if (idx > 0) {
uri = uri.substring(0,
idx);
}
return uri;
}
}

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,6 +20,12 @@ import org.acegisecurity.ConfigAttribute;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.util.Assert;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -32,28 +38,42 @@ import java.util.List;
* AccessDecisionVoter}s and the access control behaviour if all voters * AccessDecisionVoter}s and the access control behaviour if all voters
* abstain from voting (defaults to deny access). * abstain from voting (defaults to deny access).
* </p> * </p>
*
* @author Ben Alex
* @version $Id$
*/ */
public abstract class AbstractAccessDecisionManager public abstract class AbstractAccessDecisionManager
implements AccessDecisionManager, InitializingBean { implements AccessDecisionManager, InitializingBean, MessageSourceAware {
//~ Instance fields ======================================================== //~ Instance fields ========================================================
private List decisionVoters; private List decisionVoters;
protected MessageSourceAccessor messages;
private boolean allowIfAllAbstainDecisions = false; private boolean allowIfAllAbstainDecisions = false;
//~ Methods ================================================================ //~ Methods ================================================================
public void setAllowIfAllAbstainDecisions( public void afterPropertiesSet() throws Exception {
boolean allowIfAllAbstainDecisions) { checkIfValidList(this.decisionVoters);
this.allowIfAllAbstainDecisions = allowIfAllAbstainDecisions; Assert.notNull(this.messages, "A message source must be set");
}
private void checkIfValidList(List listToCheck) {
if ((listToCheck == null) || (listToCheck.size() == 0)) {
throw new IllegalArgumentException(
"A list of AccessDecisionVoters is required");
}
}
public List getDecisionVoters() {
return this.decisionVoters;
} }
public boolean isAllowIfAllAbstainDecisions() { public boolean isAllowIfAllAbstainDecisions() {
return allowIfAllAbstainDecisions; return allowIfAllAbstainDecisions;
} }
public void setAllowIfAllAbstainDecisions(
boolean allowIfAllAbstainDecisions) {
this.allowIfAllAbstainDecisions = allowIfAllAbstainDecisions;
}
public void setDecisionVoters(List newList) { public void setDecisionVoters(List newList) {
checkIfValidList(newList); checkIfValidList(newList);
@ -76,12 +96,8 @@ public abstract class AbstractAccessDecisionManager
this.decisionVoters = newList; this.decisionVoters = newList;
} }
public List getDecisionVoters() { public void setMessageSource(MessageSource messageSource) {
return this.decisionVoters; this.messages = new MessageSourceAccessor(messageSource);
}
public void afterPropertiesSet() throws Exception {
checkIfValidList(this.decisionVoters);
} }
public boolean supports(ConfigAttribute attribute) { public boolean supports(ConfigAttribute attribute) {
@ -124,11 +140,4 @@ public abstract class AbstractAccessDecisionManager
return true; return true;
} }
private void checkIfValidList(List listToCheck) {
if ((listToCheck == null) || (listToCheck.size() == 0)) {
throw new IllegalArgumentException(
"A list of AccessDecisionVoters is required");
}
}
} }

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -29,9 +29,6 @@ import java.util.Iterator;
* Simple concrete implementation of {@link * Simple concrete implementation of {@link
* org.acegisecurity.AccessDecisionManager} that grants access if any * org.acegisecurity.AccessDecisionManager} that grants access if any
* <code>AccessDecisionVoter</code> returns an affirmative response. * <code>AccessDecisionVoter</code> returns an affirmative response.
*
* @author Ben Alex
* @version $Id$
*/ */
public class AffirmativeBased extends AbstractAccessDecisionManager { public class AffirmativeBased extends AbstractAccessDecisionManager {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
@ -83,14 +80,18 @@ public class AffirmativeBased extends AbstractAccessDecisionManager {
} }
if (deny > 0) { if (deny > 0) {
throw new AccessDeniedException("Access is denied."); throw new AccessDeniedException(messages.getMessage(
"AbstractAccessDecisionManager.accessDenied",
"Access is denied"));
} }
// To get this far, every AccessDecisionVoter abstained // To get this far, every AccessDecisionVoter abstained
if (this.isAllowIfAllAbstainDecisions()) { if (this.isAllowIfAllAbstainDecisions()) {
return; return;
} else { } else {
throw new AccessDeniedException("Access is denied."); throw new AccessDeniedException(messages.getMessage(
"AbstractAccessDecisionManager.accessDenied",
"Access is denied"));
} }
} }
} }

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -29,9 +29,6 @@ import java.util.Iterator;
* Simple concrete implementation of {@link * Simple concrete implementation of {@link
* org.acegisecurity.AccessDecisionManager} that uses a consensus-based * org.acegisecurity.AccessDecisionManager} that uses a consensus-based
* approach. * approach.
*
* @author Ben Alex
* @version $Id$
*/ */
public class ConsensusBased extends AbstractAccessDecisionManager { public class ConsensusBased extends AbstractAccessDecisionManager {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
@ -44,15 +41,6 @@ public class ConsensusBased extends AbstractAccessDecisionManager {
//~ Methods ================================================================ //~ Methods ================================================================
public void setAllowIfEqualGrantedDeniedDecisions(
boolean allowIfEqualGrantedDeniedDecisions) {
this.allowIfEqualGrantedDeniedDecisions = allowIfEqualGrantedDeniedDecisions;
}
public boolean isAllowIfEqualGrantedDeniedDecisions() {
return allowIfEqualGrantedDeniedDecisions;
}
/** /**
* This concrete implementation simply polls all configured {@link * This concrete implementation simply polls all configured {@link
* AccessDecisionVoter}s and upon completion determines the consensus of * AccessDecisionVoter}s and upon completion determines the consensus of
@ -111,14 +99,18 @@ public class ConsensusBased extends AbstractAccessDecisionManager {
} }
if (deny > grant) { if (deny > grant) {
throw new AccessDeniedException("Access is denied."); throw new AccessDeniedException(messages.getMessage(
"AbstractAccessDecisionManager.accessDenied",
"Access is denied"));
} }
if ((grant == deny) && (grant != 0)) { if ((grant == deny) && (grant != 0)) {
if (this.allowIfEqualGrantedDeniedDecisions) { if (this.allowIfEqualGrantedDeniedDecisions) {
return; return;
} else { } else {
throw new AccessDeniedException("Access is denied."); throw new AccessDeniedException(messages.getMessage(
"AbstractAccessDecisionManager.accessDenied",
"Access is denied"));
} }
} }
@ -126,7 +118,18 @@ public class ConsensusBased extends AbstractAccessDecisionManager {
if (this.isAllowIfAllAbstainDecisions()) { if (this.isAllowIfAllAbstainDecisions()) {
return; return;
} else { } else {
throw new AccessDeniedException("Access is denied."); throw new AccessDeniedException(messages.getMessage(
"AbstractAccessDecisionManager.accessDenied",
"Access is denied"));
} }
} }
public boolean isAllowIfEqualGrantedDeniedDecisions() {
return allowIfEqualGrantedDeniedDecisions;
}
public void setAllowIfEqualGrantedDeniedDecisions(
boolean allowIfEqualGrantedDeniedDecisions) {
this.allowIfEqualGrantedDeniedDecisions = allowIfEqualGrantedDeniedDecisions;
}
} }

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,9 +30,6 @@ import java.util.Iterator;
* Simple concrete implementation of {@link * Simple concrete implementation of {@link
* org.acegisecurity.AccessDecisionManager} that requires all voters to * org.acegisecurity.AccessDecisionManager} that requires all voters to
* abstain or grant access. * abstain or grant access.
*
* @author Ben Alex
* @version $Id$
*/ */
public class UnanimousBased extends AbstractAccessDecisionManager { public class UnanimousBased extends AbstractAccessDecisionManager {
//~ Static fields/initializers ============================================= //~ Static fields/initializers =============================================
@ -105,7 +102,9 @@ public class UnanimousBased extends AbstractAccessDecisionManager {
} }
if (deny > 0) { if (deny > 0) {
throw new AccessDeniedException("Access is denied."); throw new AccessDeniedException(messages.getMessage(
"AbstractAccessDecisionManager.accessDenied",
"Access is denied"));
} }
// To get this far, there were no deny votes // To get this far, there were no deny votes
@ -117,7 +116,9 @@ public class UnanimousBased extends AbstractAccessDecisionManager {
if (this.isAllowIfAllAbstainDecisions()) { if (this.isAllowIfAllAbstainDecisions()) {
return; return;
} else { } else {
throw new AccessDeniedException("Access is denied."); throw new AccessDeniedException(messages.getMessage(
"AbstractAccessDecisionManager.accessDenied",
"Access is denied"));
} }
} }
} }

View File

@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.springframework.context.support.StaticMessageSource;
/** /**
@ -81,6 +82,7 @@ public class AuthByAdapterTests extends TestCase {
public void testAuthByAdapterProviderNonAuthenticationMethods() public void testAuthByAdapterProviderNonAuthenticationMethods()
throws Exception { throws Exception {
AuthByAdapterProvider provider = new AuthByAdapterProvider(); AuthByAdapterProvider provider = new AuthByAdapterProvider();
provider.setMessageSource(new StaticMessageSource());
try { try {
provider.afterPropertiesSet(); provider.afterPropertiesSet();
@ -99,6 +101,7 @@ public class AuthByAdapterTests extends TestCase {
public void testAuthByAdapterProviderOnlyAcceptsAuthByAdapterImplementations() public void testAuthByAdapterProviderOnlyAcceptsAuthByAdapterImplementations()
throws Exception { throws Exception {
AuthByAdapterProvider provider = new AuthByAdapterProvider(); AuthByAdapterProvider provider = new AuthByAdapterProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setKey("my_password"); provider.setKey("my_password");
// Should fail as UsernamePassword is not interface of AuthByAdapter // Should fail as UsernamePassword is not interface of AuthByAdapter
@ -119,6 +122,7 @@ public class AuthByAdapterTests extends TestCase {
public void testAuthByAdapterProviderRequiresCorrectKey() public void testAuthByAdapterProviderRequiresCorrectKey()
throws Exception { throws Exception {
AuthByAdapterProvider provider = new AuthByAdapterProvider(); AuthByAdapterProvider provider = new AuthByAdapterProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setKey("my_password"); provider.setKey("my_password");
// Should fail as PrincipalAcegiUserToken has different key // Should fail as PrincipalAcegiUserToken has different key

View File

@ -27,6 +27,7 @@ import org.acegisecurity.acl.basic.MockAclObjectIdentity;
import org.acegisecurity.acl.basic.SimpleAclEntry; import org.acegisecurity.acl.basic.SimpleAclEntry;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.util.SimpleMethodInvocation; import org.acegisecurity.util.SimpleMethodInvocation;
import org.springframework.context.support.StaticMessageSource;
/** /**
@ -65,6 +66,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
SimpleAclEntry.ADMINISTRATION)}); SimpleAclEntry.ADMINISTRATION)});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager); provider.setAclManager(aclManager);
provider.afterPropertiesSet(); provider.afterPropertiesSet();
@ -94,6 +96,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager); provider.setAclManager(aclManager);
provider.afterPropertiesSet(); provider.afterPropertiesSet();
@ -123,6 +126,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)}); new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager); provider.setAclManager(aclManager);
assertEquals(aclManager, provider.getAclManager()); assertEquals(aclManager, provider.getAclManager());
provider.afterPropertiesSet(); provider.afterPropertiesSet();
@ -150,6 +154,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()}); new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager); provider.setAclManager(aclManager);
provider.afterPropertiesSet(); provider.afterPropertiesSet();
@ -171,6 +176,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
new MockAclObjectIdentity(), null, SimpleAclEntry.READ), new MockAclEntry()}); new MockAclObjectIdentity(), null, SimpleAclEntry.READ), new MockAclEntry()});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager); provider.setAclManager(aclManager);
assertEquals("AFTER_ACL_READ", provider.getProcessConfigAttribute()); assertEquals("AFTER_ACL_READ", provider.getProcessConfigAttribute());
provider.setProcessConfigAttribute("AFTER_ACL_ADMIN"); provider.setProcessConfigAttribute("AFTER_ACL_ADMIN");
@ -202,6 +208,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
SimpleAclEntry.ADMINISTRATION), new MockAclEntry()}); SimpleAclEntry.ADMINISTRATION), new MockAclEntry()});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager); provider.setAclManager(aclManager);
assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]); assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]);
provider.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION}); provider.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION});
@ -222,6 +229,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
public void testStartupDetectsMissingAclManager() throws Exception { public void testStartupDetectsMissingAclManager() throws Exception {
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setMessageSource(new StaticMessageSource());
try { try {
provider.afterPropertiesSet(); provider.afterPropertiesSet();
@ -234,6 +242,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
public void testStartupDetectsMissingProcessConfigAttribute() public void testStartupDetectsMissingProcessConfigAttribute()
throws Exception { throws Exception {
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setMessageSource(new StaticMessageSource());
AclManager aclManager = new MockAclManager("sydney", "marissa", AclManager aclManager = new MockAclManager("sydney", "marissa",
new AclEntry[] {new SimpleAclEntry("marissa", new AclEntry[] {new SimpleAclEntry("marissa",
new MockAclObjectIdentity(), null, new MockAclObjectIdentity(), null,
@ -254,6 +263,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
public void testStartupDetectsMissingRequirePermission() public void testStartupDetectsMissingRequirePermission()
throws Exception { throws Exception {
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider(); BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
provider.setMessageSource(new StaticMessageSource());
AclManager aclManager = new MockAclManager("sydney", "marissa", AclManager aclManager = new MockAclManager("sydney", "marissa",
new AclEntry[] {new SimpleAclEntry("marissa", new AclEntry[] {new SimpleAclEntry("marissa",
new MockAclObjectIdentity(), null, new MockAclObjectIdentity(), null,

View File

@ -21,6 +21,7 @@ import org.acegisecurity.Authentication;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.WebAuthenticationDetails; import org.acegisecurity.ui.WebAuthenticationDetails;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession; import org.springframework.mock.web.MockHttpSession;
@ -39,6 +40,7 @@ public class ConcurrentSessionControllerImplTests extends TestCase {
ConcurrentSessionControllerImpl sc = new ConcurrentSessionControllerImpl(); ConcurrentSessionControllerImpl sc = new ConcurrentSessionControllerImpl();
SessionRegistry registry = new SessionRegistryImpl(); SessionRegistry registry = new SessionRegistryImpl();
sc.setSessionRegistry(registry); sc.setSessionRegistry(registry);
sc.setMessageSource(new StaticMessageSource());
// Attempt to authenticate - it should be successful // Attempt to authenticate - it should be successful
Authentication auth = createAuthentication("bob", "1212"); Authentication auth = createAuthentication("bob", "1212");

View File

@ -41,6 +41,7 @@ import org.acegisecurity.runas.RunAsManagerImpl;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.StaticMessageSource;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -177,6 +178,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testRejectsAccessDecisionManagersThatDoNotSupportMethodInvocation() public void testRejectsAccessDecisionManagersThatDoNotSupportMethodInvocation()
throws Exception { throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor(); MethodSecurityInterceptor si = new MethodSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManagerWhichOnlySupportsStrings()); si.setAccessDecisionManager(new MockAccessDecisionManagerWhichOnlySupportsStrings());
si.setAuthenticationManager(new MockAuthenticationManager()); si.setAuthenticationManager(new MockAuthenticationManager());
si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true)); si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
@ -212,6 +214,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testRejectsCallsWhenObjectDefinitionSourceDoesNotSupportObject() public void testRejectsCallsWhenObjectDefinitionSourceDoesNotSupportObject()
throws Throwable { throws Throwable {
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor(); MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
interceptor.setMessageSource(new StaticMessageSource());
interceptor.setObjectDefinitionSource(new MockObjectDefinitionSourceWhichOnlySupportsStrings()); interceptor.setObjectDefinitionSource(new MockObjectDefinitionSourceWhichOnlySupportsStrings());
interceptor.setAccessDecisionManager(new MockAccessDecisionManager()); interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
interceptor.setAuthenticationManager(new MockAuthenticationManager()); interceptor.setAuthenticationManager(new MockAuthenticationManager());
@ -228,6 +231,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testRejectsCallsWhenObjectIsNull() throws Throwable { public void testRejectsCallsWhenObjectIsNull() throws Throwable {
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor(); MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
interceptor.setMessageSource(new StaticMessageSource());
try { try {
interceptor.invoke(null); interceptor.invoke(null);
@ -240,6 +244,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testRejectsRunAsManagersThatDoNotSupportMethodInvocation() public void testRejectsRunAsManagersThatDoNotSupportMethodInvocation()
throws Exception { throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor(); MethodSecurityInterceptor si = new MethodSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager()); si.setAuthenticationManager(new MockAuthenticationManager());
si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true)); si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
@ -258,6 +263,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testStartupCheckForAccessDecisionManager() public void testStartupCheckForAccessDecisionManager()
throws Exception { throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor(); MethodSecurityInterceptor si = new MethodSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setRunAsManager(new MockRunAsManager()); si.setRunAsManager(new MockRunAsManager());
si.setAuthenticationManager(new MockAuthenticationManager()); si.setAuthenticationManager(new MockAuthenticationManager());
si.setAfterInvocationManager(new MockAfterInvocationManager()); si.setAfterInvocationManager(new MockAfterInvocationManager());
@ -276,6 +282,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testStartupCheckForAuthenticationManager() public void testStartupCheckForAuthenticationManager()
throws Exception { throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor(); MethodSecurityInterceptor si = new MethodSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setRunAsManager(new MockRunAsManager()); si.setRunAsManager(new MockRunAsManager());
si.setAfterInvocationManager(new MockAfterInvocationManager()); si.setAfterInvocationManager(new MockAfterInvocationManager());
@ -294,6 +301,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testStartupCheckForMethodDefinitionSource() public void testStartupCheckForMethodDefinitionSource()
throws Exception { throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor(); MethodSecurityInterceptor si = new MethodSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager()); si.setAuthenticationManager(new MockAuthenticationManager());
@ -308,6 +316,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testStartupCheckForRunAsManager() throws Exception { public void testStartupCheckForRunAsManager() throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor(); MethodSecurityInterceptor si = new MethodSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager()); si.setAuthenticationManager(new MockAuthenticationManager());
si.setRunAsManager(null); // Overriding the default si.setRunAsManager(null); // Overriding the default
@ -325,6 +334,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testStartupCheckForValidAfterInvocationManager() public void testStartupCheckForValidAfterInvocationManager()
throws Exception { throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor(); MethodSecurityInterceptor si = new MethodSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setRunAsManager(new MockRunAsManager()); si.setRunAsManager(new MockRunAsManager());
si.setAuthenticationManager(new MockAuthenticationManager()); si.setAuthenticationManager(new MockAuthenticationManager());
si.setAfterInvocationManager(new MockAfterInvocationManagerWhichOnlySupportsStrings()); si.setAfterInvocationManager(new MockAfterInvocationManagerWhichOnlySupportsStrings());
@ -342,6 +352,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testValidationFailsIfInvalidAttributePresented() public void testValidationFailsIfInvalidAttributePresented()
throws Exception { throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor(); MethodSecurityInterceptor si = new MethodSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager()); si.setAuthenticationManager(new MockAuthenticationManager());
si.setRunAsManager(new RunAsManagerImpl()); si.setRunAsManager(new RunAsManagerImpl());
@ -361,6 +372,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testValidationNotAttemptedIfIsValidateConfigAttributesSetToFalse() public void testValidationNotAttemptedIfIsValidateConfigAttributesSetToFalse()
throws Exception { throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor(); MethodSecurityInterceptor si = new MethodSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager()); si.setAuthenticationManager(new MockAuthenticationManager());
@ -376,6 +388,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testValidationNotAttemptedIfMethodDefinitionSourceCannotReturnIterator() public void testValidationNotAttemptedIfMethodDefinitionSourceCannotReturnIterator()
throws Exception { throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor(); MethodSecurityInterceptor si = new MethodSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setRunAsManager(new MockRunAsManager()); si.setRunAsManager(new MockRunAsManager());
si.setAuthenticationManager(new MockAuthenticationManager()); si.setAuthenticationManager(new MockAuthenticationManager());

View File

@ -30,6 +30,7 @@ import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.intercept.method.MethodDefinitionMap; import org.acegisecurity.intercept.method.MethodDefinitionMap;
import org.acegisecurity.intercept.method.MethodDefinitionSourceEditor; import org.acegisecurity.intercept.method.MethodDefinitionSourceEditor;
import org.acegisecurity.providers.TestingAuthenticationToken; import org.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.StaticMessageSource;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -64,6 +65,7 @@ public class AspectJSecurityInterceptorTests extends TestCase {
public void testCallbackIsInvokedWhenPermissionGranted() public void testCallbackIsInvokedWhenPermissionGranted()
throws Exception { throws Exception {
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor(); AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setApplicationEventPublisher(MockApplicationContext.getContext()); si.setApplicationEventPublisher(MockApplicationContext.getContext());
si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager()); si.setAuthenticationManager(new MockAuthenticationManager());
@ -100,6 +102,7 @@ public class AspectJSecurityInterceptorTests extends TestCase {
public void testCallbackIsNotInvokedWhenPermissionDenied() public void testCallbackIsNotInvokedWhenPermissionDenied()
throws Exception { throws Exception {
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor(); AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
si.setMessageSource(new StaticMessageSource());
si.setApplicationEventPublisher(MockApplicationContext.getContext()); si.setApplicationEventPublisher(MockApplicationContext.getContext());
si.setAccessDecisionManager(new MockAccessDecisionManager()); si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager()); si.setAuthenticationManager(new MockAuthenticationManager());

View File

@ -34,6 +34,7 @@ import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.context.SecurityContextImpl; import org.acegisecurity.context.SecurityContextImpl;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
@ -77,6 +78,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
public void testEnsuresAccessDecisionManagerSupportsFilterInvocationClass() public void testEnsuresAccessDecisionManagerSupportsFilterInvocationClass()
throws Exception { throws Exception {
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor(); FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
interceptor.setMessageSource(new StaticMessageSource());
interceptor.setAuthenticationManager(new MockAuthenticationManager()); interceptor.setAuthenticationManager(new MockAuthenticationManager());
interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap()); interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
interceptor.setRunAsManager(new MockRunAsManager()); interceptor.setRunAsManager(new MockRunAsManager());
@ -110,6 +112,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
public void testEnsuresRunAsManagerSupportsFilterInvocationClass() public void testEnsuresRunAsManagerSupportsFilterInvocationClass()
throws Exception { throws Exception {
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor(); FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
interceptor.setMessageSource(new StaticMessageSource());
interceptor.setAccessDecisionManager(new MockAccessDecisionManager()); interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
interceptor.setAuthenticationManager(new MockAuthenticationManager()); interceptor.setAuthenticationManager(new MockAuthenticationManager());
interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap()); interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
@ -144,6 +147,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
throws Throwable { throws Throwable {
// Setup the FilterSecurityInterceptor // Setup the FilterSecurityInterceptor
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor(); FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
interceptor.setMessageSource(new StaticMessageSource());
interceptor.setAccessDecisionManager(new MockAccessDecisionManager()); interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
interceptor.setAuthenticationManager(new MockAuthenticationManager()); interceptor.setAuthenticationManager(new MockAuthenticationManager());
interceptor.setRunAsManager(new MockRunAsManager()); interceptor.setRunAsManager(new MockRunAsManager());
@ -183,6 +187,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
public void testNormalStartupAndGetter() throws Exception { public void testNormalStartupAndGetter() throws Exception {
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor(); FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
interceptor.setMessageSource(new StaticMessageSource());
interceptor.setAccessDecisionManager(new MockAccessDecisionManager()); interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
interceptor.setAuthenticationManager(new MockAuthenticationManager()); interceptor.setAuthenticationManager(new MockAuthenticationManager());
@ -203,6 +208,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
public void testSuccessfulInvocation() throws Throwable { public void testSuccessfulInvocation() throws Throwable {
// Setup the FilterSecurityInterceptor // Setup the FilterSecurityInterceptor
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor(); FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
interceptor.setMessageSource(new StaticMessageSource());
interceptor.setAccessDecisionManager(new MockAccessDecisionManager()); interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
interceptor.setAuthenticationManager(new MockAuthenticationManager()); interceptor.setAuthenticationManager(new MockAuthenticationManager());
interceptor.setRunAsManager(new MockRunAsManager()); interceptor.setRunAsManager(new MockRunAsManager());

View File

@ -29,6 +29,7 @@ import org.acegisecurity.concurrent.NullConcurrentSessionController;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.support.StaticMessageSource;
/** /**
@ -182,7 +183,7 @@ public class ProviderManagerTests extends TestCase {
ProviderManager mgr = new ProviderManager(); ProviderManager mgr = new ProviderManager();
mgr.setProviders(providers); mgr.setProviders(providers);
mgr.setMessageSource(new StaticMessageSource());
mgr.afterPropertiesSet(); mgr.afterPropertiesSet();
return mgr; return mgr;

View File

@ -22,6 +22,7 @@ import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.providers.TestingAuthenticationToken; import org.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.StaticMessageSource;
/** /**
@ -53,6 +54,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
public void testDetectsAnInvalidKey() throws Exception { public void testDetectsAnInvalidKey() throws Exception {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider(); AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty"); aap.setKey("qwerty");
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("WRONG_KEY", AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("WRONG_KEY",
@ -71,6 +73,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
public void testDetectsMissingKey() throws Exception { public void testDetectsMissingKey() throws Exception {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider(); AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
aap.setMessageSource(new StaticMessageSource());
try { try {
aap.afterPropertiesSet(); aap.afterPropertiesSet();
@ -82,6 +85,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
public void testGettersSetters() throws Exception { public void testGettersSetters() throws Exception {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider(); AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty"); aap.setKey("qwerty");
aap.afterPropertiesSet(); aap.afterPropertiesSet();
assertEquals("qwerty", aap.getKey()); assertEquals("qwerty", aap.getKey());
@ -89,6 +93,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
public void testIgnoresClassesItDoesNotSupport() throws Exception { public void testIgnoresClassesItDoesNotSupport() throws Exception {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider(); AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty"); aap.setKey("qwerty");
TestingAuthenticationToken token = new TestingAuthenticationToken("user", TestingAuthenticationToken token = new TestingAuthenticationToken("user",
@ -102,6 +107,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
public void testNormalOperation() throws Exception { public void testNormalOperation() throws Exception {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider(); AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty"); aap.setKey("qwerty");
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("qwerty", AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("qwerty",
@ -116,6 +122,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
public void testSupports() { public void testSupports() {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider(); AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
aap.setMessageSource(new StaticMessageSource());
assertTrue(aap.supports(AnonymousAuthenticationToken.class)); assertTrue(aap.supports(AnonymousAuthenticationToken.class));
assertFalse(aap.supports(TestingAuthenticationToken.class)); assertFalse(aap.supports(TestingAuthenticationToken.class));
} }

View File

@ -28,6 +28,7 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.cas.ticketvalidator.AbstractTicketValidator; import org.acegisecurity.providers.cas.ticketvalidator.AbstractTicketValidator;
import org.acegisecurity.providers.dao.User; import org.acegisecurity.providers.dao.User;
import org.acegisecurity.ui.cas.CasProcessingFilter; import org.acegisecurity.ui.cas.CasProcessingFilter;
import org.springframework.context.support.StaticMessageSource;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -64,6 +65,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testAuthenticateStateful() throws Exception { public void testAuthenticateStateful() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true)); cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty"); cap.setKey("qwerty");
@ -108,6 +110,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testAuthenticateStateless() throws Exception { public void testAuthenticateStateless() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true)); cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty"); cap.setKey("qwerty");
@ -144,6 +147,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsAMissingTicketId() throws Exception { public void testDetectsAMissingTicketId() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true)); cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty"); cap.setKey("qwerty");
@ -167,6 +171,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsAnInvalidKey() throws Exception { public void testDetectsAnInvalidKey() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true)); cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty"); cap.setKey("qwerty");
@ -193,6 +198,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsMissingAuthoritiesPopulator() public void testDetectsMissingAuthoritiesPopulator()
throws Exception { throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasProxyDecider(new MockProxyDecider()); cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty"); cap.setKey("qwerty");
cap.setStatelessTicketCache(new MockStatelessTicketCache()); cap.setStatelessTicketCache(new MockStatelessTicketCache());
@ -209,6 +215,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsMissingKey() throws Exception { public void testDetectsMissingKey() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider()); cap.setCasProxyDecider(new MockProxyDecider());
cap.setStatelessTicketCache(new MockStatelessTicketCache()); cap.setStatelessTicketCache(new MockStatelessTicketCache());
@ -225,6 +232,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsMissingProxyDecider() throws Exception { public void testDetectsMissingProxyDecider() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setKey("qwerty"); cap.setKey("qwerty");
cap.setStatelessTicketCache(new MockStatelessTicketCache()); cap.setStatelessTicketCache(new MockStatelessTicketCache());
@ -241,6 +249,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsMissingStatelessTicketCache() public void testDetectsMissingStatelessTicketCache()
throws Exception { throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider()); cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty"); cap.setKey("qwerty");
@ -257,6 +266,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsMissingTicketValidator() throws Exception { public void testDetectsMissingTicketValidator() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true)); cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty"); cap.setKey("qwerty");
@ -272,6 +282,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testGettersSetters() throws Exception { public void testGettersSetters() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider()); cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty"); cap.setKey("qwerty");
@ -288,6 +299,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testIgnoresClassesItDoesNotSupport() throws Exception { public void testIgnoresClassesItDoesNotSupport() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider()); cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty"); cap.setKey("qwerty");
@ -307,6 +319,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testIgnoresUsernamePasswordAuthenticationTokensWithoutCasIdentifiersAsPrincipal() public void testIgnoresUsernamePasswordAuthenticationTokensWithoutCasIdentifiersAsPrincipal()
throws Exception { throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator()); cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider()); cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty"); cap.setKey("qwerty");
@ -322,6 +335,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testSupports() { public void testSupports() {
CasAuthenticationProvider cap = new CasAuthenticationProvider(); CasAuthenticationProvider cap = new CasAuthenticationProvider();
cap.setMessageSource(new StaticMessageSource());
assertTrue(cap.supports(UsernamePasswordAuthenticationToken.class)); assertTrue(cap.supports(UsernamePasswordAuthenticationToken.class));
assertTrue(cap.supports(CasAuthenticationToken.class)); assertTrue(cap.supports(CasAuthenticationToken.class));
} }

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,15 +19,14 @@ import junit.framework.TestCase;
import org.acegisecurity.providers.cas.ProxyUntrustedException; import org.acegisecurity.providers.cas.ProxyUntrustedException;
import org.springframework.context.support.StaticMessageSource;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
/** /**
* Tests {@link NamedCasProxyDecider}. * Tests {@link NamedCasProxyDecider}.
*
* @author Ben Alex
* @version $Id$
*/ */
public class NamedCasProxyDeciderTests extends TestCase { public class NamedCasProxyDeciderTests extends TestCase {
//~ Constructors =========================================================== //~ Constructors ===========================================================
@ -42,17 +41,18 @@ public class NamedCasProxyDeciderTests extends TestCase {
//~ Methods ================================================================ //~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
}
public static void main(String[] args) { public static void main(String[] args) {
junit.textui.TestRunner.run(NamedCasProxyDeciderTests.class); junit.textui.TestRunner.run(NamedCasProxyDeciderTests.class);
} }
public final void setUp() throws Exception {
super.setUp();
}
public void testAcceptsIfNearestProxyIsAuthorized() public void testAcceptsIfNearestProxyIsAuthorized()
throws Exception { throws Exception {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider(); NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
proxyDecider.setMessageSource(new StaticMessageSource());
// Build the ticket returned from CAS // Build the ticket returned from CAS
List proxyList = new Vector(); List proxyList = new Vector();
@ -72,6 +72,8 @@ public class NamedCasProxyDeciderTests extends TestCase {
public void testAcceptsIfNoProxiesInTicket() { public void testAcceptsIfNoProxiesInTicket() {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider(); NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
proxyDecider.setMessageSource(new StaticMessageSource());
List proxyList = new Vector(); // no proxies in list List proxyList = new Vector(); // no proxies in list
proxyDecider.confirmProxyListTrusted(proxyList); proxyDecider.confirmProxyListTrusted(proxyList);
@ -80,6 +82,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
public void testDetectsMissingValidProxiesList() throws Exception { public void testDetectsMissingValidProxiesList() throws Exception {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider(); NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
proxyDecider.setMessageSource(new StaticMessageSource());
try { try {
proxyDecider.afterPropertiesSet(); proxyDecider.afterPropertiesSet();
@ -92,6 +95,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
public void testDoesNotAcceptNull() { public void testDoesNotAcceptNull() {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider(); NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
proxyDecider.setMessageSource(new StaticMessageSource());
try { try {
proxyDecider.confirmProxyListTrusted(null); proxyDecider.confirmProxyListTrusted(null);
@ -103,6 +107,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
public void testGettersSetters() { public void testGettersSetters() {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider(); NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
proxyDecider.setMessageSource(new StaticMessageSource());
// Build the list of valid nearest proxies // Build the list of valid nearest proxies
List validProxies = new Vector(); List validProxies = new Vector();
@ -117,6 +122,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
public void testRejectsIfNearestProxyIsNotAuthorized() public void testRejectsIfNearestProxyIsNotAuthorized()
throws Exception { throws Exception {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider(); NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
proxyDecider.setMessageSource(new StaticMessageSource());
// Build the ticket returned from CAS // Build the ticket returned from CAS
List proxyList = new Vector(); List proxyList = new Vector();

View File

@ -18,6 +18,7 @@ package org.acegisecurity.providers.cas.proxy;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.acegisecurity.providers.cas.ProxyUntrustedException; import org.acegisecurity.providers.cas.ProxyUntrustedException;
import org.springframework.context.support.StaticMessageSource;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
@ -71,6 +72,7 @@ public class RejectProxyTicketsTests extends TestCase {
public void testRejectsIfAnyProxyInList() { public void testRejectsIfAnyProxyInList() {
RejectProxyTickets proxyDecider = new RejectProxyTickets(); RejectProxyTickets proxyDecider = new RejectProxyTickets();
proxyDecider.setMessageSource(new StaticMessageSource());
List proxyList = new Vector(); List proxyList = new Vector();
proxyList.add("https://localhost/webApp/j_acegi_cas_security_check"); proxyList.add("https://localhost/webApp/j_acegi_cas_security_check");

View File

@ -34,6 +34,7 @@ import org.acegisecurity.providers.dao.cache.NullUserCache;
import org.acegisecurity.providers.dao.salt.SystemWideSaltSource; import org.acegisecurity.providers.dao.salt.SystemWideSaltSource;
import org.acegisecurity.providers.encoding.ShaPasswordEncoder; import org.acegisecurity.providers.encoding.ShaPasswordEncoder;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataRetrievalFailureException; import org.springframework.dao.DataRetrievalFailureException;
@ -63,6 +64,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"KOala"); "KOala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -79,6 +81,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"opal"); "opal");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterAccountExpired()); provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterAccountExpired());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -95,6 +98,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"opal"); "opal");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterAccountLocked()); provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterAccountLocked());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -111,6 +115,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"opal"); "opal");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterCredentialsExpired()); provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterCredentialsExpired());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -138,6 +143,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"opal"); "opal");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeter()); provider.setAuthenticationDao(new MockAuthenticationDaoUserPeter());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -154,6 +160,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala"); "koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoSimulateBackendError()); provider.setAuthenticationDao(new MockAuthenticationDaoSimulateBackendError());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -170,6 +177,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala"); "koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -186,6 +194,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"INVALID_PASSWORD"); "INVALID_PASSWORD");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -202,6 +211,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala"); "koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setHideUserNotFoundExceptions(false); // we want UsernameNotFoundExceptions provider.setHideUserNotFoundExceptions(false); // we want UsernameNotFoundExceptions
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -219,6 +229,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala"); "koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
assertTrue(provider.isHideUserNotFoundExceptions()); assertTrue(provider.isHideUserNotFoundExceptions());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -236,6 +247,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala"); "koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -253,6 +265,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
token.setDetails("192.168.0.1"); token.setDetails("192.168.0.1");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -276,6 +289,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala"); "koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -305,6 +319,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
salt.setSystemWideSalt("SYSTEM_SALT_VALUE"); salt.setSystemWideSalt("SYSTEM_SALT_VALUE");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissaWithSalt()); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissaWithSalt());
provider.setSaltSource(salt); provider.setSaltSource(salt);
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -330,6 +345,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala"); "koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
provider.setForcePrincipalAsString(true); provider.setForcePrincipalAsString(true);
@ -351,6 +367,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala"); "koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoReturnsNull()); provider.setAuthenticationDao(new MockAuthenticationDaoReturnsNull());
try { try {
@ -364,6 +381,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
public void testGettersSetters() { public void testGettersSetters() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setPasswordEncoder(new ShaPasswordEncoder()); provider.setPasswordEncoder(new ShaPasswordEncoder());
assertEquals(ShaPasswordEncoder.class, assertEquals(ShaPasswordEncoder.class,
provider.getPasswordEncoder().getClass()); provider.getPasswordEncoder().getClass());
@ -388,6 +406,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
MockAuthenticationDaoUserMarissa authenticationDao = new MockAuthenticationDaoUserMarissa(); MockAuthenticationDaoUserMarissa authenticationDao = new MockAuthenticationDaoUserMarissa();
MockUserCache cache = new MockUserCache(); MockUserCache cache = new MockUserCache();
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(authenticationDao); provider.setAuthenticationDao(authenticationDao);
provider.setUserCache(cache); provider.setUserCache(cache);
@ -414,6 +433,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
public void testStartupFailsIfNoAuthenticationDao() public void testStartupFailsIfNoAuthenticationDao()
throws Exception { throws Exception {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
try { try {
provider.afterPropertiesSet(); provider.afterPropertiesSet();
@ -425,6 +445,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
public void testStartupFailsIfNoUserCacheSet() throws Exception { public void testStartupFailsIfNoUserCacheSet() throws Exception {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa()); provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
assertEquals(NullUserCache.class, provider.getUserCache().getClass()); assertEquals(NullUserCache.class, provider.getUserCache().getClass());
provider.setUserCache(null); provider.setUserCache(null);
@ -439,6 +460,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
public void testStartupSuccess() throws Exception { public void testStartupSuccess() throws Exception {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
AuthenticationDao dao = new MockAuthenticationDaoUserMarissa(); AuthenticationDao dao = new MockAuthenticationDaoUserMarissa();
provider.setAuthenticationDao(dao); provider.setAuthenticationDao(dao);
provider.setUserCache(new MockUserCache()); provider.setUserCache(new MockUserCache());
@ -449,6 +471,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
public void testSupports() { public void testSupports() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
assertTrue(provider.supports(UsernamePasswordAuthenticationToken.class)); assertTrue(provider.supports(UsernamePasswordAuthenticationToken.class));
assertTrue(!provider.supports(TestingAuthenticationToken.class)); assertTrue(!provider.supports(TestingAuthenticationToken.class));
} }

View File

@ -22,6 +22,7 @@ import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.providers.TestingAuthenticationToken; import org.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.StaticMessageSource;
/** /**
@ -53,6 +54,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
public void testDetectsAnInvalidKey() throws Exception { public void testDetectsAnInvalidKey() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider(); RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty"); aap.setKey("qwerty");
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("WRONG_KEY", RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("WRONG_KEY",
@ -71,6 +73,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
public void testDetectsMissingKey() throws Exception { public void testDetectsMissingKey() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider(); RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
aap.setMessageSource(new StaticMessageSource());
try { try {
aap.afterPropertiesSet(); aap.afterPropertiesSet();
@ -82,6 +85,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
public void testGettersSetters() throws Exception { public void testGettersSetters() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider(); RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty"); aap.setKey("qwerty");
aap.afterPropertiesSet(); aap.afterPropertiesSet();
assertEquals("qwerty", aap.getKey()); assertEquals("qwerty", aap.getKey());
@ -102,6 +106,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
public void testNormalOperation() throws Exception { public void testNormalOperation() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider(); RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty"); aap.setKey("qwerty");
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("qwerty", RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("qwerty",
@ -116,6 +121,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
public void testSupports() { public void testSupports() {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider(); RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
aap.setMessageSource(new StaticMessageSource());
assertTrue(aap.supports(RememberMeAuthenticationToken.class)); assertTrue(aap.supports(RememberMeAuthenticationToken.class));
assertFalse(aap.supports(TestingAuthenticationToken.class)); assertFalse(aap.supports(TestingAuthenticationToken.class));
} }

View File

@ -20,6 +20,7 @@ import junit.framework.TestCase;
import org.acegisecurity.*; import org.acegisecurity.*;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.dao.User; import org.acegisecurity.providers.dao.User;
import org.springframework.context.support.StaticMessageSource;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
@ -49,6 +50,7 @@ public class X509AuthenticationProviderTests extends TestCase {
public void testAuthenticationIsNullWithUnsupportedToken() { public void testAuthenticationIsNullWithUnsupportedToken() {
X509AuthenticationProvider provider = new X509AuthenticationProvider(); X509AuthenticationProvider provider = new X509AuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
Authentication request = new UsernamePasswordAuthenticationToken("dummy", Authentication request = new UsernamePasswordAuthenticationToken("dummy",
"dummy"); "dummy");
Authentication result = provider.authenticate(request); Authentication result = provider.authenticate(request);
@ -57,6 +59,7 @@ public class X509AuthenticationProviderTests extends TestCase {
public void testFailsWithNullCertificate() { public void testFailsWithNullCertificate() {
X509AuthenticationProvider provider = new X509AuthenticationProvider(); X509AuthenticationProvider provider = new X509AuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(false)); provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(false));
@ -70,6 +73,7 @@ public class X509AuthenticationProviderTests extends TestCase {
public void testNormalOperation() throws Exception { public void testNormalOperation() throws Exception {
X509AuthenticationProvider provider = new X509AuthenticationProvider(); X509AuthenticationProvider provider = new X509AuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(false)); provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(false));
provider.afterPropertiesSet(); provider.afterPropertiesSet();
@ -82,6 +86,7 @@ public class X509AuthenticationProviderTests extends TestCase {
public void testPopulatorRejectionCausesFailure() throws Exception { public void testPopulatorRejectionCausesFailure() throws Exception {
X509AuthenticationProvider provider = new X509AuthenticationProvider(); X509AuthenticationProvider provider = new X509AuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(true)); provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(true));
try { try {
@ -94,6 +99,7 @@ public class X509AuthenticationProviderTests extends TestCase {
public void testRequiresPopulator() throws Exception { public void testRequiresPopulator() throws Exception {
X509AuthenticationProvider provider = new X509AuthenticationProvider(); X509AuthenticationProvider provider = new X509AuthenticationProvider();
provider.setMessageSource(new StaticMessageSource());
try { try {
provider.afterPropertiesSet(); provider.afterPropertiesSet();

View File

@ -26,6 +26,7 @@ import org.acegisecurity.providers.dao.User;
import org.acegisecurity.providers.dao.UsernameNotFoundException; import org.acegisecurity.providers.dao.UsernameNotFoundException;
import org.acegisecurity.providers.x509.X509TestUtils; import org.acegisecurity.providers.x509.X509TestUtils;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
@ -56,6 +57,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testDefaultCNPatternMatch() throws Exception { public void testDefaultCNPatternMatch() throws Exception {
X509Certificate cert = X509TestUtils.buildTestCertificate(); X509Certificate cert = X509TestUtils.buildTestCertificate();
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator(); DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
populator.setMessageSource(new StaticMessageSource());
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail()); populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
populator.afterPropertiesSet(); populator.afterPropertiesSet();
@ -65,6 +67,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testEmailPatternMatch() throws Exception { public void testEmailPatternMatch() throws Exception {
X509Certificate cert = X509TestUtils.buildTestCertificate(); X509Certificate cert = X509TestUtils.buildTestCertificate();
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator(); DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
populator.setMessageSource(new StaticMessageSource());
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail()); populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
populator.setSubjectDNRegex("emailAddress=(.*?),"); populator.setSubjectDNRegex("emailAddress=(.*?),");
@ -74,6 +77,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testInvalidRegexFails() throws Exception { public void testInvalidRegexFails() throws Exception {
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator(); DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
populator.setMessageSource(new StaticMessageSource());
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail()); populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
populator.setSubjectDNRegex("CN=(.*?,"); // missing closing bracket on group populator.setSubjectDNRegex("CN=(.*?,"); // missing closing bracket on group
@ -88,6 +92,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testMatchOnShoeSizeFieldInDNFails() throws Exception { public void testMatchOnShoeSizeFieldInDNFails() throws Exception {
X509Certificate cert = X509TestUtils.buildTestCertificate(); X509Certificate cert = X509TestUtils.buildTestCertificate();
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator(); DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
populator.setMessageSource(new StaticMessageSource());
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail()); populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
populator.setSubjectDNRegex("shoeSize=(.*?),"); populator.setSubjectDNRegex("shoeSize=(.*?),");
@ -104,6 +109,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testPatternWithNoGroupFails() throws Exception { public void testPatternWithNoGroupFails() throws Exception {
X509Certificate cert = X509TestUtils.buildTestCertificate(); X509Certificate cert = X509TestUtils.buildTestCertificate();
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator(); DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
populator.setMessageSource(new StaticMessageSource());
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail()); populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
populator.setSubjectDNRegex("CN=.*?,"); populator.setSubjectDNRegex("CN=.*?,");
@ -120,6 +126,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testRequiresDao() throws Exception { public void testRequiresDao() throws Exception {
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator(); DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
populator.setMessageSource(new StaticMessageSource());
try { try {
populator.afterPropertiesSet(); populator.afterPropertiesSet();

View File

@ -1,4 +1,4 @@
/* Copyright 2004 Acegi Technology Pty Limited /* Copyright 2004, 2005 Acegi Technology Pty Limited
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,15 +21,15 @@ import org.acegisecurity.Authentication;
import org.acegisecurity.BadCredentialsException; import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.providers.TestingAuthenticationToken; import org.acegisecurity.providers.TestingAuthenticationToken;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.springframework.context.support.StaticMessageSource;
/** /**
* Tests {@link RunAsImplAuthenticationProvider}. * Tests {@link RunAsImplAuthenticationProvider}.
*
* @author Ben Alex
* @version $Id$
*/ */
public class RunAsImplAuthenticationProviderTests extends TestCase { public class RunAsImplAuthenticationProviderTests extends TestCase {
//~ Constructors =========================================================== //~ Constructors ===========================================================
@ -44,14 +44,14 @@ public class RunAsImplAuthenticationProviderTests extends TestCase {
//~ Methods ================================================================ //~ Methods ================================================================
public final void setUp() throws Exception {
super.setUp();
}
public static void main(String[] args) { public static void main(String[] args) {
junit.textui.TestRunner.run(RunAsImplAuthenticationProviderTests.class); junit.textui.TestRunner.run(RunAsImplAuthenticationProviderTests.class);
} }
public final void setUp() throws Exception {
super.setUp();
}
public void testAuthenticationFailDueToWrongKey() { public void testAuthenticationFailDueToWrongKey() {
RunAsUserToken token = new RunAsUserToken("WRONG_PASSWORD", "Test", RunAsUserToken token = new RunAsUserToken("WRONG_PASSWORD", "Test",
"Password", "Password",
@ -59,6 +59,7 @@ public class RunAsImplAuthenticationProviderTests extends TestCase {
"ROLE_TWO")}, UsernamePasswordAuthenticationToken.class); "ROLE_TWO")}, UsernamePasswordAuthenticationToken.class);
RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider(); RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider();
provider.setKey("hello_world"); provider.setKey("hello_world");
provider.setMessageSource(new StaticMessageSource());
try { try {
provider.authenticate(token); provider.authenticate(token);

View File

@ -31,6 +31,7 @@ import org.acegisecurity.providers.dao.User;
import org.acegisecurity.providers.dao.UsernameNotFoundException; import org.acegisecurity.providers.dao.UsernameNotFoundException;
import org.acegisecurity.util.MockFilterChain; import org.acegisecurity.util.MockFilterChain;
import org.springframework.context.support.StaticMessageSource;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
@ -74,6 +75,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
"user-that-doesnt-exist"); "user-that-doesnt-exist");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord()); filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
try { try {
@ -97,6 +99,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
"mcgarrett"); "mcgarrett");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord()); filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
try { try {
@ -122,6 +125,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
"wofat"); "wofat");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord()); filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
try { try {
@ -147,6 +151,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
"steve"); "steve");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord()); filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
try { try {
@ -169,6 +174,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
"jacklord"); "jacklord");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord()); filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
Authentication result = filter.attemptSwitchUser(request); Authentication result = filter.attemptSwitchUser(request);
@ -177,6 +183,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
public void testBadConfigMissingAuthenticationDao() { public void testBadConfigMissingAuthenticationDao() {
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setSwitchUserUrl("/j_acegi_switch_user"); filter.setSwitchUserUrl("/j_acegi_switch_user");
filter.setExitUserUrl("/j_acegi_exit_user"); filter.setExitUserUrl("/j_acegi_exit_user");
filter.setTargetUrl("/main.jsp"); filter.setTargetUrl("/main.jsp");
@ -191,6 +198,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
public void testBadConfigMissingTargetUrl() { public void testBadConfigMissingTargetUrl() {
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord()); filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
filter.setSwitchUserUrl("/j_acegi_switch_user"); filter.setSwitchUserUrl("/j_acegi_switch_user");
filter.setExitUserUrl("/j_acegi_exit_user"); filter.setExitUserUrl("/j_acegi_exit_user");
@ -206,6 +214,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
public void testDefaultProcessesFilterUrlWithPathParameter() { public void testDefaultProcessesFilterUrlWithPathParameter() {
MockHttpServletRequest request = createMockSwitchRequest(); MockHttpServletRequest request = createMockSwitchRequest();
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setSwitchUserUrl("/j_acegi_switch_user"); filter.setSwitchUserUrl("/j_acegi_switch_user");
request.setRequestURI( request.setRequestURI(
@ -238,6 +247,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
// setup filter // setup filter
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord()); filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
filter.setExitUserUrl("/j_acegi_exit_user"); filter.setExitUserUrl("/j_acegi_exit_user");
@ -266,6 +276,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
// setup filter // setup filter
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord()); filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
filter.setExitUserUrl("/j_acegi_exit_user"); filter.setExitUserUrl("/j_acegi_exit_user");
@ -294,6 +305,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
MockFilterChain chain = new MockFilterChain(true); MockFilterChain chain = new MockFilterChain(true);
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setSwitchUserUrl("/j_acegi_switch_user"); filter.setSwitchUserUrl("/j_acegi_switch_user");
filter.setTargetUrl("/webapp/someOtherUrl"); filter.setTargetUrl("/webapp/someOtherUrl");
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord()); filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
@ -343,6 +355,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
// setup filter // setup filter
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter(); SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord()); filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
filter.setSwitchUserUrl("/j_acegi_switch_user"); filter.setSwitchUserUrl("/j_acegi_switch_user");

View File

@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.SecurityConfig; import org.acegisecurity.SecurityConfig;
import org.acegisecurity.providers.TestingAuthenticationToken; import org.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.StaticMessageSource;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
@ -143,6 +144,7 @@ public class AffirmativeBasedTests extends TestCase {
private AffirmativeBased makeDecisionManager() { private AffirmativeBased makeDecisionManager() {
AffirmativeBased decisionManager = new AffirmativeBased(); AffirmativeBased decisionManager = new AffirmativeBased();
decisionManager.setMessageSource(new StaticMessageSource());
RoleVoter roleVoter = new RoleVoter(); RoleVoter roleVoter = new RoleVoter();
DenyVoter denyForSureVoter = new DenyVoter(); DenyVoter denyForSureVoter = new DenyVoter();
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter(); DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();

View File

@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.SecurityConfig; import org.acegisecurity.SecurityConfig;
import org.acegisecurity.providers.TestingAuthenticationToken; import org.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.StaticMessageSource;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
@ -164,6 +165,7 @@ public class ConsensusBasedTests extends TestCase {
private ConsensusBased makeDecisionManager() { private ConsensusBased makeDecisionManager() {
ConsensusBased decisionManager = new ConsensusBased(); ConsensusBased decisionManager = new ConsensusBased();
decisionManager.setMessageSource(new StaticMessageSource());
RoleVoter roleVoter = new RoleVoter(); RoleVoter roleVoter = new RoleVoter();
DenyVoter denyForSureVoter = new DenyVoter(); DenyVoter denyForSureVoter = new DenyVoter();
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter(); DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();

View File

@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.SecurityConfig; import org.acegisecurity.SecurityConfig;
import org.acegisecurity.providers.TestingAuthenticationToken; import org.acegisecurity.providers.TestingAuthenticationToken;
import org.springframework.context.support.StaticMessageSource;
import java.util.List; import java.util.List;
import java.util.Vector; import java.util.Vector;
@ -59,6 +60,7 @@ public class UnanimousBasedTests extends TestCase {
throws Exception { throws Exception {
TestingAuthenticationToken auth = makeTestToken(); TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager(); UnanimousBased mgr = makeDecisionManager();
mgr.setMessageSource(new StaticMessageSource());
ConfigAttributeDefinition config = new ConfigAttributeDefinition(); ConfigAttributeDefinition config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
@ -76,6 +78,7 @@ public class UnanimousBasedTests extends TestCase {
throws Exception { throws Exception {
TestingAuthenticationToken auth = makeTestToken(); TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager(); UnanimousBased mgr = makeDecisionManager();
mgr.setMessageSource(new StaticMessageSource());
ConfigAttributeDefinition config = new ConfigAttributeDefinition(); ConfigAttributeDefinition config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
@ -88,6 +91,7 @@ public class UnanimousBasedTests extends TestCase {
throws Exception { throws Exception {
TestingAuthenticationToken auth = makeTestToken(); TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager(); UnanimousBased mgr = makeDecisionManager();
mgr.setMessageSource(new StaticMessageSource());
ConfigAttributeDefinition config = new ConfigAttributeDefinition(); ConfigAttributeDefinition config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_WE_DO_NOT_HAVE")); // deny config.addConfigAttribute(new SecurityConfig("ROLE_WE_DO_NOT_HAVE")); // deny
@ -103,6 +107,7 @@ public class UnanimousBasedTests extends TestCase {
public void testRoleVoterPrefixObserved() throws Exception { public void testRoleVoterPrefixObserved() throws Exception {
TestingAuthenticationToken auth = makeTestTokenWithFooBarPrefix(); TestingAuthenticationToken auth = makeTestTokenWithFooBarPrefix();
UnanimousBased mgr = makeDecisionManagerWithFooBarPrefix(); UnanimousBased mgr = makeDecisionManagerWithFooBarPrefix();
mgr.setMessageSource(new StaticMessageSource());
ConfigAttributeDefinition config = new ConfigAttributeDefinition(); ConfigAttributeDefinition config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("FOOBAR_1")); // grant config.addConfigAttribute(new SecurityConfig("FOOBAR_1")); // grant
@ -116,6 +121,7 @@ public class UnanimousBasedTests extends TestCase {
throws Exception { throws Exception {
TestingAuthenticationToken auth = makeTestToken(); TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager(); UnanimousBased mgr = makeDecisionManager();
mgr.setMessageSource(new StaticMessageSource());
assertTrue(!mgr.isAllowIfAllAbstainDecisions()); // check default assertTrue(!mgr.isAllowIfAllAbstainDecisions()); // check default
@ -135,6 +141,7 @@ public class UnanimousBasedTests extends TestCase {
TestingAuthenticationToken auth = makeTestToken(); TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager(); UnanimousBased mgr = makeDecisionManager();
mgr.setAllowIfAllAbstainDecisions(true); mgr.setAllowIfAllAbstainDecisions(true);
mgr.setMessageSource(new StaticMessageSource());
assertTrue(mgr.isAllowIfAllAbstainDecisions()); // check changed assertTrue(mgr.isAllowIfAllAbstainDecisions()); // check changed
ConfigAttributeDefinition config = new ConfigAttributeDefinition(); ConfigAttributeDefinition config = new ConfigAttributeDefinition();
@ -148,6 +155,7 @@ public class UnanimousBasedTests extends TestCase {
throws Exception { throws Exception {
TestingAuthenticationToken auth = makeTestToken(); TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager(); UnanimousBased mgr = makeDecisionManager();
mgr.setMessageSource(new StaticMessageSource());
ConfigAttributeDefinition config = new ConfigAttributeDefinition(); ConfigAttributeDefinition config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
@ -159,6 +167,7 @@ public class UnanimousBasedTests extends TestCase {
private UnanimousBased makeDecisionManager() { private UnanimousBased makeDecisionManager() {
UnanimousBased decisionManager = new UnanimousBased(); UnanimousBased decisionManager = new UnanimousBased();
decisionManager.setMessageSource(new StaticMessageSource());
RoleVoter roleVoter = new RoleVoter(); RoleVoter roleVoter = new RoleVoter();
DenyVoter denyForSureVoter = new DenyVoter(); DenyVoter denyForSureVoter = new DenyVoter();
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter(); DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
@ -173,6 +182,7 @@ public class UnanimousBasedTests extends TestCase {
private UnanimousBased makeDecisionManagerWithFooBarPrefix() { private UnanimousBased makeDecisionManagerWithFooBarPrefix() {
UnanimousBased decisionManager = new UnanimousBased(); UnanimousBased decisionManager = new UnanimousBased();
decisionManager.setMessageSource(new StaticMessageSource());
RoleVoter roleVoter = new RoleVoter(); RoleVoter roleVoter = new RoleVoter();
roleVoter.setRolePrefix("FOOBAR_"); roleVoter.setRolePrefix("FOOBAR_");