From fddcd6112ee7dca2c1fd9f6d49af2d124a14ecdc Mon Sep 17 00:00:00 2001
From: Ben Alex
AclObjectIdentity
.
- *
- *
- * The {@link BasicAclEntry}s returned by this method will have
- * String
-based recipients. This will not be a problem if you
- * are using the GrantedAuthorityEffectiveAclsResolver
, which
- * is the default configured against BasicAclProvider
.
- *
- * This method will only return ACLs for requests where the
- * AclObjectIdentity
is of type {@link
- * NamedEntityObjectIdentity}. Of course, you can subclass or replace this
- * class and support your own custom AclObjectIdentity
types.
- *
null
and must be an instance of
- * NamedEntityObjectIdentity
)
- *
- * @return the ACLs that apply (without any null
s inside the
- * array), or null
if not found or if an incompatible
- * AclObjectIdentity
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 AclObjectIdentity
to a
* String
that can be located in the RDBMS.
@@ -193,17 +85,13 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
* @param aclObjectIdentity to locate
*
* @return the object identity as a String
- *
- * @throws IllegalArgumentException DOCUMENT ME!
*/
protected String convertAclObjectIdentityToString(
AclObjectIdentity aclObjectIdentity) {
// Ensure we can process this type of AclObjectIdentity
- if (!(aclObjectIdentity instanceof NamedEntityObjectIdentity)) {
- throw new IllegalArgumentException(
- "Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: "
- + aclObjectIdentity + ")");
- }
+ Assert.isInstanceOf(NamedEntityObjectIdentity.class, aclObjectIdentity,
+ "Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: "
+ + aclObjectIdentity + ")");
NamedEntityObjectIdentity neoi = (NamedEntityObjectIdentity) aclObjectIdentity;
@@ -211,19 +99,6 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
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 BasicAclEntry
from the passed
* AclDetailsHolder
s.
@@ -263,206 +138,336 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
entry.setAclObjectIdentity(propertiesInformation.getAclObjectIdentity());
entry.setAclObjectParentIdentity(propertiesInformation
- .getAclObjectParentIdentity());
+ .getAclObjectParentIdentity());
- if (aclInformation == null) {
- // this is an inheritence marker instance only
- entry.setMask(0);
- entry.setRecipient(RECIPIENT_USED_FOR_INHERITENCE_MARKER);
- } else {
- // this is an individual ACL entry
- entry.setMask(aclInformation.getMask());
- entry.setRecipient(aclInformation.getRecipient());
- }
+ if (aclInformation == null) {
+ // this is an inheritence marker instance only
+ entry.setMask(0);
+ entry.setRecipient(RECIPIENT_USED_FOR_INHERITENCE_MARKER);
+ } else {
+ // this is an individual ACL entry
+ entry.setMask(aclInformation.getMask());
+ entry.setRecipient(aclInformation.getRecipient());
+ }
- return entry;
- }
-
- //~ Inner Classes ==========================================================
-
- /**
- * Used to hold details of a domain object instance's properties, or an
- * individual ACL entry.
- *
- *
- * Not all properties will be set. The actual properties set will depend on
- * which MappingSqlQuery
creates the object.
- *
- * Does not enforce null
s or empty String
s as
- * this is performed by the MappingSqlQuery
objects (or
- * preferably the backend RDBMS via schema constraints).
- *
AclObjectIdentity
.
+ *
+ *
+ * The {@link BasicAclEntry}s returned by this method will have
+ * String
-based recipients. This will not be a problem if
+ * you are using the
+ * GrantedAuthorityEffectiveAclsResolver
, which is the
+ * default configured against BasicAclProvider
.
+ *
+ * This method will only return ACLs for requests where the
+ * AclObjectIdentity
is of type {@link
+ * NamedEntityObjectIdentity}. Of course, you can subclass or replace
+ * this class and support your own custom
+ * AclObjectIdentity
types.
+ *
AclsByObjectIdentityMapping
to locate the
- * individual ACL entries
- * @param aclObjectIdentity the object identity of the domain object
- * instance
- * @param aclObjectParentIdentity the object identity of the domain
- * object instance's parent
- * @param aclClass the class of which a new instance which should be
- * created for each individual ACL entry (or an inheritence
- * "holder" class if there are no ACL entries)
+ * @param aclObjectIdentity for which ACL information is required
+ * (cannot be null
and must be an instance of
+ * NamedEntityObjectIdentity
)
+ *
+ * @return the ACLs that apply (without any null
s inside
+ * the array), or null
if not found or if an
+ * incompatible AclObjectIdentity
was requested
*/
- public AclDetailsHolder(long foreignKeyId,
- AclObjectIdentity aclObjectIdentity,
- AclObjectIdentity aclObjectParentIdentity, Class aclClass) {
- this.foreignKeyId = foreignKeyId;
- this.aclObjectIdentity = aclObjectIdentity;
- this.aclObjectParentIdentity = aclObjectParentIdentity;
- this.aclClass = aclClass;
- }
-
- public Class getAclClass() {
- return aclClass;
- }
-
- public AclObjectIdentity getAclObjectIdentity() {
- return aclObjectIdentity;
- }
-
- public AclObjectIdentity getAclObjectParentIdentity() {
- return aclObjectParentIdentity;
- }
-
- public long getForeignKeyId() {
- return foreignKeyId;
- }
-
- public int getMask() {
- return mask;
- }
-
- public Object getRecipient() {
- return recipient;
- }
- }
-
- /**
- * Query object to look up individual ACL entries.
- *
- *
- * Returns the generic AclDetailsHolder
object.
- *
- * Guarantees to never return null
(exceptions are thrown in
- * the event of any issues).
- *
- * The executed SQL requires the following information be made available - * from the indicated placeholders: 1. RECIPIENT, 2. MASK. - *
- */ - protected class AclsByObjectIdentityMapping extends MappingSqlQuery { - protected AclsByObjectIdentityMapping(DataSource ds) { - super(ds, aclsByObjectIdentityQuery); - declareParameter(new SqlParameter(Types.BIGINT)); - compile(); - } - - protected Object mapRow(ResultSet rs, int rownum) - throws SQLException { - String recipient = rs.getString(1); - int mask = rs.getInt(2); - - if ((recipient == null) || "".equals(recipient)) { - throw new IllegalArgumentException("recipient required"); - } - - return new AclDetailsHolder(recipient, mask); - } - } - - /** - * Query object to look up properties for an object identity. - * - *
- * Returns the generic AclDetailsHolder
object.
- *
- * Guarantees to never return null
(exceptions are thrown in
- * the event of any issues).
- *
- * The executed SQL requires the following information be made available - * from the indicated placeholders: 1. ID, 2. OBJECT_IDENTITY, 3. - * ACL_CLASS and 4. PARENT_OBJECT_IDENTITY. - *
- */ - protected class ObjectPropertiesMapping extends MappingSqlQuery { - protected ObjectPropertiesMapping(DataSource ds) { - super(ds, objectPropertiesQuery); - declareParameter(new SqlParameter(Types.VARCHAR)); - 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; + public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) { + String aclObjectIdentityString; try { - aclClazz = this.getClass().getClassLoader().loadClass(aclClass); - } catch (ClassNotFoundException cnf) { - throw new IllegalArgumentException(cnf.getMessage()); + aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity); + } catch (IllegalArgumentException unsupported) { + return null; // pursuant to contract described in JavaDocs above } - return new AclDetailsHolder(id, buildIdentity(objectIdentity), - buildIdentity(parentObjectIdentity), aclClazz); - } + // Lookup the object's main properties from the RDBMS (guaranteed no nulls) + List objects = objectProperties.execute(aclObjectIdentityString); - private AclObjectIdentity buildIdentity(String identity) { - if (identity == null) { - // Must be an empty parent, so return null + if (objects.size() == 0) { + // this is an unknown object identity string return null; } - int delim = identity.lastIndexOf(":"); - String classname = identity.substring(0, delim); - String id = identity.substring(delim + 1); + // Cast to an object properties holder (there should only be one record) + AclDetailsHolder propertiesInformation = (AclDetailsHolder) objects + .get(0); - return new NamedEntityObjectIdentity(classname, id); - } - } -} + // 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. + * + *
+ * Not all properties will be set. The actual properties set
+ * will depend on which MappingSqlQuery
creates
+ * the object.
+ *
+ * Does not enforce null
s or empty
+ * String
s as this is performed by the
+ * MappingSqlQuery
objects (or preferably the
+ * backend RDBMS via schema constraints).
+ *
AclsByObjectIdentityMapping
to
+ * locate the individual ACL entries
+ * @param aclObjectIdentity the object identity of the
+ * domain object instance
+ * @param aclObjectParentIdentity the object identity of
+ * the domain object instance's parent
+ * @param aclClass the class of which a new instance which
+ * should be created for each individual ACL entry
+ * (or an inheritence "holder" class if there are
+ * no ACL entries)
+ */
+ public AclDetailsHolder(long foreignKeyId,
+ AclObjectIdentity aclObjectIdentity,
+ AclObjectIdentity aclObjectParentIdentity,
+ Class aclClass) {
+ this.foreignKeyId = foreignKeyId;
+ this.aclObjectIdentity = aclObjectIdentity;
+ this.aclObjectParentIdentity = aclObjectParentIdentity;
+ this.aclClass = aclClass;
+ }
+
+ public Class getAclClass() {
+ return aclClass;
+ }
+
+ public AclObjectIdentity getAclObjectIdentity() {
+ return aclObjectIdentity;
+ }
+
+ public AclObjectIdentity getAclObjectParentIdentity() {
+ return aclObjectParentIdentity;
+ }
+
+ public long getForeignKeyId() {
+ return foreignKeyId;
+ }
+
+ public int getMask() {
+ return mask;
+ }
+
+ public Object getRecipient() {
+ return recipient;
+ }
+ }
+
+ /**
+ * Query object to look up individual ACL entries.
+ *
+ *
+ * Returns the generic AclDetailsHolder
object.
+ *
+ * Guarantees to never return null
(exceptions are
+ * thrown in the event of any issues).
+ *
+ * The executed SQL requires the following information be made + * available from the indicated placeholders: 1. RECIPIENT, 2. + * MASK. + *
+ */ + protected class AclsByObjectIdentityMapping + extends MappingSqlQuery { + protected AclsByObjectIdentityMapping(DataSource ds) { + super(ds, aclsByObjectIdentityQuery); + declareParameter(new SqlParameter(Types.BIGINT)); + compile(); + } + + protected Object mapRow(ResultSet rs, int rownum) + throws SQLException { + String recipient = rs.getString(1); + int mask = rs.getInt(2); + Assert.hasText(recipient, "recipient required"); + + return new AclDetailsHolder(recipient, mask); + } + } + + /** + * Query object to look up properties for an object identity. + * + *
+ * Returns the generic AclDetailsHolder
object.
+ *
+ * Guarantees to never return null
(exceptions are
+ * thrown in the event of any issues).
+ *
+ * The executed SQL requires the following information be made + * available from the indicated placeholders: 1. ID, 2. + * OBJECT_IDENTITY, 3. ACL_CLASS and 4. + * PARENT_OBJECT_IDENTITY. + *
+ */ + protected class ObjectPropertiesMapping extends MappingSqlQuery { + protected ObjectPropertiesMapping(DataSource ds) { + super(ds, objectPropertiesQuery); + declareParameter(new SqlParameter(Types.VARCHAR)); + compile(); + } + + private AclObjectIdentity buildIdentity(String identity) { + if (identity == null) { + // Must be an empty parent, so return null + return null; + } + + int delim = identity.lastIndexOf(":"); + String classname = identity.substring(0, delim); + String id = identity.substring(delim + 1); + + 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); + } + } + } diff --git a/core/src/main/java/org/acegisecurity/adapters/AuthByAdapterProvider.java b/core/src/main/java/org/acegisecurity/adapters/AuthByAdapterProvider.java index e10fcaec2a..8232131258 100644 --- a/core/src/main/java/org/acegisecurity/adapters/AuthByAdapterProvider.java +++ b/core/src/main/java/org/acegisecurity/adapters/AuthByAdapterProvider.java @@ -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"); * 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.AuthenticationException; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.AuthenticationProvider; 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; @@ -38,28 +44,20 @@ import org.springframework.util.Assert; *
* If the key does not match, a BadCredentialsException
is thrown.
*
Authentication
object. This class is designed to process
* {@link AclEntry}s that are subclasses of {@link
- * org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these
- * are obtained by using the {@link
- * org.acegisecurity.acl.basic.BasicAclProvider}.
+ * org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are
+ * obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}.
*
*
*
@@ -55,8 +60,8 @@ import java.util.Iterator;
* ConfigAttribute#getAttribute()} matches the {@link
* #processConfigAttribute}. The provider will then lookup the ACLs from the
* AclManager
and ensure the principal is {@link
- * org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for
- * at least one of the {@link #requirePermission}s.
+ * org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least
+ * one of the {@link #requirePermission}s.
*
@@ -74,9 +79,8 @@ import java.util.Iterator; *
* The AclManager
is allowed to return any implementations of
* AclEntry
it wishes. However, this provider will only be able
- * to validate against BasicAclEntry
s, and thus access
- * will be denied if no AclEntry
is of type
- * BasicAclEntry
.
+ * to validate against BasicAclEntry
s, and thus access will be
+ * denied if no AclEntry
is of type BasicAclEntry
.
*
@@ -87,12 +91,9 @@ import java.util.Iterator; *
* All comparisons and prefixes are case sensitive. *
- * - * @author Ben Alex - * @version $Id$ */ public class BasicAclEntryAfterInvocationProvider - implements AfterInvocationProvider, InitializingBean { + implements AfterInvocationProvider, InitializingBean, MessageSourceAware { //~ Static fields/initializers ============================================= protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationProvider.class); @@ -100,41 +101,21 @@ public class BasicAclEntryAfterInvocationProvider //~ Instance fields ======================================================== private AclManager aclManager; + protected MessageSourceAccessor messages; private String processConfigAttribute = "AFTER_ACL_READ"; private int[] requirePermission = {SimpleAclEntry.READ}; //~ 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 { - Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory"); + Assert.notNull(processConfigAttribute, + "A processConfigAttribute is mandatory"); Assert.notNull(aclManager, "An aclManager is mandatory"); + Assert.notNull(messages, "A message source must be set"); 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,16 +143,16 @@ public class BasicAclEntryAfterInvocationProvider authentication); if ((acls == null) || (acls.length == 0)) { - throw new AccessDeniedException("Authentication: " - + authentication.toString() - + " has NO permissions at all to the domain object: " - + returnedObject); + throw new AccessDeniedException(messages.getMessage( + "BasicAclEntryAfterInvocationProvider.noPermission", + new Object[] {authentication.getName(), returnedObject}, + "Authentication {0} has NO permissions at all to the domain object {1}")); } for (int i = 0; i < acls.length; i++) { // Locate processable AclEntrys if (acls[i] instanceof BasicAclEntry) { - BasicAclEntry processableAcl = (BasicAclEntry) acls[i]; + BasicAclEntry processableAcl = (BasicAclEntry) acls[i]; // See if principal has any of the required permissions for (int y = 0; y < requirePermission.length; y++) { @@ -190,16 +171,44 @@ public class BasicAclEntryAfterInvocationProvider } // No permissions match - throw new AccessDeniedException("Authentication: " - + authentication.toString() - + " has ACL permissions to the domain object, but not the required ACL permission to the domain object: " - + returnedObject); + throw new AccessDeniedException(messages.getMessage( + "BasicAclEntryAfterInvocationProvider.insufficientPermission", + new Object[] {authentication.getName(), returnedObject}, + "Authentication {0} has ACL permissions to the domain object, but not the required ACL permission to the domain object {1}")); } } 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) { if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(getProcessConfigAttribute())) { diff --git a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java index f487fbee25..284d54d31f 100644 --- a/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java +++ b/core/src/main/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImpl.java @@ -19,6 +19,11 @@ import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; 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; @@ -30,36 +35,61 @@ import org.springframework.util.Assert; * By default uses {@link org.acegisecurity.concurrent.SessionRegistryImpl}, * although anySessionRegistry
may be used.
*
- *
- * @author Ben Alex
- * @version $Id$
*/
public class ConcurrentSessionControllerImpl
- implements ConcurrentSessionController, InitializingBean {
+ implements ConcurrentSessionController, InitializingBean,
+ MessageSourceAware {
//~ Instance fields ========================================================
+ protected MessageSourceAccessor messages;
private SessionRegistry sessionRegistry = new SessionRegistryImpl();
- private int maximumSessions = 1;
private boolean exceptionIfMaximumExceeded = false;
+ private int maximumSessions = 1;
//~ 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.isTrue(maximumSessions != 0,
"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 null
or all unexpired sessions
+ * associated with the principal
+ * @param allowableSessions DOCUMENT ME!
+ * @param registry an instance of the SessionRegistry
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)
@@ -68,86 +98,82 @@ public class ConcurrentSessionControllerImpl
"Authentication request cannot be null (violation of interface contract)");
Object principal = SessionRegistryUtils
- .obtainPrincipalFromAuthentication(request);
- String sessionId = SessionRegistryUtils
- .obtainSessionIdFromAuthentication(request);
+ .obtainPrincipalFromAuthentication(request);
+ String sessionId = SessionRegistryUtils
+ .obtainSessionIdFromAuthentication(request);
- SessionInformation[] sessions = sessionRegistry.getAllSessions(principal);
+ SessionInformation[] sessions = sessionRegistry.getAllSessions(principal);
- int sessionCount = 0;
+ int sessionCount = 0;
- if (sessions != null) {
- sessionCount = sessions.length;
- }
-
- int allowableSessions = getMaximumSessionsForThisUser(request);
- Assert.isTrue(allowableSessions != 0,
- "getMaximumSessionsForThisUser() must return either -1 to allow unlimited logins, or a positive integer to specify a maximum");
-
- if (sessionCount < allowableSessions) {
- return;
- } else if (sessionCount == allowableSessions) {
- // Only permit it though if this request is associated with one of the sessions
- for (int i = 0; i < sessionCount; i++) {
- if (sessions[i].getSessionId().equals(sessionId)) {
- return;
+ if (sessions != null) {
+ sessionCount = sessions.length;
}
+
+ int allowableSessions = getMaximumSessionsForThisUser(request);
+ Assert.isTrue(allowableSessions != 0,
+ "getMaximumSessionsForThisUser() must return either -1 to allow unlimited logins, or a positive integer to specify a maximum");
+
+ if (sessionCount < allowableSessions) {
+ return;
+ } else if (sessionCount == allowableSessions) {
+ // Only permit it though if this request is associated with one of the sessions
+ for (int i = 0; i < sessionCount; i++) {
+ if (sessions[i].getSessionId().equals(sessionId)) {
+ return;
+ }
+ }
+ }
+
+ allowableSessionsExceeded(sessionId, sessions,
+ allowableSessions, sessionRegistry);
}
- }
- allowableSessionsExceeded(sessionId, sessions, allowableSessions, sessionRegistry);
- }
-
- /**
- * Allows subclasses to customise behaviour when too many sessions are
- * detected.
- *
- * @param sessionId the session ID of the present request
- * @param sessions either null
or all unexpired sessions associated with the principal
- * @param registry an instance of the SessionRegistry
for subclass use
- */
- protected void allowableSessionsExceeded(String sessionId, SessionInformation[] sessions, int allowableSessions, SessionRegistry registry) {
- if (exceptionIfMaximumExceeded || sessions == null) {
- throw new ConcurrentLoginException("Maximum sessions of "
- + allowableSessions + " 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();
- }
+ /**
+ * Method intended for use by subclasses to override the maximum
+ * number of sessions that are permitted for a particular
+ * authentication. The default implementation simply returns the
+ * maximumSessions
value for the bean.
+ *
+ * @param authentication to determine the maximum sessions for
+ *
+ * @return either -1 meaning unlimited, or a positive integer to
+ * limit (never zero)
+ */
+ protected int getMaximumSessionsForThisUser(
+ Authentication authentication) {
+ return maximumSessions;
+ }
- public void registerSuccessfulAuthentication(Authentication authentication) {
- Assert.notNull(authentication,
- "Authentication cannot be null (violation of interface contract)");
+ public void registerSuccessfulAuthentication(
+ Authentication authentication) {
+ Assert.notNull(authentication,
+ "Authentication cannot be null (violation of interface contract)");
- Object principal = SessionRegistryUtils
- .obtainPrincipalFromAuthentication(authentication);
- String sessionId = SessionRegistryUtils
- .obtainSessionIdFromAuthentication(authentication);
+ Object principal = SessionRegistryUtils
+ .obtainPrincipalFromAuthentication(authentication);
+ String sessionId = SessionRegistryUtils
+ .obtainSessionIdFromAuthentication(authentication);
- sessionRegistry.removeSessionInformation(sessionId);
- sessionRegistry.registerNewSession(sessionId, principal);
- }
+ sessionRegistry.removeSessionInformation(sessionId);
+ sessionRegistry.registerNewSession(sessionId, principal);
+ }
- /**
- * Method intended for use by subclasses to override the maximum number of
- * sessions that are permitted for a particular authentication. The
- * default implementation simply returns the maximumSessions
- * value for the bean.
- *
- * @param authentication to determine the maximum sessions for
- *
- * @return either -1 meaning unlimited, or a positive integer to limit
- * (never zero)
- */
- protected int getMaximumSessionsForThisUser(Authentication authentication) {
- return maximumSessions;
- }
-}
+ public void setExceptionIfMaximumExceeded(
+ boolean exceptionIfMaximumExceeded) {
+ this.exceptionIfMaximumExceeded = exceptionIfMaximumExceeded;
+ }
+
+ public void setMaximumSessions(int maximumSessions) {
+ this.maximumSessions = maximumSessions;
+ }
+
+ public void setMessageSource(MessageSource messageSource) {
+ this.messages = new MessageSourceAccessor(messageSource);
+ }
+
+ public void setSessionRegistry(
+ SessionRegistry sessionRegistry) {
+ this.sessionRegistry = sessionRegistry;
+ }
+ }
diff --git a/core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java b/core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java
index 3cd7d9fa6e..4e873d893d 100644
--- a/core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java
+++ b/core/src/main/java/org/acegisecurity/intercept/AbstractSecurityInterceptor.java
@@ -42,6 +42,9 @@ 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;
@@ -135,12 +138,9 @@ import java.util.Set;
*
*
*
- *
- * @author Ben Alex
- * @version $Id$
*/
public abstract class AbstractSecurityInterceptor implements InitializingBean,
- ApplicationEventPublisherAware {
+ ApplicationEventPublisherAware, MessageSourceAware {
//~ Static fields/initializers =============================================
protected static final Log logger = LogFactory.getLog(AbstractSecurityInterceptor.class);
@@ -151,6 +151,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
private AfterInvocationManager afterInvocationManager;
private ApplicationEventPublisher eventPublisher;
private AuthenticationManager authenticationManager;
+ protected MessageSourceAccessor messages;
private RunAsManager runAsManager = new NullRunAsManager();
private boolean alwaysReauthenticate = false;
private boolean rejectPublicInvocations = false;
@@ -158,194 +159,6 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
//~ Methods ================================================================
- public void setAfterInvocationManager(
- AfterInvocationManager afterInvocationManager) {
- this.afterInvocationManager = afterInvocationManager;
- }
-
- public AfterInvocationManager getAfterInvocationManager() {
- return afterInvocationManager;
- }
-
- /**
- * Indicates whether the AbstractSecurityInterceptor
should
- * ignore the {@link Authentication#isAuthenticated()} property. Defaults
- * to false
, meaning by default the
- * Authentication.isAuthenticated()
property is trusted and
- * re-authentication will not occur if the principal has already been
- * authenticated.
- *
- * @param alwaysReauthenticate true
to force
- * AbstractSecurityInterceptor
to disregard the value
- * of Authentication.isAuthenticated()
and always
- * re-authenticate the request (defaults to false
).
- */
- 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 AbstractSecurityInterceptor
all
- * support the indicated secure object class.
- *
- * @return the type of secure object the subclass provides services for
- */
- public abstract Class getSecureObjectClass();
-
- public abstract ObjectDefinitionSource obtainObjectDefinitionSource();
-
- public void setAccessDecisionManager(
- AccessDecisionManager accessDecisionManager) {
- this.accessDecisionManager = accessDecisionManager;
- }
-
- public AccessDecisionManager getAccessDecisionManager() {
- return accessDecisionManager;
- }
-
- public void setAuthenticationManager(AuthenticationManager newManager) {
- this.authenticationManager = newManager;
- }
-
- public AuthenticationManager getAuthenticationManager() {
- return this.authenticationManager;
- }
-
- /**
- * By rejecting public invocations (and setting this property to
- * true
), essentially you are ensuring that every secure
- * object invocation advised by AbstractSecurityInterceptor
- * 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
- * IllegalArgumentException
will be thrown by the
- * AbstractSecurityInterceptor
if you set this property to
- * true
and an attempt is made to invoke a secure object that
- * has no configuration attributes.
- *
- * @param rejectPublicInvocations set to true
to reject
- * invocations of secure objects that have no configuration
- * attributes (by default it is true
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 {
- Assert.notNull(getSecureObjectClass(),
- "Subclass must provide a non-null response to getSecureObjectClass()");
-
- Assert.notNull(this.authenticationManager,
- "An AuthenticationManager is required");
-
- Assert.notNull(this.accessDecisionManager,
- "An AccessDecisionManager is required");
-
- Assert.notNull(this.runAsManager, "A RunAsManager is required");
-
- Assert.notNull(this.obtainObjectDefinitionSource(),
- "An ObjectDefinitionSource is required");
-
- if (!this.obtainObjectDefinitionSource().supports(getSecureObjectClass())) {
- throw new IllegalArgumentException(
- "ObjectDefinitionSource does not support secure object class: "
- + getSecureObjectClass());
- }
-
- if (!this.runAsManager.supports(getSecureObjectClass())) {
- throw new IllegalArgumentException(
- "RunAsManager does not support secure object class: "
- + getSecureObjectClass());
- }
-
- if (!this.accessDecisionManager.supports(getSecureObjectClass())) {
- throw new IllegalArgumentException(
- "AccessDecisionManager does not support secure object class: "
- + getSecureObjectClass());
- }
-
- if ((this.afterInvocationManager != null)
- && !this.afterInvocationManager.supports(getSecureObjectClass())) {
- throw new IllegalArgumentException(
- "AfterInvocationManager does not support secure object class: "
- + getSecureObjectClass());
- }
-
- if (this.validateConfigAttributes) {
- Iterator iter = this.obtainObjectDefinitionSource()
- .getConfigAttributeDefinitions();
-
- if (iter == null) {
- if (logger.isWarnEnabled()) {
- logger.warn(
- "Could not validate configuration attributes as the MethodDefinitionSource did not return a ConfigAttributeDefinition Iterator");
- }
- } else {
- Set set = new HashSet();
-
- while (iter.hasNext()) {
- ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter
- .next();
- Iterator attributes = def.getConfigAttributes();
-
- while (attributes.hasNext()) {
- ConfigAttribute attr = (ConfigAttribute) attributes
- .next();
-
- if (!this.runAsManager.supports(attr)
- && !this.accessDecisionManager.supports(attr)
- && ((this.afterInvocationManager == null)
- || !this.afterInvocationManager.supports(attr))) {
- set.add(attr);
- }
- }
- }
-
- if (set.size() == 0) {
- if (logger.isInfoEnabled()) {
- logger.info("Validated configuration attributes");
- }
- } else {
- throw new IllegalArgumentException(
- "Unsupported configuration attributes: "
- + set.toString());
- }
- }
- }
- }
-
/**
* Completes the work of the AbstractSecurityInterceptor
after
* the secure object invocation has been complete
@@ -371,151 +184,353 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
+ token.getAuthentication().toString());
}
- SecurityContextHolder.getContext().setAuthentication(token
- .getAuthentication());
+ 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) {
- Assert.notNull(object, "Object was null");
- Assert.isTrue(getSecureObjectClass().isAssignableFrom(object.getClass()),
- "Security invocation attempted for object "
- + object.getClass().getName()
- + " but AbstractSecurityInterceptor only configured to support secure objects of type: "
- + getSecureObjectClass());
-
- ConfigAttributeDefinition attr = this.obtainObjectDefinitionSource()
- .getAttributes(object);
-
- if ((attr == null) && rejectPublicInvocations) {
- throw new IllegalArgumentException(
- "No public invocations are allowed via this AbstractSecurityInterceptor. This indicates a configuration error because the AbstractSecurityInterceptor.rejectPublicInvocations property is set to 'true'");
- }
-
- if (attr != null) {
- if (logger.isDebugEnabled()) {
- logger.debug("Secure object: " + object.toString()
- + "; ConfigAttributes: " + attr.toString());
+ .getAuthentication(), token.getSecureObject(),
+ token.getAttr(), returnedObject);
}
- // We check for just the property we're interested in (we do
- // not call Context.validate() like the ContextInterceptor)
- if (SecurityContextHolder.getContext().getAuthentication() == null) {
- credentialsNotFound("Authentication credentials were not found in the SecurityContext",
- object, attr);
+ return returnedObject;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(getSecureObjectClass(),
+ "Subclass must provide a non-null response to getSecureObjectClass()");
+
+ Assert.notNull(this.messages, "A message source must be set");
+ Assert.notNull(this.authenticationManager,
+ "An AuthenticationManager is required");
+
+ Assert.notNull(this.accessDecisionManager,
+ "An AccessDecisionManager is required");
+
+ Assert.notNull(this.runAsManager, "A RunAsManager is required");
+
+ Assert.notNull(this.obtainObjectDefinitionSource(),
+ "An ObjectDefinitionSource is required");
+
+ if (!this.obtainObjectDefinitionSource()
+ .supports(getSecureObjectClass())) {
+ throw new IllegalArgumentException(
+ "ObjectDefinitionSource does not support secure object class: "
+ + getSecureObjectClass());
}
- // Attempt authentication if not already authenticated, or user always wants reauthentication
- Authentication authenticated;
+ if (!this.runAsManager.supports(getSecureObjectClass())) {
+ throw new IllegalArgumentException(
+ "RunAsManager does not support secure object class: "
+ + getSecureObjectClass());
+ }
- if (!SecurityContextHolder.getContext().getAuthentication()
- .isAuthenticated()
- || alwaysReauthenticate) {
+ if (!this.accessDecisionManager.supports(getSecureObjectClass())) {
+ throw new IllegalArgumentException(
+ "AccessDecisionManager does not support secure object class: "
+ + getSecureObjectClass());
+ }
+
+ if ((this.afterInvocationManager != null)
+ && !this.afterInvocationManager.supports(getSecureObjectClass())) {
+ throw new IllegalArgumentException(
+ "AfterInvocationManager does not support secure object class: "
+ + getSecureObjectClass());
+ }
+
+ if (this.validateConfigAttributes) {
+ Iterator iter = this.obtainObjectDefinitionSource()
+ .getConfigAttributeDefinitions();
+
+ if (iter == null) {
+ if (logger.isWarnEnabled()) {
+ logger.warn(
+ "Could not validate configuration attributes as the MethodDefinitionSource did not return a ConfigAttributeDefinition Iterator");
+ }
+ } else {
+ Set set = new HashSet();
+
+ while (iter.hasNext()) {
+ ConfigAttributeDefinition def = (ConfigAttributeDefinition) iter
+ .next();
+ Iterator attributes = def.getConfigAttributes();
+
+ while (attributes.hasNext()) {
+ ConfigAttribute attr = (ConfigAttribute) attributes
+ .next();
+
+ if (!this.runAsManager.supports(attr)
+ && !this.accessDecisionManager.supports(attr)
+ && ((this.afterInvocationManager == null)
+ || !this.afterInvocationManager.supports(attr))) {
+ set.add(attr);
+ }
+ }
+ }
+
+ if (set.size() == 0) {
+ if (logger.isInfoEnabled()) {
+ logger.info("Validated configuration attributes");
+ }
+ } else {
+ throw new IllegalArgumentException(
+ "Unsupported configuration attributes: "
+ + set.toString());
+ }
+ }
+ }
+ }
+
+ protected InterceptorStatusToken beforeInvocation(Object object) {
+ Assert.notNull(object, "Object was null");
+ Assert.isTrue(getSecureObjectClass()
+ .isAssignableFrom(object.getClass()),
+ "Security invocation attempted for object "
+ + object.getClass().getName()
+ + " but AbstractSecurityInterceptor only configured to support secure objects of type: "
+ + getSecureObjectClass());
+
+ ConfigAttributeDefinition attr = this.obtainObjectDefinitionSource()
+ .getAttributes(object);
+
+ if ((attr == null) && rejectPublicInvocations) {
+ throw new IllegalArgumentException(
+ "No public invocations are allowed via this AbstractSecurityInterceptor. This indicates a configuration error because the AbstractSecurityInterceptor.rejectPublicInvocations property is set to 'true'");
+ }
+
+ if (attr != null) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Secure object: " + object.toString()
+ + "; ConfigAttributes: " + attr.toString());
+ }
+
+ // We check for just the property we're interested in (we do
+ // not call Context.validate() like the ContextInterceptor)
+ if (SecurityContextHolder.getContext().getAuthentication() == null) {
+ credentialsNotFound(messages.getMessage(
+ "AbstractSecurityInterceptor.authenticationNotFound",
+ "An Authentication object was not found in the SecurityContext"),
+ object, attr);
+ }
+
+ // Attempt authentication if not already authenticated, or user always wants reauthentication
+ Authentication authenticated;
+
+ if (!SecurityContextHolder.getContext().getAuthentication()
+ .isAuthenticated()
+ || alwaysReauthenticate) {
+ try {
+ authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext()
+ .getAuthentication());
+ } catch (AuthenticationException authenticationException) {
+ throw authenticationException;
+ }
+
+ // We don't authenticated.setAuthentication(true), because each provider should do that
+ if (logger.isDebugEnabled()) {
+ logger.debug("Successfully Authenticated: "
+ + authenticated.toString());
+ }
+
+ SecurityContextHolder.getContext()
+ .setAuthentication(authenticated);
+ } else {
+ authenticated = SecurityContextHolder.getContext()
+ .getAuthentication();
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Previously Authenticated: "
+ + authenticated.toString());
+ }
+ }
+
+ // Attempt authorization
try {
- authenticated = this.authenticationManager.authenticate(SecurityContextHolder.getContext()
- .getAuthentication());
- } catch (AuthenticationException authenticationException) {
- throw authenticationException;
- }
+ this.accessDecisionManager.decide(authenticated, object,
+ attr);
+ } catch (AccessDeniedException accessDeniedException) {
+ AuthorizationFailureEvent event = new AuthorizationFailureEvent(object,
+ attr, authenticated, accessDeniedException);
+ this.eventPublisher.publishEvent(event);
- // We don't authenticated.setAuthentication(true), because each provider should do that
- if (logger.isDebugEnabled()) {
- logger.debug("Successfully Authenticated: "
- + authenticated.toString());
+ throw accessDeniedException;
}
- SecurityContextHolder.getContext().setAuthentication(authenticated);
- } else {
- authenticated = SecurityContextHolder.getContext()
- .getAuthentication();
-
if (logger.isDebugEnabled()) {
- logger.debug("Previously Authenticated: "
- + authenticated.toString());
+ logger.debug("Authorization successful");
}
- }
- // Attempt authorization
- try {
- this.accessDecisionManager.decide(authenticated, object, attr);
- } catch (AccessDeniedException accessDeniedException) {
- AuthorizationFailureEvent event = new AuthorizationFailureEvent(object,
- attr, authenticated, accessDeniedException);
+ AuthorizedEvent event = new AuthorizedEvent(object, attr,
+ authenticated);
this.eventPublisher.publishEvent(event);
- throw accessDeniedException;
- }
+ // Attempt to run as a different user
+ Authentication runAs = this.runAsManager.buildRunAs(authenticated,
+ object, attr);
- if (logger.isDebugEnabled()) {
- logger.debug("Authorization successful");
- }
+ if (runAs == null) {
+ if (logger.isDebugEnabled()) {
+ logger.debug(
+ "RunAsManager did not change Authentication object");
+ }
- AuthorizedEvent event = new AuthorizedEvent(object, attr,
- authenticated);
- this.eventPublisher.publishEvent(event);
+ return new InterceptorStatusToken(authenticated, false,
+ attr, object); // no further work post-invocation
+ } else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Switching to RunAs Authentication: "
+ + runAs.toString());
+ }
- // Attempt to run as a different user
- Authentication runAs = this.runAsManager.buildRunAs(authenticated,
- object, attr);
+ SecurityContextHolder.getContext().setAuthentication(runAs);
- if (runAs == null) {
- if (logger.isDebugEnabled()) {
- logger.debug(
- "RunAsManager did not change Authentication object");
+ return new InterceptorStatusToken(authenticated, true,
+ attr, object); // revert to token.Authenticated post-invocation
}
-
- return new InterceptorStatusToken(authenticated, false, attr,
- object); // no further work post-invocation
} else {
if (logger.isDebugEnabled()) {
- logger.debug("Switching to RunAs Authentication: "
- + runAs.toString());
+ logger.debug("Public object - authentication not attempted");
}
- SecurityContextHolder.getContext().setAuthentication(runAs);
+ this.eventPublisher.publishEvent(new PublicInvocationEvent(
+ object));
- return new InterceptorStatusToken(authenticated, true, attr,
- object); // revert to token.Authenticated post-invocation
- }
- } else {
- if (logger.isDebugEnabled()) {
- logger.debug("Public object - authentication not attempted");
+ return null; // no further work post-invocation
}
+ }
- this.eventPublisher.publishEvent(new PublicInvocationEvent(object));
+ /**
+ * Helper method which generates an exception containing the passed
+ * reason, and publishes an event to the application context.
+ *
+ * + * Always throws an exception. + *
+ * + * @param reason to be provided in the exception detail + * @param secureObject that was being called + * @param configAttribs that were defined for the secureObject + */ + private void credentialsNotFound(String reason, Object secureObject, + ConfigAttributeDefinition configAttribs) { + AuthenticationCredentialsNotFoundException exception = new AuthenticationCredentialsNotFoundException(reason); - return null; // no further work post-invocation + AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(secureObject, + configAttribs, exception); + this.eventPublisher.publishEvent(event); + + 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 theAbstractSecurityInterceptor
+ * 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 AbstractSecurityInterceptor
+ * should ignore the {@link Authentication#isAuthenticated()}
+ * property. Defaults to false
, meaning by default the
+ * Authentication.isAuthenticated()
property is trusted
+ * and re-authentication will not occur if the principal has already
+ * been authenticated.
+ *
+ * @param alwaysReauthenticate true
to force
+ * AbstractSecurityInterceptor
to disregard the
+ * value of Authentication.isAuthenticated()
and
+ * always re-authenticate the request (defaults to
+ * false
).
+ */
+ 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
+ * true
), essentially you are ensuring that every secure
+ * object invocation advised by
+ * AbstractSecurityInterceptor
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 IllegalArgumentException
+ * will be thrown by the AbstractSecurityInterceptor
if
+ * you set this property to true
and an attempt is made
+ * to invoke a secure object that has no configuration attributes.
+ *
+ * @param rejectPublicInvocations set to true
to reject
+ * invocations of secure objects that have no configuration
+ * attributes (by default it is true
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;
}
}
-
- /**
- * Helper method which generates an exception containing the passed reason,
- * and publishes an event to the application context.
- *
- * - * Always throws an exception. - *
- * - * @param reason to be provided in the exception detail - * @param secureObject that was being called - * @param configAttribs that were defined for the secureObject - */ - private void credentialsNotFound(String reason, Object secureObject, - ConfigAttributeDefinition configAttribs) { - AuthenticationCredentialsNotFoundException exception = new AuthenticationCredentialsNotFoundException(reason); - - AuthenticationCredentialsNotFoundEvent event = new AuthenticationCredentialsNotFoundEvent(secureObject, - configAttribs, exception); - this.eventPublisher.publishEvent(event); - - throw exception; - } -} diff --git a/core/src/main/java/org/acegisecurity/messages.properties b/core/src/main/java/org/acegisecurity/messages.properties new file mode 100644 index 0000000000..7b70e0c659 --- /dev/null +++ b/core/src/main/java/org/acegisecurity/messages.properties @@ -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 diff --git a/core/src/main/java/org/acegisecurity/providers/ProviderManager.java b/core/src/main/java/org/acegisecurity/providers/ProviderManager.java index 9ef142acd2..77b321ac8b 100644 --- a/core/src/main/java/org/acegisecurity/providers/ProviderManager.java +++ b/core/src/main/java/org/acegisecurity/providers/ProviderManager.java @@ -24,9 +24,11 @@ import org.acegisecurity.BadCredentialsException; import org.acegisecurity.CredentialsExpiredException; import org.acegisecurity.DisabledException; import org.acegisecurity.LockedException; + import org.acegisecurity.concurrent.ConcurrentLoginException; import org.acegisecurity.concurrent.ConcurrentSessionController; import org.acegisecurity.concurrent.NullConcurrentSessionController; + import org.acegisecurity.event.authentication.AbstractAuthenticationEvent; import org.acegisecurity.event.authentication.AuthenticationFailureBadCredentialsEvent; 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.AuthenticationFailureServiceExceptionEvent; import org.acegisecurity.event.authentication.AuthenticationSuccessEvent; + import org.acegisecurity.providers.cas.ProxyUntrustedException; 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.ApplicationEventPublisherAware; +import org.springframework.context.MessageSource; +import org.springframework.context.MessageSourceAware; +import org.springframework.context.support.MessageSourceAccessor; import org.springframework.util.Assert; @@ -85,8 +91,8 @@ import java.util.Properties; * If a validAuthentication
is returned by an
* AuthenticationProvider
, the ProviderManager
will
* publish an {@link
- * org.acegisecurity.event.authentication.AuthenticationSuccessEvent}. If
- * an AuthenticationException
is detected, the final
+ * org.acegisecurity.event.authentication.AuthenticationSuccessEvent}. If an
+ * AuthenticationException
is detected, the final
* AuthenticationException
thrown will be used to publish an
* appropriate failure event. By default ProviderManager
maps
* 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.
*
*
- * @author Ben Alex
- * @author Wesley Hall
- * @author Ray Krueger
- * @version $Id$
- *
* @see ConcurrentSessionController
*/
public class ProviderManager extends AbstractAuthenticationManager
- implements InitializingBean, ApplicationEventPublisherAware {
+ implements InitializingBean, ApplicationEventPublisherAware,
+ MessageSourceAware {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(ProviderManager.class);
@@ -116,74 +118,14 @@ public class ProviderManager extends AbstractAuthenticationManager
private ApplicationEventPublisher applicationEventPublisher;
private ConcurrentSessionController sessionController = new NullConcurrentSessionController();
private List providers;
+ protected MessageSourceAccessor messages;
private Properties exceptionMappings;
//~ 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 {
checkIfValidList(this.providers);
+ Assert.notNull(this.messages, "A message source must be set");
if (exceptionMappings == null) {
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.
*
@@ -244,8 +203,7 @@ public class ProviderManager extends AbstractAuthenticationManager
AuthenticationException lastException = null;
while (iter.hasNext()) {
- AuthenticationProvider provider = (AuthenticationProvider) iter
- .next();
+ AuthenticationProvider provider = (AuthenticationProvider) iter.next();
if (provider.supports(toTest)) {
logger.debug("Authentication attempt using "
@@ -272,8 +230,10 @@ public class ProviderManager extends AbstractAuthenticationManager
}
if (lastException == null) {
- lastException = new ProviderNotFoundException(
- "No authentication provider for " + toTest.getName());
+ lastException = new ProviderNotFoundException(messages.getMessage(
+ "ProviderManager.providerNotFound",
+ new Object[] {toTest.getName()},
+ "No AuthenticationProvider found for {0}"));
}
// Publish the event
@@ -309,20 +269,69 @@ public class ProviderManager extends AbstractAuthenticationManager
throw lastException;
}
- /**
- * 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) {}
+ public List getProviders() {
+ return this.providers;
+ }
- 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;
}
}
diff --git a/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProvider.java
index c69f85a5a8..8858c96918 100644
--- a/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProvider.java
+++ b/core/src/main/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProvider.java
@@ -18,6 +18,7 @@ package org.acegisecurity.providers.anonymous;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.BadCredentialsException;
+
import org.acegisecurity.providers.AuthenticationProvider;
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.context.MessageSource;
+import org.springframework.context.MessageSourceAware;
+import org.springframework.context.support.MessageSourceAccessor;
+
import org.springframework.util.Assert;
@@ -37,32 +42,23 @@ import org.springframework.util.Assert;
* org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken#getKeyHash()}
* must match this class' {@link #getKey()}.
*
- *
- * @author Ben Alex
- * @version $Id$
*/
public class AnonymousAuthenticationProvider implements AuthenticationProvider,
- InitializingBean {
+ InitializingBean, MessageSourceAware {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(AnonymousAuthenticationProvider.class);
//~ Instance fields ========================================================
+ protected MessageSourceAccessor messages;
private String key;
//~ Methods ================================================================
- public void setKey(String key) {
- this.key = key;
- }
-
- public String getKey() {
- return key;
- }
-
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)
@@ -73,13 +69,26 @@ public class AnonymousAuthenticationProvider implements AuthenticationProvider,
if (this.key.hashCode() != ((AnonymousAuthenticationToken) authentication)
.getKeyHash()) {
- throw new BadCredentialsException(
- "The presented AnonymousAuthenticationToken does not contain the expected key");
+ throw new BadCredentialsException(messages.getMessage(
+ "AnonymousAuthenticationProvider.incorrectKey",
+ "The presented AnonymousAuthenticationToken does not contain the expected key"));
}
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) {
return (AnonymousAuthenticationToken.class.isAssignableFrom(authentication));
}
diff --git a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java
index 503407bc0a..6d03891a21 100644
--- a/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java
+++ b/core/src/main/java/org/acegisecurity/providers/cas/CasAuthenticationProvider.java
@@ -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");
* 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.BadCredentialsException;
import org.acegisecurity.UserDetails;
+
import org.acegisecurity.providers.AuthenticationProvider;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+
import org.acegisecurity.ui.cas.CasProcessingFilter;
import org.apache.commons.logging.Log;
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;
@@ -42,12 +49,9 @@ import org.springframework.util.Assert;
* CasProcessingFilter#CAS_STATELESS_IDENTIFIER}. It can also validate a
* previously created {@link CasAuthenticationToken}.
*
- *
- * @author Ben Alex
- * @version $Id$
*/
public class CasAuthenticationProvider implements AuthenticationProvider,
- InitializingBean {
+ InitializingBean, MessageSourceAware {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(CasAuthenticationProvider.class);
@@ -56,60 +60,23 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
private CasAuthoritiesPopulator casAuthoritiesPopulator;
private CasProxyDecider casProxyDecider;
+ protected MessageSourceAccessor messages;
private StatelessTicketCache statelessTicketCache;
private String key;
private TicketValidator ticketValidator;
//~ 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 {
- 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.casProxyDecider, "A casProxyDecider must be set");
- Assert.notNull(this.statelessTicketCache, "A statelessTicketCache must be set");
- Assert.notNull(key, "A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated");
+ Assert.notNull(this.statelessTicketCache,
+ "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)
@@ -133,16 +100,18 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
.getKeyHash()) {
return authentication;
} else {
- throw new BadCredentialsException(
- "The presented CasAuthenticationToken does not contain the expected key");
+ throw new BadCredentialsException(messages.getMessage(
+ "CasAuthenticationProvider.incorrectKey",
+ "The presented CasAuthenticationToken does not contain the expected key"));
}
}
// Ensure credentials are presented
if ((authentication.getCredentials() == null)
|| "".equals(authentication.getCredentials())) {
- throw new BadCredentialsException(
- "Failed to provide a CAS service ticket to validate");
+ throw new BadCredentialsException(messages.getMessage(
+ "CasAuthenticationProvider.noServiceTicket",
+ "Failed to provide a CAS service ticket to validate"));
}
boolean stateless = false;
@@ -173,17 +142,6 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
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(
Authentication authentication) throws AuthenticationException {
// Validate
@@ -203,4 +161,61 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
userDetails, response.getProxyList(),
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;
+ }
+ }
}
diff --git a/core/src/main/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDecider.java b/core/src/main/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDecider.java
index 19867f7014..d7af3b6bb0 100644
--- a/core/src/main/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDecider.java
+++ b/core/src/main/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDecider.java
@@ -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");
* 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.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.List;
@@ -35,11 +40,9 @@ import java.util.List;
* Also accepts the request if there was no proxy (ie the user directly
* authenticated against this service).
*
- *
- * @author Ben Alex
- * @version $Id$
*/
-public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean {
+public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean,
+ MessageSourceAware {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(NamedCasProxyDecider.class);
@@ -47,19 +50,13 @@ public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean {
//~ Instance fields ========================================================
private List validProxies;
+ protected MessageSourceAccessor messages;
//~ Methods ================================================================
- public void setValidProxies(List validProxies) {
- this.validProxies = validProxies;
- }
-
- public List getValidProxies() {
- return validProxies;
- }
-
public void afterPropertiesSet() throws Exception {
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)
@@ -76,8 +73,22 @@ public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean {
}
if (!validProxies.contains(proxyList.get(0))) {
- throw new ProxyUntrustedException("Nearest proxy '"
- + proxyList.get(0) + "' is untrusted");
+ throw new ProxyUntrustedException(messages.getMessage(
+ "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;
+ }
}
diff --git a/core/src/main/java/org/acegisecurity/providers/cas/proxy/RejectProxyTickets.java b/core/src/main/java/org/acegisecurity/providers/cas/proxy/RejectProxyTickets.java
index 5cbf957fb1..be5fdafe9d 100644
--- a/core/src/main/java/org/acegisecurity/providers/cas/proxy/RejectProxyTickets.java
+++ b/core/src/main/java/org/acegisecurity/providers/cas/proxy/RejectProxyTickets.java
@@ -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");
* 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.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.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
* proxy tickets at all).
*
- *
- * @author Ben Alex
- * @version $Id$
*/
-public class RejectProxyTickets implements CasProxyDecider {
+public class RejectProxyTickets implements CasProxyDecider, MessageSourceAware,
+ InitializingBean {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(RejectProxyTickets.class);
+ //~ Instance fields ========================================================
+
+ protected MessageSourceAccessor messages;
+
//~ Methods ================================================================
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(this.messages, "A message source must be set");
+ }
+
public void confirmProxyListTrusted(List proxyList)
throws ProxyUntrustedException {
Assert.notNull(proxyList, "proxyList cannot be null");
@@ -54,9 +67,14 @@ public class RejectProxyTickets implements CasProxyDecider {
if (logger.isDebugEnabled()) {
logger.debug("Proxies are unacceptable; proxy list provided: "
- + 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);
}
}
diff --git a/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java
index 7e593a47bb..3deb9d3ecb 100644
--- a/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java
+++ b/core/src/main/java/org/acegisecurity/providers/dao/AbstractUserDetailsAuthenticationProvider.java
@@ -22,12 +22,17 @@ import org.acegisecurity.CredentialsExpiredException;
import org.acegisecurity.DisabledException;
import org.acegisecurity.LockedException;
import org.acegisecurity.UserDetails;
+
import org.acegisecurity.providers.AuthenticationProvider;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.dao.cache.NullUserCache;
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;
@@ -62,110 +67,17 @@ import org.springframework.util.Assert;
* incorrect password, the {@link AuthenticationDao} will be queried to
* confirm the most up-to-date password was used for comparison.
*
- *
- * @author Ben Alex
- * @version $Id$
*/
public abstract class AbstractUserDetailsAuthenticationProvider
- implements AuthenticationProvider, InitializingBean {
+ implements AuthenticationProvider, InitializingBean, MessageSourceAware {
//~ Instance fields ========================================================
+ protected MessageSourceAccessor messages;
private UserCache userCache = new NullUserCache();
private boolean forcePrincipalAsString = false;
//~ 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
* cached) UserDetails
for a given authentication request.
@@ -190,8 +102,132 @@ public abstract class AbstractUserDetailsAuthenticationProvider
UsernamePasswordAuthenticationToken authentication)
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.
+ *
+ * + * Protected so subclasses can override. + *
+ * + *
+ * Subclasses will usually store the original credentials the user supplied
+ * (not salted or encoded passwords) in the returned
+ * Authentication
object.
+ *
DaoAuthenticationProvider
for validation
+ * @param user that was loaded by the AuthenticationDao
+ *
+ * @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 {}
+ public UserCache getUserCache() {
+ return userCache;
+ }
+
+ public boolean isForcePrincipalAsString() {
+ return forcePrincipalAsString;
+ }
+
/**
* Allows subclasses to actually retrieve the UserDetails
from
* an implementation-specific location, with the option of throwing an
@@ -243,38 +279,19 @@ public abstract class AbstractUserDetailsAuthenticationProvider
UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException;
- /**
- * Creates a successful {@link Authentication} object.
- *
- * - * Protected so subclasses can override. - *
- * - *
- * Subclasses will usually store the original credentials the user supplied
- * (not salted or encoded passwords) in the returned
- * Authentication
object.
- *
DaoAuthenticationProvider
for validation
- * @param user that was loaded by the AuthenticationDao
- *
- * @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);
+ public void setForcePrincipalAsString(boolean forcePrincipalAsString) {
+ this.forcePrincipalAsString = forcePrincipalAsString;
+ }
- 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));
}
}
diff --git a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java
index f54f926108..9ad3a04a23 100644
--- a/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java
+++ b/core/src/main/java/org/acegisecurity/providers/dao/DaoAuthenticationProvider.java
@@ -19,6 +19,7 @@ import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationServiceException;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.UserDetails;
+
import org.acegisecurity.providers.AuthenticationProvider;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.encoding.PasswordEncoder;
@@ -32,9 +33,6 @@ import org.springframework.util.Assert;
/**
* An {@link AuthenticationProvider} implementation that retrieves user details
* from an {@link AuthenticationDao}.
- *
- * @author Ben Alex
- * @version $Id$
*/
public class DaoAuthenticationProvider
extends AbstractUserDetailsAuthenticationProvider {
@@ -47,68 +45,6 @@ public class DaoAuthenticationProvider
//~ Methods ================================================================
- public void setAuthenticationDao(AuthenticationDao authenticationDao) {
- this.authenticationDao = authenticationDao;
- }
-
- public AuthenticationDao getAuthenticationDao() {
- return authenticationDao;
- }
-
- /**
- * By default the DaoAuthenticationProvider
throws a
- * BadCredentialsException
if a username is not found or the
- * password is incorrect. Setting this property to false
will
- * cause UsernameNotFoundException
s to be thrown instead for
- * the former. Note this is considered less secure than throwing
- * BadCredentialsException
for both exceptions.
- *
- * @param hideUserNotFoundExceptions set to false
if you wish
- * UsernameNotFoundException
s to be thrown instead of
- * the non-specific BadCredentialsException
(defaults
- * to true
)
- */
- 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. null
- * is a valid value, meaning the DaoAuthenticationProvider
- * will present null
to the relevant
- * PasswordEncoder
.
- *
- * @param saltSource to use when attempting to decode passwords via the
- * PasswordEncoder
- */
- public void setSaltSource(SaltSource saltSource) {
- this.saltSource = saltSource;
- }
-
- public SaltSource getSaltSource() {
- return saltSource;
- }
-
protected void additionalAuthenticationChecks(UserDetails userDetails,
UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
@@ -120,7 +56,9 @@ public class DaoAuthenticationProvider
if (!passwordEncoder.isPasswordValid(userDetails.getPassword(),
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");
}
+ 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,
UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
@@ -138,20 +92,70 @@ public class DaoAuthenticationProvider
loadedUser = this.authenticationDao.loadUserByUsername(username);
} catch (UsernameNotFoundException notFound) {
if (hideUserNotFoundExceptions) {
- throw new BadCredentialsException("Bad credentials presented");
+ throw new BadCredentialsException(messages.getMessage(
+ "AbstractUserDetailsAuthenticationProvider.badCredentials",
+ "Bad credentials"));
} else {
throw notFound;
}
} catch (DataAccessException repositoryProblem) {
throw new AuthenticationServiceException(repositoryProblem
- .getMessage(), repositoryProblem);
+ .getMessage(), repositoryProblem);
+ }
+
+ if (loadedUser == null) {
+ throw new AuthenticationServiceException(
+ "AuthenticationDao returned null, which is an interface contract violation");
+ }
+
+ return loadedUser;
}
- if (loadedUser == null) {
- throw new AuthenticationServiceException(
- "AuthenticationDao returned null, which is an interface contract violation");
+ public void setAuthenticationDao(AuthenticationDao authenticationDao) {
+ this.authenticationDao = authenticationDao;
}
- return loadedUser;
+ /**
+ * By default the DaoAuthenticationProvider
throws a
+ * BadCredentialsException
if a username is not found or
+ * the password is incorrect. Setting this property to
+ * false
will cause
+ * UsernameNotFoundException
s to be thrown instead for
+ * the former. Note this is considered less secure than throwing
+ * BadCredentialsException
for both exceptions.
+ *
+ * @param hideUserNotFoundExceptions set to false
if you
+ * wish UsernameNotFoundException
s to be thrown
+ * instead of the non-specific
+ * BadCredentialsException
(defaults to
+ * true
)
+ */
+ 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.
+ * null
is a valid value, meaning the
+ * DaoAuthenticationProvider
will present
+ * null
to the relevant PasswordEncoder
.
+ *
+ * @param saltSource to use when attempting to decode passwords via the
+ * PasswordEncoder
+ */
+ public void setSaltSource(SaltSource saltSource) {
+ this.saltSource = saltSource;
+ }
}
-}
diff --git a/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProvider.java
index f49f53e0d3..c397e061bc 100644
--- a/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProvider.java
+++ b/core/src/main/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProvider.java
@@ -18,6 +18,7 @@ package org.acegisecurity.providers.rememberme;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.BadCredentialsException;
+
import org.acegisecurity.providers.AuthenticationProvider;
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.context.MessageSource;
+import org.springframework.context.MessageSourceAware;
+import org.springframework.context.support.MessageSourceAccessor;
+
import org.springframework.util.Assert;
@@ -37,32 +42,23 @@ import org.springframework.util.Assert;
* org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken#getKeyHash()}
* must match this class' {@link #getKey()}.
*
- *
- * @author Ben Alex
- * @version $Id$
*/
public class RememberMeAuthenticationProvider implements AuthenticationProvider,
- InitializingBean {
+ InitializingBean, MessageSourceAware {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(RememberMeAuthenticationProvider.class);
//~ Instance fields ========================================================
+ protected MessageSourceAccessor messages;
private String key;
//~ Methods ================================================================
- public void setKey(String key) {
- this.key = key;
- }
-
- public String getKey() {
- return key;
- }
-
public void afterPropertiesSet() throws Exception {
Assert.hasLength(key);
+ Assert.notNull(this.messages, "A message source must be set");
}
public Authentication authenticate(Authentication authentication)
@@ -73,13 +69,26 @@ public class RememberMeAuthenticationProvider implements AuthenticationProvider,
if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication)
.getKeyHash()) {
- throw new BadCredentialsException(
- "The presented RememberMeAuthenticationToken does not contain the expected key");
+ throw new BadCredentialsException(messages.getMessage(
+ "RememberMeAuthenticationProvider.incorrectKey",
+ "The presented RememberMeAuthenticationToken does not contain the expected key"));
}
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) {
return (RememberMeAuthenticationToken.class.isAssignableFrom(authentication));
}
diff --git a/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationProvider.java b/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationProvider.java
index 360ae5b630..d5f03891e3 100644
--- a/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationProvider.java
+++ b/core/src/main/java/org/acegisecurity/providers/x509/X509AuthenticationProvider.java
@@ -15,71 +15,81 @@
package org.acegisecurity.providers.x509;
-import org.acegisecurity.providers.AuthenticationProvider;
-import org.acegisecurity.providers.x509.cache.NullX509UserCache;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
-import org.acegisecurity.UserDetails;
import org.acegisecurity.BadCredentialsException;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.util.Assert;
+import org.acegisecurity.UserDetails;
+
+import org.acegisecurity.providers.AuthenticationProvider;
+import org.acegisecurity.providers.x509.cache.NullX509UserCache;
+
import org.apache.commons.logging.Log;
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;
+
/**
* Processes an X.509 authentication request.
+ *
* - * The request will typically originate from - * {@link org.acegisecurity.ui.x509.X509ProcessingFilter}). + * The request will typically originate from {@link + * org.acegisecurity.ui.x509.X509ProcessingFilter}). *
- * - * @author Luke Taylor - * @version $Id$ */ public class X509AuthenticationProvider implements AuthenticationProvider, - InitializingBean { + InitializingBean, MessageSourceAware { //~ Static fields/initializers ============================================= - + private static final Log logger = LogFactory.getLog(X509AuthenticationProvider.class); //~ Instance fields ======================================================== + protected MessageSourceAccessor messages; private X509AuthoritiesPopulator x509AuthoritiesPopulator; private X509UserCache userCache = new NullX509UserCache(); //~ Methods ================================================================ - public void setX509AuthoritiesPopulator(X509AuthoritiesPopulator x509AuthoritiesPopulator) { - this.x509AuthoritiesPopulator = x509AuthoritiesPopulator; - } - - public void setX509UserCache(X509UserCache cache) { - this.userCache = cache; - } - public void afterPropertiesSet() throws Exception { 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 - * to the configured {@link X509AuthoritiesPopulator} - * to obtain the user details and authorities for the user identified by the certificate. + * If the supplied authentication token contains a certificate then this + * will be passed to the configured {@link X509AuthoritiesPopulator} to + * obtain the user details and authorities for the user identified by the + * certificate. + * *- * If no certificate is present (for example, if the filter is applied to an HttpRequest for which - * client authentication hasn't been configured in the container) then a BadCredentialsException will be raised. + * If no certificate is present (for example, if the filter is applied to + * an HttpRequest for which client authentication hasn't been configured + * in the container) then a BadCredentialsException will be raised. *
* * @param authentication the authentication request. - * @return an X509AuthenticationToken containing the authorities of the principal represented by the - * certificate. - * @throws AuthenticationException if the {@link X509AuthoritiesPopulator} rejects the certficate. - * @throws BadCredentialsException if no certificate was presented in the authentication request. + * + * @return an X509AuthenticationToken containing the authorities of the + * principal represented by the certificate. + * + * @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())) { return null; } @@ -88,25 +98,42 @@ public class X509AuthenticationProvider implements AuthenticationProvider, logger.debug("X509 authentication request: " + authentication); } - X509Certificate clientCertificate = (X509Certificate)authentication.getCredentials(); + X509Certificate clientCertificate = (X509Certificate) authentication + .getCredentials(); - if(clientCertificate == null) { - throw new BadCredentialsException("Certificate is null."); + if (clientCertificate == null) { + throw new BadCredentialsException(messages.getMessage( + "X509AuthenticationProvider.certificateNull", + "Certificate is null")); + } + + UserDetails user = userCache.getUserFromCache(clientCertificate); + + if (user == null) { + logger.debug("Authenticating with certificate " + + clientCertificate); + user = x509AuthoritiesPopulator.getUserDetails(clientCertificate); + userCache.putUserInCache(clientCertificate, user); + } + + return new X509AuthenticationToken(user, clientCertificate, + user.getAuthorities()); } - UserDetails user = userCache.getUserFromCache(clientCertificate); - - if(user == null) { - logger.debug("Authenticating with certificate " + clientCertificate); - user = x509AuthoritiesPopulator.getUserDetails(clientCertificate); - userCache.putUserInCache(clientCertificate, user); + public void setMessageSource(MessageSource messageSource) { + this.messages = new MessageSourceAccessor(messageSource); } - return new X509AuthenticationToken(user, clientCertificate, user.getAuthorities()); - } + public void setX509AuthoritiesPopulator( + X509AuthoritiesPopulator x509AuthoritiesPopulator) { + this.x509AuthoritiesPopulator = x509AuthoritiesPopulator; + } - public boolean supports(Class authentication) { - return X509AuthenticationToken.class.isAssignableFrom(authentication); - } + public void setX509UserCache(X509UserCache cache) { + this.userCache = cache; + } -} + public boolean supports(Class authentication) { + return X509AuthenticationToken.class.isAssignableFrom(authentication); + } + } diff --git a/core/src/main/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulator.java b/core/src/main/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulator.java index d5d9269dbc..89492549fc 100644 --- a/core/src/main/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulator.java +++ b/core/src/main/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulator.java @@ -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"); * you may not use this file except in compliance with the License. @@ -16,29 +16,34 @@ package org.acegisecurity.providers.x509.populator; import org.acegisecurity.AuthenticationException; -import org.acegisecurity.UserDetails; import org.acegisecurity.BadCredentialsException; +import org.acegisecurity.UserDetails; + import org.acegisecurity.providers.dao.AuthenticationDao; 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.LogFactory; + 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; - /** - * Populates the X509 authorities via an {@link org.acegisecurity.providers.dao.AuthenticationDao}. - * - * @author Luke Taylor - * @version $Id$ + * Populates the X509 authorities via an {@link + * org.acegisecurity.providers.dao.AuthenticationDao}. */ public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator, - InitializingBean { + InitializingBean, MessageSourceAware { //~ Static fields/initializers ============================================= private static final Log logger = LogFactory.getLog(DaoX509AuthoritiesPopulator.class); @@ -46,18 +51,64 @@ public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator, //~ Instance fields ======================================================== private AuthenticationDao authenticationDao; - private String subjectDNRegex = "CN=(.*?),"; + protected MessageSourceAccessor messages; private Pattern subjectDNPattern; + private String subjectDNRegex = "CN=(.*?),"; //~ 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) { 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 * from the certificate's Subject DN. + * ** It should contain a single group; for example the default expression * "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) { 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); - } - } } diff --git a/core/src/main/java/org/acegisecurity/runas/RunAsImplAuthenticationProvider.java b/core/src/main/java/org/acegisecurity/runas/RunAsImplAuthenticationProvider.java index 3101983023..290bc9b04f 100644 --- a/core/src/main/java/org/acegisecurity/runas/RunAsImplAuthenticationProvider.java +++ b/core/src/main/java/org/acegisecurity/runas/RunAsImplAuthenticationProvider.java @@ -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"); * 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.AuthenticationException; import org.acegisecurity.BadCredentialsException; + import org.acegisecurity.providers.AuthenticationProvider; 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; @@ -38,28 +44,19 @@ import org.springframework.util.Assert; *
* If the key does not match, a BadCredentialsException
is thrown.
*
* If authentication is successful, an {@link
- * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} will be
- * published to the application context. No events will be published if
- * authentication was unsuccessful, because this would generally be recorded
- * via an AuthenticationManager
-specific application event.
+ * org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent}
+ * will be published to the application context. No events will be published
+ * if authentication was unsuccessful, because this would generally be
+ * recorded via an AuthenticationManager
-specific application
+ * event.
*
filterProcessesUrl
for the
- * implementation.
- *
- * @return the default filterProcessesUrl
- */
- 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;
+ 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);
}
/**
@@ -247,34 +204,6 @@ public abstract class AbstractProcessingFilter implements Filter,
public abstract Authentication attemptAuthentication(
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.
*/
@@ -324,6 +253,38 @@ public abstract class AbstractProcessingFilter implements Filter,
chain.doFilter(request, response);
}
+ public String getAuthenticationFailureUrl() {
+ return authenticationFailureUrl;
+ }
+
+ public AuthenticationManager getAuthenticationManager() {
+ return authenticationManager;
+ }
+
+ /**
+ * Specifies the default filterProcessesUrl
for the
+ * implementation.
+ *
+ * @return the default filterProcessesUrl
+ */
+ 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.
*
@@ -333,6 +294,14 @@ public abstract class AbstractProcessingFilter implements Filter,
*/
public void init(FilterConfig arg0) throws ServletException {}
+ public boolean isAlwaysUseDefaultTargetUrl() {
+ return alwaysUseDefaultTargetUrl;
+ }
+
+ public boolean isContinueChainBeforeSuccessfulAuthentication() {
+ return continueChainBeforeSuccessfulAuthentication;
+ }
+
protected void onPreAuthentication(HttpServletRequest request,
HttpServletResponse response) throws IOException {}
@@ -380,6 +349,49 @@ public abstract class AbstractProcessingFilter implements Filter,
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,
HttpServletResponse response, Authentication authResult)
throws IOException {
@@ -395,7 +407,8 @@ public abstract class AbstractProcessingFilter implements Filter,
+ 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);
if (alwaysUseDefaultTargetUrl == true) {
@@ -444,8 +457,8 @@ public abstract class AbstractProcessingFilter implements Filter,
}
try {
- request.getSession().setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY,
- failed);
+ request.getSession()
+ .setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed);
} catch (Exception ignored) {}
onUnsuccessfulAuthentication(request, response);
diff --git a/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java
index 013dcd2cfc..b35c00ee8d 100644
--- a/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java
+++ b/core/src/main/java/org/acegisecurity/ui/digestauth/DigestProcessingFilter.java
@@ -19,13 +19,17 @@ import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationServiceException;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.UserDetails;
+
import org.acegisecurity.context.SecurityContextHolder;
+
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.dao.AuthenticationDao;
import org.acegisecurity.providers.dao.UserCache;
import org.acegisecurity.providers.dao.UsernameNotFoundException;
import org.acegisecurity.providers.dao.cache.NullUserCache;
+
import org.acegisecurity.ui.WebAuthenticationDetails;
+
import org.acegisecurity.util.StringSplitUtils;
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.context.MessageSource;
+import org.springframework.context.MessageSourceAware;
+import org.springframework.context.support.MessageSourceAccessor;
+
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -72,19 +80,22 @@ import javax.servlet.http.HttpServletResponse;
* * This Digest implementation has been designed to avoid needing to store * 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}. *
* *
- * If authentication is successful, the resulting {@link org.acegisecurity.Authentication Authentication}
- * object will be placed into the SecurityContextHolder
.
+ * If authentication is successful, the resulting {@link
+ * org.acegisecurity.Authentication Authentication} object will be placed into
+ * the SecurityContextHolder
.
*
- * If authentication fails, an - * {@link org.acegisecurity.intercept.web.AuthenticationEntryPoint AuthenticationEntryPoint} - * implementation is called. This must always be {@link DigestProcessingFilterEntryPoint}, - * which will prompt the user to authenticate again via Digest authentication. + * If authentication fails, an {@link + * org.acegisecurity.intercept.web.AuthenticationEntryPoint + * AuthenticationEntryPoint} implementation is called. This must always be + * {@link DigestProcessingFilterEntryPoint}, which will prompt the user to + * authenticate again via Digest authentication. *
* *
@@ -100,11 +111,9 @@ import javax.servlet.http.HttpServletResponse;
* web.xml
to use the {@link
* org.acegisecurity.util.FilterToBeanProxy}.
*
response
portion of a Digest authentication
* header. Both the server and user agent should compute the
* response
independently. Provided as a static method to
* simplify the coding of user agents.
*
+ * @param passwordAlreadyEncoded DOCUMENT ME!
* @param username DOCUMENT ME!
* @param realm DOCUMENT ME!
* @param password DOCUMENT ME!
@@ -408,19 +427,20 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
*
* @throws IllegalArgumentException DOCUMENT ME!
*/
- public static String generateDigest(boolean passwordAlreadyEncoded, String username, String realm,
- String password, String httpMethod, String uri, String qop,
- String nonce, String nc, String cnonce) throws IllegalArgumentException {
+ public static String generateDigest(boolean passwordAlreadyEncoded,
+ String username, String realm, String password, String httpMethod,
+ String uri, String qop, String nonce, String nc, String cnonce)
+ throws IllegalArgumentException {
String a1Md5 = null;
String a2 = httpMethod + ":" + uri;
String a2Md5 = new String(DigestUtils.md5Hex(a2));
-
+
if (passwordAlreadyEncoded) {
- a1Md5 = password;
+ a1Md5 = password;
} else {
- a1Md5 = encodePasswordInA1Format(username, realm, password);
+ a1Md5 = encodePasswordInA1Format(username, realm, password);
}
-
+
String digest;
if (qop == null) {
@@ -440,8 +460,12 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
return digestMd5;
}
- public void setUserCache(UserCache userCache) {
- this.userCache = userCache;
+ public AuthenticationDao getAuthenticationDao() {
+ return authenticationDao;
+ }
+
+ public DigestProcessingFilterEntryPoint getAuthenticationEntryPoint() {
+ return authenticationEntryPoint;
}
public UserCache getUserCache() {
@@ -450,14 +474,24 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
public void init(FilterConfig ignored) throws ServletException {}
- private void fail(ServletRequest request, ServletResponse response,
- AuthenticationException failed) throws IOException, ServletException {
- SecurityContextHolder.getContext().setAuthentication(null);
+ public void setAuthenticationDao(AuthenticationDao authenticationDao) {
+ this.authenticationDao = authenticationDao;
+ }
- if (logger.isDebugEnabled()) {
- logger.debug(failed);
- }
+ public void setAuthenticationEntryPoint(
+ DigestProcessingFilterEntryPoint authenticationEntryPoint) {
+ this.authenticationEntryPoint = authenticationEntryPoint;
+ }
- authenticationEntryPoint.commence(request, response, failed);
+ 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;
}
}
diff --git a/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilter.java b/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilter.java
index d26f8cd2d1..9d96b0513c 100644
--- a/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilter.java
+++ b/core/src/main/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilter.java
@@ -22,12 +22,17 @@ import org.acegisecurity.AuthenticationException;
import org.acegisecurity.CredentialsExpiredException;
import org.acegisecurity.DisabledException;
import org.acegisecurity.GrantedAuthority;
+import org.acegisecurity.LockedException;
import org.acegisecurity.UserDetails;
+
import org.acegisecurity.context.SecurityContextHolder;
+
import org.acegisecurity.event.authentication.AuthenticationSwitchUserEvent;
+
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.dao.AuthenticationDao;
import org.acegisecurity.providers.dao.UsernameNotFoundException;
+
import org.acegisecurity.ui.WebAuthenticationDetails;
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.factory.InitializingBean;
-import org.springframework.context.ApplicationEventPublisherAware;
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;
@@ -80,8 +88,8 @@ import javax.servlet.http.HttpServletResponse;
*
* On successful switch, the user's SecurityContextHolder
will be
* updated to reflect the specified user and will also contain an additinal
- * {@link org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority }
- * which contains the original user.
+ * {@link org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority } which
+ * contains the original user.
*
@@ -104,13 +112,10 @@ import javax.servlet.http.HttpServletResponse; * *
* - * @author Mark St.Godard - * @version $Id$ - * * @see org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority */ public class SwitchUserProcessingFilter implements Filter, InitializingBean, - ApplicationEventPublisherAware { + ApplicationEventPublisherAware, MessageSourceAware { //~ Static fields/initializers ============================================= private static final Log logger = LogFactory.getLog(SwitchUserProcessingFilter.class); @@ -127,105 +132,21 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, // ~ Instance fields // ======================================================== private AuthenticationDao authenticationDao; + protected MessageSourceAccessor messages; private String exitUserUrl = "/j_acegi_exit_user"; private String switchUserUrl = "/j_acegi_switch_user"; private String targetUrl; //~ 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 { Assert.hasLength(switchUserUrl, "switchUserUrl must be specified"); Assert.hasLength(exitUserUrl, "exitUserUrl must be specified"); Assert.hasLength(targetUrl, "targetUrl 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. * @@ -244,229 +165,397 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean, .getAuthentication(); if (null == current) { - throw new AuthenticationCredentialsNotFoundException( - "No current user associated with this request!"); - } - - // check to see if the current user did actual switch to another user - // if so, get the original source user so we can switch back - Authentication original = getSourceAuthentication(current); - - if (original == null) { - logger.error("Could not find original user Authentication object!"); - throw new AuthenticationCredentialsNotFoundException( - "Could not find original Authentication object!"); - } - - // get the source user details - UserDetails originalUser = null; - Object obj = original.getPrincipal(); - - if ((obj != null) && obj instanceof UserDetails) { - originalUser = (UserDetails) obj; - } - - // publish event - if (this.eventPublisher != null) { - eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(current, - originalUser)); - } - - return original; - } - - /** - * Attempt to switch to another user. If the user does not exist or is not - * active, return null. - * - * @param request The http request - * - * @return The newAuthentication
request if successfully
- * switched to another user, null
otherwise.
- *
- * @throws AuthenticationException
- * @throws UsernameNotFoundException If the target user is not found.
- * @throws DisabledException If the target user is disabled.
- * @throws AccountExpiredException If the target user account is expired.
- * @throws CredentialsExpiredException If the target user credentials are
- * expired.
- */
- protected Authentication attemptSwitchUser(HttpServletRequest request)
- throws AuthenticationException {
- UsernamePasswordAuthenticationToken targetUserRequest = null;
-
- String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
-
- if (username == null) {
- username = "";
- }
-
- if (logger.isDebugEnabled()) {
- logger.debug("Attempt to switch to user [" + username + "]");
- }
-
- // load the user by name
- UserDetails targetUser = this.authenticationDao.loadUserByUsername(username);
-
- // user not found
- if (targetUser == null) {
- throw new UsernameNotFoundException("User [" + username
- + "] cannot be found!");
- }
-
- // user is disabled
- if (!targetUser.isEnabled()) {
- throw new DisabledException("User is disabled");
- }
-
- // account is expired
- if (!targetUser.isAccountNonExpired()) {
- throw new AccountExpiredException("User account has expired");
- }
-
- // credentials expired
- if (!targetUser.isCredentialsNonExpired()) {
- throw new CredentialsExpiredException("User credentials expired");
- }
-
- // ok, create the switch user token
- targetUserRequest = createSwitchUserToken(request, username, targetUser);
-
- if (logger.isDebugEnabled()) {
- logger.debug("Switch User Token [" + targetUserRequest + "]");
- }
-
- // publish event
- if (this.eventPublisher != null) {
- eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
- SecurityContextHolder.getContext().getAuthentication(),
- targetUser));
- }
-
- return targetUserRequest;
- }
-
- /**
- * Checks the request URI for the presence of exitUserUrl.
- *
- * @param request The http servlet request
- *
- * @return true
if the request requires a exit user,
- * false
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 switchUserUrl.
- *
- * @param request The http servlet request
- *
- * @return true
if the request requires a switch,
- * false
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 Authentication
object from the current
- * user's granted authorities. A successfully switched user should have a
- * SwitchUserGrantedAuthority
that contains the original
- * source user Authentication
object.
- *
- * @param current The current Authentication
object
- *
- * @return The source user Authentication
object or
- * null
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 + "]");
+ throw new AuthenticationCredentialsNotFoundException(messages
+ .getMessage("SwitchUserProcessingFilter.noCurrentUser",
+ "No current user associated with this request"));
}
- }
- return original;
- }
+ // check to see if the current user did actual switch to another user
+ // if so, get the original source user so we can switch back
+ Authentication original = getSourceAuthentication(current);
- /**
- * Create a switch user token that contains an additional
- * GrantedAuthority that contains the original
- * Authentication
object.
- *
- * @param request The http servlet request.
- * @param username The username of target user
- * @param targetUser The target user
- *
- * @return The authentication token
- *
- * @see SwitchUserGrantedAuthority
- */
- private UsernamePasswordAuthenticationToken createSwitchUserToken(
- HttpServletRequest request, String username, UserDetails targetUser) {
- UsernamePasswordAuthenticationToken targetUserRequest;
+ if (original == null) {
+ logger.error(
+ "Could not find original user Authentication object!");
+ throw new AuthenticationCredentialsNotFoundException(messages
+ .getMessage(
+ "SwitchUserProcessingFilter.noOriginalAuthentication",
+ "Could not find original Authentication object"));
+ }
- // grant an additional authority that contains the original Authentication object
- // which will be used to 'exit' from the current switched user.
- Authentication currentAuth = SecurityContextHolder.getContext()
- .getAuthentication();
- GrantedAuthority switchAuthority = new SwitchUserGrantedAuthority(ROLE_PREVIOUS_ADMINISTRATOR,
- currentAuth);
+ // get the source user details
+ UserDetails originalUser = null;
+ Object obj = original.getPrincipal();
- // get the original authorities
- List orig = Arrays.asList(targetUser.getAuthorities());
+ if ((obj != null) && obj instanceof UserDetails) {
+ originalUser = (UserDetails) obj;
+ }
- // add the new switch user authority
- List newAuths = new ArrayList(orig);
- newAuths.add(switchAuthority);
+ // publish event
+ if (this.eventPublisher != null) {
+ eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
+ current, originalUser));
+ }
- GrantedAuthority[] authorities = {};
- authorities = (GrantedAuthority[]) newAuths.toArray(authorities);
+ return original;
+ }
- // create the new authentication token
- targetUserRequest = new UsernamePasswordAuthenticationToken(targetUser,
- targetUser.getPassword(), authorities);
+ /**
+ * Attempt to switch to another user. If the user does not exist or
+ * is not active, return null.
+ *
+ * @param request The http request
+ *
+ * @return The new Authentication
request if
+ * successfully switched to another user,
+ * null
otherwise.
+ *
+ * @throws AuthenticationException
+ * @throws UsernameNotFoundException If the target user is not
+ * found.
+ * @throws LockedException DOCUMENT ME!
+ * @throws DisabledException If the target user is disabled.
+ * @throws AccountExpiredException If the target user account is
+ * expired.
+ * @throws CredentialsExpiredException If the target user
+ * credentials are expired.
+ */
+ protected Authentication attemptSwitchUser(
+ HttpServletRequest request) throws AuthenticationException {
+ UsernamePasswordAuthenticationToken targetUserRequest = null;
- // set details
- targetUserRequest.setDetails(new WebAuthenticationDetails(request));
+ String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
- return targetUserRequest;
- }
-}
+ if (username == null) {
+ username = "";
+ }
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Attempt to switch to user [" + username + "]");
+ }
+
+ // load the user by name
+ UserDetails targetUser = this.authenticationDao
+ .loadUserByUsername(username);
+
+ // user not found
+ if (targetUser == null) {
+ throw new UsernameNotFoundException(messages.getMessage(
+ "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
+ if (!targetUser.isEnabled()) {
+ throw new DisabledException(messages.getMessage(
+ "SwitchUserProcessingFilter.disabled",
+ "User is disabled"));
+ }
+
+ // account is expired
+ if (!targetUser.isAccountNonExpired()) {
+ throw new AccountExpiredException(messages.getMessage(
+ "SwitchUserProcessingFilter.expired",
+ "User account has expired"));
+ }
+
+ // credentials expired
+ if (!targetUser.isCredentialsNonExpired()) {
+ throw new CredentialsExpiredException(messages
+ .getMessage(
+ "SwitchUserProcessingFilter.credentialsExpired",
+ "User credentials have expired"));
+ }
+
+ // ok, create the switch user token
+ targetUserRequest = createSwitchUserToken(request,
+ username, targetUser);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Switch User Token ["
+ + targetUserRequest + "]");
+ }
+
+ // publish event
+ if (this.eventPublisher != null) {
+ eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
+ SecurityContextHolder.getContext()
+ .getAuthentication(),
+ targetUser));
+ }
+
+ return targetUserRequest;
+ }
+
+ /**
+ * Create a switch user token that contains an additional
+ * GrantedAuthority that contains the original
+ * Authentication
object.
+ *
+ * @param request The http servlet request.
+ * @param username The username of target user
+ * @param targetUser The target user
+ *
+ * @return The authentication token
+ *
+ * @see SwitchUserGrantedAuthority
+ */
+ private UsernamePasswordAuthenticationToken createSwitchUserToken(
+ HttpServletRequest request, String username,
+ UserDetails targetUser) {
+ UsernamePasswordAuthenticationToken targetUserRequest;
+
+ // grant an additional authority that contains the original Authentication object
+ // which will be used to 'exit' from the current switched user.
+ Authentication currentAuth = SecurityContextHolder.getContext()
+ .getAuthentication();
+ GrantedAuthority switchAuthority = new SwitchUserGrantedAuthority(ROLE_PREVIOUS_ADMINISTRATOR,
+ currentAuth);
+
+ // get the original authorities
+ List orig = Arrays.asList(targetUser.getAuthorities());
+
+ // add the new switch user authority
+ List newAuths = new ArrayList(orig);
+ newAuths.add(switchAuthority);
+
+ GrantedAuthority[] authorities = {};
+ authorities = (GrantedAuthority[]) newAuths.toArray(authorities);
+
+ // create the new authentication token
+ targetUserRequest = new UsernamePasswordAuthenticationToken(targetUser,
+ targetUser.getPassword(), authorities);
+
+ // set details
+ targetUserRequest.setDetails(new WebAuthenticationDetails(
+ request));
+
+ 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
+ * Authentication
object from
+ * the current user's granted authorities.
+ * A successfully switched user should
+ * have a
+ * SwitchUserGrantedAuthority
+ * that contains the original source user
+ * Authentication
object.
+ *
+ * @param current The current
+ * Authentication
+ * object
+ *
+ * @return The source user
+ * Authentication
+ * object or null
+ * 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 exitUserUrl.
+ *
+ * @param request The http servlet request
+ *
+ * @return true
if the request
+ * requires a exit user,
+ * false
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 switchUserUrl.
+ *
+ * @param request The http servlet
+ * request
+ *
+ * @return true
if the
+ * request requires a switch,
+ * false
+ * 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;
+ }
+ }
diff --git a/core/src/main/java/org/acegisecurity/vote/AbstractAccessDecisionManager.java b/core/src/main/java/org/acegisecurity/vote/AbstractAccessDecisionManager.java
index 268b2020ec..82734f0702 100644
--- a/core/src/main/java/org/acegisecurity/vote/AbstractAccessDecisionManager.java
+++ b/core/src/main/java/org/acegisecurity/vote/AbstractAccessDecisionManager.java
@@ -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");
* 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.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.List;
@@ -32,28 +38,42 @@ import java.util.List;
* AccessDecisionVoter}s and the access control behaviour if all voters
* abstain from voting (defaults to deny access).
*
- *
- * @author Ben Alex
- * @version $Id$
*/
public abstract class AbstractAccessDecisionManager
- implements AccessDecisionManager, InitializingBean {
+ implements AccessDecisionManager, InitializingBean, MessageSourceAware {
//~ Instance fields ========================================================
private List decisionVoters;
+ protected MessageSourceAccessor messages;
private boolean allowIfAllAbstainDecisions = false;
//~ Methods ================================================================
- public void setAllowIfAllAbstainDecisions(
- boolean allowIfAllAbstainDecisions) {
- this.allowIfAllAbstainDecisions = allowIfAllAbstainDecisions;
+ public void afterPropertiesSet() throws Exception {
+ checkIfValidList(this.decisionVoters);
+ 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() {
return allowIfAllAbstainDecisions;
}
+ public void setAllowIfAllAbstainDecisions(
+ boolean allowIfAllAbstainDecisions) {
+ this.allowIfAllAbstainDecisions = allowIfAllAbstainDecisions;
+ }
+
public void setDecisionVoters(List newList) {
checkIfValidList(newList);
@@ -76,12 +96,8 @@ public abstract class AbstractAccessDecisionManager
this.decisionVoters = newList;
}
- public List getDecisionVoters() {
- return this.decisionVoters;
- }
-
- public void afterPropertiesSet() throws Exception {
- checkIfValidList(this.decisionVoters);
+ public void setMessageSource(MessageSource messageSource) {
+ this.messages = new MessageSourceAccessor(messageSource);
}
public boolean supports(ConfigAttribute attribute) {
@@ -124,11 +140,4 @@ public abstract class AbstractAccessDecisionManager
return true;
}
-
- private void checkIfValidList(List listToCheck) {
- if ((listToCheck == null) || (listToCheck.size() == 0)) {
- throw new IllegalArgumentException(
- "A list of AccessDecisionVoters is required");
- }
- }
}
diff --git a/core/src/main/java/org/acegisecurity/vote/AffirmativeBased.java b/core/src/main/java/org/acegisecurity/vote/AffirmativeBased.java
index c686b8d3a8..1418cd9dd8 100644
--- a/core/src/main/java/org/acegisecurity/vote/AffirmativeBased.java
+++ b/core/src/main/java/org/acegisecurity/vote/AffirmativeBased.java
@@ -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");
* 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
* org.acegisecurity.AccessDecisionManager} that grants access if any
* AccessDecisionVoter
returns an affirmative response.
- *
- * @author Ben Alex
- * @version $Id$
*/
public class AffirmativeBased extends AbstractAccessDecisionManager {
//~ Static fields/initializers =============================================
@@ -83,14 +80,18 @@ public class AffirmativeBased extends AbstractAccessDecisionManager {
}
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
if (this.isAllowIfAllAbstainDecisions()) {
return;
} else {
- throw new AccessDeniedException("Access is denied.");
+ throw new AccessDeniedException(messages.getMessage(
+ "AbstractAccessDecisionManager.accessDenied",
+ "Access is denied"));
}
}
}
diff --git a/core/src/main/java/org/acegisecurity/vote/ConsensusBased.java b/core/src/main/java/org/acegisecurity/vote/ConsensusBased.java
index 3339f64b90..059e5a6c1f 100644
--- a/core/src/main/java/org/acegisecurity/vote/ConsensusBased.java
+++ b/core/src/main/java/org/acegisecurity/vote/ConsensusBased.java
@@ -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");
* 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
* org.acegisecurity.AccessDecisionManager} that uses a consensus-based
* approach.
- *
- * @author Ben Alex
- * @version $Id$
*/
public class ConsensusBased extends AbstractAccessDecisionManager {
//~ Static fields/initializers =============================================
@@ -44,15 +41,6 @@ public class ConsensusBased extends AbstractAccessDecisionManager {
//~ Methods ================================================================
- public void setAllowIfEqualGrantedDeniedDecisions(
- boolean allowIfEqualGrantedDeniedDecisions) {
- this.allowIfEqualGrantedDeniedDecisions = allowIfEqualGrantedDeniedDecisions;
- }
-
- public boolean isAllowIfEqualGrantedDeniedDecisions() {
- return allowIfEqualGrantedDeniedDecisions;
- }
-
/**
* This concrete implementation simply polls all configured {@link
* AccessDecisionVoter}s and upon completion determines the consensus of
@@ -111,14 +99,18 @@ public class ConsensusBased extends AbstractAccessDecisionManager {
}
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 (this.allowIfEqualGrantedDeniedDecisions) {
return;
} 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()) {
return;
} 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;
+ }
}
diff --git a/core/src/main/java/org/acegisecurity/vote/UnanimousBased.java b/core/src/main/java/org/acegisecurity/vote/UnanimousBased.java
index 642c537a5b..9f362d06ed 100644
--- a/core/src/main/java/org/acegisecurity/vote/UnanimousBased.java
+++ b/core/src/main/java/org/acegisecurity/vote/UnanimousBased.java
@@ -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");
* 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
* org.acegisecurity.AccessDecisionManager} that requires all voters to
* abstain or grant access.
- *
- * @author Ben Alex
- * @version $Id$
*/
public class UnanimousBased extends AbstractAccessDecisionManager {
//~ Static fields/initializers =============================================
@@ -105,7 +102,9 @@ public class UnanimousBased extends AbstractAccessDecisionManager {
}
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
@@ -117,7 +116,9 @@ public class UnanimousBased extends AbstractAccessDecisionManager {
if (this.isAllowIfAllAbstainDecisions()) {
return;
} else {
- throw new AccessDeniedException("Access is denied.");
+ throw new AccessDeniedException(messages.getMessage(
+ "AbstractAccessDecisionManager.accessDenied",
+ "Access is denied"));
}
}
}
diff --git a/core/src/test/java/org/acegisecurity/adapters/AuthByAdapterTests.java b/core/src/test/java/org/acegisecurity/adapters/AuthByAdapterTests.java
index ddcbe26451..19ac5a7485 100644
--- a/core/src/test/java/org/acegisecurity/adapters/AuthByAdapterTests.java
+++ b/core/src/test/java/org/acegisecurity/adapters/AuthByAdapterTests.java
@@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+import org.springframework.context.support.StaticMessageSource;
/**
@@ -81,6 +82,7 @@ public class AuthByAdapterTests extends TestCase {
public void testAuthByAdapterProviderNonAuthenticationMethods()
throws Exception {
AuthByAdapterProvider provider = new AuthByAdapterProvider();
+ provider.setMessageSource(new StaticMessageSource());
try {
provider.afterPropertiesSet();
@@ -99,6 +101,7 @@ public class AuthByAdapterTests extends TestCase {
public void testAuthByAdapterProviderOnlyAcceptsAuthByAdapterImplementations()
throws Exception {
AuthByAdapterProvider provider = new AuthByAdapterProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setKey("my_password");
// Should fail as UsernamePassword is not interface of AuthByAdapter
@@ -119,6 +122,7 @@ public class AuthByAdapterTests extends TestCase {
public void testAuthByAdapterProviderRequiresCorrectKey()
throws Exception {
AuthByAdapterProvider provider = new AuthByAdapterProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setKey("my_password");
// Should fail as PrincipalAcegiUserToken has different key
diff --git a/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProviderTests.java b/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProviderTests.java
index 1bb23cf69c..cca7f77036 100644
--- a/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProviderTests.java
+++ b/core/src/test/java/org/acegisecurity/afterinvocation/BasicAclEntryAfterInvocationProviderTests.java
@@ -27,6 +27,7 @@ import org.acegisecurity.acl.basic.MockAclObjectIdentity;
import org.acegisecurity.acl.basic.SimpleAclEntry;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.util.SimpleMethodInvocation;
+import org.springframework.context.support.StaticMessageSource;
/**
@@ -65,6 +66,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
SimpleAclEntry.ADMINISTRATION)});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager);
provider.afterPropertiesSet();
@@ -94,6 +96,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager);
provider.afterPropertiesSet();
@@ -123,6 +126,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager);
assertEquals(aclManager, provider.getAclManager());
provider.afterPropertiesSet();
@@ -150,6 +154,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager);
provider.afterPropertiesSet();
@@ -171,6 +176,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
new MockAclObjectIdentity(), null, SimpleAclEntry.READ), new MockAclEntry()});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager);
assertEquals("AFTER_ACL_READ", provider.getProcessConfigAttribute());
provider.setProcessConfigAttribute("AFTER_ACL_ADMIN");
@@ -202,6 +208,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
SimpleAclEntry.ADMINISTRATION), new MockAclEntry()});
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAclManager(aclManager);
assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]);
provider.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION});
@@ -222,6 +229,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
public void testStartupDetectsMissingAclManager() throws Exception {
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
+ provider.setMessageSource(new StaticMessageSource());
try {
provider.afterPropertiesSet();
@@ -234,6 +242,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
public void testStartupDetectsMissingProcessConfigAttribute()
throws Exception {
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
+ provider.setMessageSource(new StaticMessageSource());
AclManager aclManager = new MockAclManager("sydney", "marissa",
new AclEntry[] {new SimpleAclEntry("marissa",
new MockAclObjectIdentity(), null,
@@ -254,6 +263,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
public void testStartupDetectsMissingRequirePermission()
throws Exception {
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
+ provider.setMessageSource(new StaticMessageSource());
AclManager aclManager = new MockAclManager("sydney", "marissa",
new AclEntry[] {new SimpleAclEntry("marissa",
new MockAclObjectIdentity(), null,
diff --git a/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImplTests.java b/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImplTests.java
index 58caed15c3..7c42310eac 100644
--- a/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImplTests.java
+++ b/core/src/test/java/org/acegisecurity/concurrent/ConcurrentSessionControllerImplTests.java
@@ -21,6 +21,7 @@ import org.acegisecurity.Authentication;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.ui.WebAuthenticationDetails;
+import org.springframework.context.support.StaticMessageSource;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpSession;
@@ -39,6 +40,7 @@ public class ConcurrentSessionControllerImplTests extends TestCase {
ConcurrentSessionControllerImpl sc = new ConcurrentSessionControllerImpl();
SessionRegistry registry = new SessionRegistryImpl();
sc.setSessionRegistry(registry);
+ sc.setMessageSource(new StaticMessageSource());
// Attempt to authenticate - it should be successful
Authentication auth = createAuthentication("bob", "1212");
diff --git a/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java
index 504c8178ac..a1e1c55bef 100644
--- a/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java
+++ b/core/src/test/java/org/acegisecurity/intercept/method/aopalliance/MethodSecurityInterceptorTests.java
@@ -41,6 +41,7 @@ import org.acegisecurity.runas.RunAsManagerImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.context.support.StaticMessageSource;
import java.lang.reflect.Method;
@@ -177,6 +178,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testRejectsAccessDecisionManagersThatDoNotSupportMethodInvocation()
throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManagerWhichOnlySupportsStrings());
si.setAuthenticationManager(new MockAuthenticationManager());
si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
@@ -212,6 +214,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testRejectsCallsWhenObjectDefinitionSourceDoesNotSupportObject()
throws Throwable {
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
+ interceptor.setMessageSource(new StaticMessageSource());
interceptor.setObjectDefinitionSource(new MockObjectDefinitionSourceWhichOnlySupportsStrings());
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
interceptor.setAuthenticationManager(new MockAuthenticationManager());
@@ -228,6 +231,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testRejectsCallsWhenObjectIsNull() throws Throwable {
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
+ interceptor.setMessageSource(new StaticMessageSource());
try {
interceptor.invoke(null);
@@ -240,6 +244,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testRejectsRunAsManagersThatDoNotSupportMethodInvocation()
throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager());
si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
@@ -258,6 +263,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testStartupCheckForAccessDecisionManager()
throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setRunAsManager(new MockRunAsManager());
si.setAuthenticationManager(new MockAuthenticationManager());
si.setAfterInvocationManager(new MockAfterInvocationManager());
@@ -276,6 +282,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testStartupCheckForAuthenticationManager()
throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setRunAsManager(new MockRunAsManager());
si.setAfterInvocationManager(new MockAfterInvocationManager());
@@ -294,6 +301,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testStartupCheckForMethodDefinitionSource()
throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager());
@@ -308,6 +316,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testStartupCheckForRunAsManager() throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager());
si.setRunAsManager(null); // Overriding the default
@@ -325,6 +334,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testStartupCheckForValidAfterInvocationManager()
throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setRunAsManager(new MockRunAsManager());
si.setAuthenticationManager(new MockAuthenticationManager());
si.setAfterInvocationManager(new MockAfterInvocationManagerWhichOnlySupportsStrings());
@@ -342,6 +352,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testValidationFailsIfInvalidAttributePresented()
throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager());
si.setRunAsManager(new RunAsManagerImpl());
@@ -361,6 +372,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testValidationNotAttemptedIfIsValidateConfigAttributesSetToFalse()
throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager());
@@ -376,6 +388,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
public void testValidationNotAttemptedIfMethodDefinitionSourceCannotReturnIterator()
throws Exception {
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setRunAsManager(new MockRunAsManager());
si.setAuthenticationManager(new MockAuthenticationManager());
diff --git a/core/src/test/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptorTests.java
index 543a9caa95..803d9bd127 100644
--- a/core/src/test/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptorTests.java
+++ b/core/src/test/java/org/acegisecurity/intercept/method/aspectj/AspectJSecurityInterceptorTests.java
@@ -30,6 +30,7 @@ import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.intercept.method.MethodDefinitionMap;
import org.acegisecurity.intercept.method.MethodDefinitionSourceEditor;
import org.acegisecurity.providers.TestingAuthenticationToken;
+import org.springframework.context.support.StaticMessageSource;
import java.lang.reflect.Method;
@@ -64,6 +65,7 @@ public class AspectJSecurityInterceptorTests extends TestCase {
public void testCallbackIsInvokedWhenPermissionGranted()
throws Exception {
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setApplicationEventPublisher(MockApplicationContext.getContext());
si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager());
@@ -100,6 +102,7 @@ public class AspectJSecurityInterceptorTests extends TestCase {
public void testCallbackIsNotInvokedWhenPermissionDenied()
throws Exception {
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
+ si.setMessageSource(new StaticMessageSource());
si.setApplicationEventPublisher(MockApplicationContext.getContext());
si.setAccessDecisionManager(new MockAccessDecisionManager());
si.setAuthenticationManager(new MockAuthenticationManager());
diff --git a/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java b/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java
index 69f3b6421f..a31a85c798 100644
--- a/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java
+++ b/core/src/test/java/org/acegisecurity/intercept/web/FilterSecurityInterceptorTests.java
@@ -34,6 +34,7 @@ import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.context.SecurityContextImpl;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+import org.springframework.context.support.StaticMessageSource;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@@ -77,6 +78,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
public void testEnsuresAccessDecisionManagerSupportsFilterInvocationClass()
throws Exception {
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
+ interceptor.setMessageSource(new StaticMessageSource());
interceptor.setAuthenticationManager(new MockAuthenticationManager());
interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
interceptor.setRunAsManager(new MockRunAsManager());
@@ -110,6 +112,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
public void testEnsuresRunAsManagerSupportsFilterInvocationClass()
throws Exception {
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
+ interceptor.setMessageSource(new StaticMessageSource());
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
interceptor.setAuthenticationManager(new MockAuthenticationManager());
interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
@@ -144,6 +147,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
throws Throwable {
// Setup the FilterSecurityInterceptor
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
+ interceptor.setMessageSource(new StaticMessageSource());
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
interceptor.setAuthenticationManager(new MockAuthenticationManager());
interceptor.setRunAsManager(new MockRunAsManager());
@@ -183,6 +187,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
public void testNormalStartupAndGetter() throws Exception {
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
+ interceptor.setMessageSource(new StaticMessageSource());
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
interceptor.setAuthenticationManager(new MockAuthenticationManager());
@@ -203,6 +208,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
public void testSuccessfulInvocation() throws Throwable {
// Setup the FilterSecurityInterceptor
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
+ interceptor.setMessageSource(new StaticMessageSource());
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
interceptor.setAuthenticationManager(new MockAuthenticationManager());
interceptor.setRunAsManager(new MockRunAsManager());
diff --git a/core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java b/core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java
index d1356cd264..c780a76aa4 100644
--- a/core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/ProviderManagerTests.java
@@ -29,6 +29,7 @@ import org.acegisecurity.concurrent.NullConcurrentSessionController;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.support.StaticMessageSource;
/**
@@ -182,8 +183,8 @@ public class ProviderManagerTests extends TestCase {
ProviderManager mgr = new ProviderManager();
mgr.setProviders(providers);
+ mgr.setMessageSource(new StaticMessageSource());
-
mgr.afterPropertiesSet();
return mgr;
}
diff --git a/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProviderTests.java
index 22e8257f48..c06777dd3f 100644
--- a/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProviderTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/anonymous/AnonymousAuthenticationProviderTests.java
@@ -22,6 +22,7 @@ import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
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 {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
+ aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty");
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("WRONG_KEY",
@@ -71,6 +73,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
public void testDetectsMissingKey() throws Exception {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
+ aap.setMessageSource(new StaticMessageSource());
try {
aap.afterPropertiesSet();
@@ -82,6 +85,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
public void testGettersSetters() throws Exception {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
+ aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty");
aap.afterPropertiesSet();
assertEquals("qwerty", aap.getKey());
@@ -89,6 +93,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
public void testIgnoresClassesItDoesNotSupport() throws Exception {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
+ aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty");
TestingAuthenticationToken token = new TestingAuthenticationToken("user",
@@ -102,6 +107,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
public void testNormalOperation() throws Exception {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
+ aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty");
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("qwerty",
@@ -116,6 +122,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
public void testSupports() {
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
+ aap.setMessageSource(new StaticMessageSource());
assertTrue(aap.supports(AnonymousAuthenticationToken.class));
assertFalse(aap.supports(TestingAuthenticationToken.class));
}
diff --git a/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationProviderTests.java
index 85ce5cdb60..cc0cac2930 100644
--- a/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationProviderTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/cas/CasAuthenticationProviderTests.java
@@ -28,6 +28,7 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.cas.ticketvalidator.AbstractTicketValidator;
import org.acegisecurity.providers.dao.User;
import org.acegisecurity.ui.cas.CasProcessingFilter;
+import org.springframework.context.support.StaticMessageSource;
import java.util.HashMap;
import java.util.List;
@@ -64,6 +65,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testAuthenticateStateful() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty");
@@ -108,6 +110,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testAuthenticateStateless() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty");
@@ -144,6 +147,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsAMissingTicketId() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty");
@@ -167,6 +171,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsAnInvalidKey() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty");
@@ -193,6 +198,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsMissingAuthoritiesPopulator()
throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty");
cap.setStatelessTicketCache(new MockStatelessTicketCache());
@@ -209,6 +215,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsMissingKey() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider());
cap.setStatelessTicketCache(new MockStatelessTicketCache());
@@ -225,6 +232,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsMissingProxyDecider() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setKey("qwerty");
cap.setStatelessTicketCache(new MockStatelessTicketCache());
@@ -241,6 +249,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsMissingStatelessTicketCache()
throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty");
@@ -257,6 +266,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testDetectsMissingTicketValidator() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider(true));
cap.setKey("qwerty");
@@ -272,6 +282,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testGettersSetters() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty");
@@ -288,6 +299,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testIgnoresClassesItDoesNotSupport() throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty");
@@ -307,6 +319,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testIgnoresUsernamePasswordAuthenticationTokensWithoutCasIdentifiersAsPrincipal()
throws Exception {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
cap.setCasProxyDecider(new MockProxyDecider());
cap.setKey("qwerty");
@@ -322,6 +335,7 @@ public class CasAuthenticationProviderTests extends TestCase {
public void testSupports() {
CasAuthenticationProvider cap = new CasAuthenticationProvider();
+ cap.setMessageSource(new StaticMessageSource());
assertTrue(cap.supports(UsernamePasswordAuthenticationToken.class));
assertTrue(cap.supports(CasAuthenticationToken.class));
}
diff --git a/core/src/test/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDeciderTests.java b/core/src/test/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDeciderTests.java
index 5680933a8b..8cf2eb41a2 100644
--- a/core/src/test/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDeciderTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/cas/proxy/NamedCasProxyDeciderTests.java
@@ -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");
* 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.springframework.context.support.StaticMessageSource;
+
import java.util.List;
import java.util.Vector;
/**
* Tests {@link NamedCasProxyDecider}.
- *
- * @author Ben Alex
- * @version $Id$
*/
public class NamedCasProxyDeciderTests extends TestCase {
//~ Constructors ===========================================================
@@ -42,17 +41,18 @@ public class NamedCasProxyDeciderTests extends TestCase {
//~ Methods ================================================================
- public final void setUp() throws Exception {
- super.setUp();
- }
-
public static void main(String[] args) {
junit.textui.TestRunner.run(NamedCasProxyDeciderTests.class);
}
+ public final void setUp() throws Exception {
+ super.setUp();
+ }
+
public void testAcceptsIfNearestProxyIsAuthorized()
throws Exception {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
+ proxyDecider.setMessageSource(new StaticMessageSource());
// Build the ticket returned from CAS
List proxyList = new Vector();
@@ -72,6 +72,8 @@ public class NamedCasProxyDeciderTests extends TestCase {
public void testAcceptsIfNoProxiesInTicket() {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
+ proxyDecider.setMessageSource(new StaticMessageSource());
+
List proxyList = new Vector(); // no proxies in list
proxyDecider.confirmProxyListTrusted(proxyList);
@@ -80,6 +82,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
public void testDetectsMissingValidProxiesList() throws Exception {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
+ proxyDecider.setMessageSource(new StaticMessageSource());
try {
proxyDecider.afterPropertiesSet();
@@ -92,6 +95,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
public void testDoesNotAcceptNull() {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
+ proxyDecider.setMessageSource(new StaticMessageSource());
try {
proxyDecider.confirmProxyListTrusted(null);
@@ -103,6 +107,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
public void testGettersSetters() {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
+ proxyDecider.setMessageSource(new StaticMessageSource());
// Build the list of valid nearest proxies
List validProxies = new Vector();
@@ -117,6 +122,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
public void testRejectsIfNearestProxyIsNotAuthorized()
throws Exception {
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
+ proxyDecider.setMessageSource(new StaticMessageSource());
// Build the ticket returned from CAS
List proxyList = new Vector();
diff --git a/core/src/test/java/org/acegisecurity/providers/cas/proxy/RejectProxyTicketsTests.java b/core/src/test/java/org/acegisecurity/providers/cas/proxy/RejectProxyTicketsTests.java
index e971943ae0..d477fff22c 100644
--- a/core/src/test/java/org/acegisecurity/providers/cas/proxy/RejectProxyTicketsTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/cas/proxy/RejectProxyTicketsTests.java
@@ -18,6 +18,7 @@ package org.acegisecurity.providers.cas.proxy;
import junit.framework.TestCase;
import org.acegisecurity.providers.cas.ProxyUntrustedException;
+import org.springframework.context.support.StaticMessageSource;
import java.util.List;
import java.util.Vector;
@@ -71,6 +72,7 @@ public class RejectProxyTicketsTests extends TestCase {
public void testRejectsIfAnyProxyInList() {
RejectProxyTickets proxyDecider = new RejectProxyTickets();
+ proxyDecider.setMessageSource(new StaticMessageSource());
List proxyList = new Vector();
proxyList.add("https://localhost/webApp/j_acegi_cas_security_check");
diff --git a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java
index d634b16dde..cd0edbc904 100644
--- a/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/dao/DaoAuthenticationProviderTests.java
@@ -34,6 +34,7 @@ import org.acegisecurity.providers.dao.cache.NullUserCache;
import org.acegisecurity.providers.dao.salt.SystemWideSaltSource;
import org.acegisecurity.providers.encoding.ShaPasswordEncoder;
+import org.springframework.context.support.StaticMessageSource;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataRetrievalFailureException;
@@ -63,6 +64,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"KOala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache());
@@ -79,6 +81,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"opal");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterAccountExpired());
provider.setUserCache(new MockUserCache());
@@ -95,6 +98,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"opal");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterAccountLocked());
provider.setUserCache(new MockUserCache());
@@ -111,6 +115,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"opal");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterCredentialsExpired());
provider.setUserCache(new MockUserCache());
@@ -138,6 +143,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"opal");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeter());
provider.setUserCache(new MockUserCache());
@@ -154,6 +160,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoSimulateBackendError());
provider.setUserCache(new MockUserCache());
@@ -170,6 +177,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache());
@@ -186,6 +194,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"INVALID_PASSWORD");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache());
@@ -202,6 +211,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setHideUserNotFoundExceptions(false); // we want UsernameNotFoundExceptions
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache());
@@ -219,6 +229,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
assertTrue(provider.isHideUserNotFoundExceptions());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache());
@@ -236,6 +247,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache());
@@ -253,6 +265,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
token.setDetails("192.168.0.1");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache());
@@ -276,6 +289,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache());
@@ -305,6 +319,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
salt.setSystemWideSalt("SYSTEM_SALT_VALUE");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissaWithSalt());
provider.setSaltSource(salt);
provider.setUserCache(new MockUserCache());
@@ -330,6 +345,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
provider.setUserCache(new MockUserCache());
provider.setForcePrincipalAsString(true);
@@ -351,6 +367,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
"koala");
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoReturnsNull());
try {
@@ -364,6 +381,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
public void testGettersSetters() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setPasswordEncoder(new ShaPasswordEncoder());
assertEquals(ShaPasswordEncoder.class,
provider.getPasswordEncoder().getClass());
@@ -388,6 +406,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
MockAuthenticationDaoUserMarissa authenticationDao = new MockAuthenticationDaoUserMarissa();
MockUserCache cache = new MockUserCache();
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(authenticationDao);
provider.setUserCache(cache);
@@ -414,6 +433,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
public void testStartupFailsIfNoAuthenticationDao()
throws Exception {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
try {
provider.afterPropertiesSet();
@@ -425,6 +445,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
public void testStartupFailsIfNoUserCacheSet() throws Exception {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
assertEquals(NullUserCache.class, provider.getUserCache().getClass());
provider.setUserCache(null);
@@ -439,6 +460,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
public void testStartupSuccess() throws Exception {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
AuthenticationDao dao = new MockAuthenticationDaoUserMarissa();
provider.setAuthenticationDao(dao);
provider.setUserCache(new MockUserCache());
@@ -449,6 +471,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
public void testSupports() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
assertTrue(provider.supports(UsernamePasswordAuthenticationToken.class));
assertTrue(!provider.supports(TestingAuthenticationToken.class));
}
diff --git a/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProviderTests.java
index 0d5acb6166..224391e60b 100644
--- a/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProviderTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/rememberme/RememberMeAuthenticationProviderTests.java
@@ -22,6 +22,7 @@ import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
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 {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
+ aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty");
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("WRONG_KEY",
@@ -71,6 +73,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
public void testDetectsMissingKey() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
+ aap.setMessageSource(new StaticMessageSource());
try {
aap.afterPropertiesSet();
@@ -82,6 +85,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
public void testGettersSetters() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
+ aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty");
aap.afterPropertiesSet();
assertEquals("qwerty", aap.getKey());
@@ -102,6 +106,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
public void testNormalOperation() throws Exception {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
+ aap.setMessageSource(new StaticMessageSource());
aap.setKey("qwerty");
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("qwerty",
@@ -116,6 +121,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
public void testSupports() {
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
+ aap.setMessageSource(new StaticMessageSource());
assertTrue(aap.supports(RememberMeAuthenticationToken.class));
assertFalse(aap.supports(TestingAuthenticationToken.class));
}
diff --git a/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationProviderTests.java
index 371ebba15e..e962e2e158 100644
--- a/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationProviderTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/x509/X509AuthenticationProviderTests.java
@@ -20,6 +20,7 @@ import junit.framework.TestCase;
import org.acegisecurity.*;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.providers.dao.User;
+import org.springframework.context.support.StaticMessageSource;
import java.security.cert.X509Certificate;
@@ -49,6 +50,7 @@ public class X509AuthenticationProviderTests extends TestCase {
public void testAuthenticationIsNullWithUnsupportedToken() {
X509AuthenticationProvider provider = new X509AuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
Authentication request = new UsernamePasswordAuthenticationToken("dummy",
"dummy");
Authentication result = provider.authenticate(request);
@@ -57,6 +59,7 @@ public class X509AuthenticationProviderTests extends TestCase {
public void testFailsWithNullCertificate() {
X509AuthenticationProvider provider = new X509AuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(false));
@@ -70,6 +73,7 @@ public class X509AuthenticationProviderTests extends TestCase {
public void testNormalOperation() throws Exception {
X509AuthenticationProvider provider = new X509AuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(false));
provider.afterPropertiesSet();
@@ -82,6 +86,7 @@ public class X509AuthenticationProviderTests extends TestCase {
public void testPopulatorRejectionCausesFailure() throws Exception {
X509AuthenticationProvider provider = new X509AuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(true));
try {
@@ -94,6 +99,7 @@ public class X509AuthenticationProviderTests extends TestCase {
public void testRequiresPopulator() throws Exception {
X509AuthenticationProvider provider = new X509AuthenticationProvider();
+ provider.setMessageSource(new StaticMessageSource());
try {
provider.afterPropertiesSet();
diff --git a/core/src/test/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulatorTests.java b/core/src/test/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulatorTests.java
index e43fa85ec6..a240a7113f 100644
--- a/core/src/test/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulatorTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/x509/populator/DaoX509AuthoritiesPopulatorTests.java
@@ -26,6 +26,7 @@ import org.acegisecurity.providers.dao.User;
import org.acegisecurity.providers.dao.UsernameNotFoundException;
import org.acegisecurity.providers.x509.X509TestUtils;
+import org.springframework.context.support.StaticMessageSource;
import org.springframework.dao.DataAccessException;
import java.security.cert.X509Certificate;
@@ -56,6 +57,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testDefaultCNPatternMatch() throws Exception {
X509Certificate cert = X509TestUtils.buildTestCertificate();
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
+ populator.setMessageSource(new StaticMessageSource());
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
populator.afterPropertiesSet();
@@ -65,6 +67,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testEmailPatternMatch() throws Exception {
X509Certificate cert = X509TestUtils.buildTestCertificate();
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
+ populator.setMessageSource(new StaticMessageSource());
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
populator.setSubjectDNRegex("emailAddress=(.*?),");
@@ -74,6 +77,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testInvalidRegexFails() throws Exception {
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
+ populator.setMessageSource(new StaticMessageSource());
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
populator.setSubjectDNRegex("CN=(.*?,"); // missing closing bracket on group
@@ -88,6 +92,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testMatchOnShoeSizeFieldInDNFails() throws Exception {
X509Certificate cert = X509TestUtils.buildTestCertificate();
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
+ populator.setMessageSource(new StaticMessageSource());
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
populator.setSubjectDNRegex("shoeSize=(.*?),");
@@ -104,6 +109,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testPatternWithNoGroupFails() throws Exception {
X509Certificate cert = X509TestUtils.buildTestCertificate();
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
+ populator.setMessageSource(new StaticMessageSource());
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
populator.setSubjectDNRegex("CN=.*?,");
@@ -120,6 +126,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
public void testRequiresDao() throws Exception {
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
+ populator.setMessageSource(new StaticMessageSource());
try {
populator.afterPropertiesSet();
diff --git a/core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java b/core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java
index 6ecd1106cf..6bc476eef9 100644
--- a/core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java
+++ b/core/src/test/java/org/acegisecurity/runas/RunAsImplAuthenticationProviderTests.java
@@ -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");
* 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.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
+
import org.acegisecurity.providers.TestingAuthenticationToken;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
+import org.springframework.context.support.StaticMessageSource;
+
/**
* Tests {@link RunAsImplAuthenticationProvider}.
- *
- * @author Ben Alex
- * @version $Id$
*/
public class RunAsImplAuthenticationProviderTests extends TestCase {
//~ Constructors ===========================================================
@@ -44,14 +44,14 @@ public class RunAsImplAuthenticationProviderTests extends TestCase {
//~ Methods ================================================================
- public final void setUp() throws Exception {
- super.setUp();
- }
-
public static void main(String[] args) {
junit.textui.TestRunner.run(RunAsImplAuthenticationProviderTests.class);
}
+ public final void setUp() throws Exception {
+ super.setUp();
+ }
+
public void testAuthenticationFailDueToWrongKey() {
RunAsUserToken token = new RunAsUserToken("WRONG_PASSWORD", "Test",
"Password",
@@ -59,6 +59,7 @@ public class RunAsImplAuthenticationProviderTests extends TestCase {
"ROLE_TWO")}, UsernamePasswordAuthenticationToken.class);
RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider();
provider.setKey("hello_world");
+ provider.setMessageSource(new StaticMessageSource());
try {
provider.authenticate(token);
diff --git a/core/src/test/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilterTests.java b/core/src/test/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilterTests.java
index d43e3f3a83..2bc7fadec0 100644
--- a/core/src/test/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilterTests.java
+++ b/core/src/test/java/org/acegisecurity/ui/switchuser/SwitchUserProcessingFilterTests.java
@@ -31,6 +31,7 @@ import org.acegisecurity.providers.dao.User;
import org.acegisecurity.providers.dao.UsernameNotFoundException;
import org.acegisecurity.util.MockFilterChain;
+import org.springframework.context.support.StaticMessageSource;
import org.springframework.dao.DataAccessException;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@@ -74,6 +75,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
"user-that-doesnt-exist");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
try {
@@ -97,6 +99,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
"mcgarrett");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
try {
@@ -122,6 +125,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
"wofat");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
try {
@@ -147,6 +151,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
"steve");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
try {
@@ -169,6 +174,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
"jacklord");
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
Authentication result = filter.attemptSwitchUser(request);
@@ -177,6 +183,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
public void testBadConfigMissingAuthenticationDao() {
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setSwitchUserUrl("/j_acegi_switch_user");
filter.setExitUserUrl("/j_acegi_exit_user");
filter.setTargetUrl("/main.jsp");
@@ -191,6 +198,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
public void testBadConfigMissingTargetUrl() {
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
filter.setSwitchUserUrl("/j_acegi_switch_user");
filter.setExitUserUrl("/j_acegi_exit_user");
@@ -206,6 +214,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
public void testDefaultProcessesFilterUrlWithPathParameter() {
MockHttpServletRequest request = createMockSwitchRequest();
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setSwitchUserUrl("/j_acegi_switch_user");
request.setRequestURI(
@@ -238,6 +247,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
// setup filter
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
filter.setExitUserUrl("/j_acegi_exit_user");
@@ -266,6 +276,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
// setup filter
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
filter.setExitUserUrl("/j_acegi_exit_user");
@@ -294,6 +305,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
MockFilterChain chain = new MockFilterChain(true);
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setSwitchUserUrl("/j_acegi_switch_user");
filter.setTargetUrl("/webapp/someOtherUrl");
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
@@ -343,6 +355,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
// setup filter
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
+ filter.setMessageSource(new StaticMessageSource());
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
filter.setSwitchUserUrl("/j_acegi_switch_user");
diff --git a/core/src/test/java/org/acegisecurity/vote/AffirmativeBasedTests.java b/core/src/test/java/org/acegisecurity/vote/AffirmativeBasedTests.java
index a4f2e64803..f40d48f8dd 100644
--- a/core/src/test/java/org/acegisecurity/vote/AffirmativeBasedTests.java
+++ b/core/src/test/java/org/acegisecurity/vote/AffirmativeBasedTests.java
@@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.SecurityConfig;
import org.acegisecurity.providers.TestingAuthenticationToken;
+import org.springframework.context.support.StaticMessageSource;
import java.util.List;
import java.util.Vector;
@@ -143,6 +144,7 @@ public class AffirmativeBasedTests extends TestCase {
private AffirmativeBased makeDecisionManager() {
AffirmativeBased decisionManager = new AffirmativeBased();
+ decisionManager.setMessageSource(new StaticMessageSource());
RoleVoter roleVoter = new RoleVoter();
DenyVoter denyForSureVoter = new DenyVoter();
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
diff --git a/core/src/test/java/org/acegisecurity/vote/ConsensusBasedTests.java b/core/src/test/java/org/acegisecurity/vote/ConsensusBasedTests.java
index 57bdaf4f8a..4e47159713 100644
--- a/core/src/test/java/org/acegisecurity/vote/ConsensusBasedTests.java
+++ b/core/src/test/java/org/acegisecurity/vote/ConsensusBasedTests.java
@@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.SecurityConfig;
import org.acegisecurity.providers.TestingAuthenticationToken;
+import org.springframework.context.support.StaticMessageSource;
import java.util.List;
import java.util.Vector;
@@ -164,6 +165,7 @@ public class ConsensusBasedTests extends TestCase {
private ConsensusBased makeDecisionManager() {
ConsensusBased decisionManager = new ConsensusBased();
+ decisionManager.setMessageSource(new StaticMessageSource());
RoleVoter roleVoter = new RoleVoter();
DenyVoter denyForSureVoter = new DenyVoter();
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
diff --git a/core/src/test/java/org/acegisecurity/vote/UnanimousBasedTests.java b/core/src/test/java/org/acegisecurity/vote/UnanimousBasedTests.java
index a1c986bde5..5274533048 100644
--- a/core/src/test/java/org/acegisecurity/vote/UnanimousBasedTests.java
+++ b/core/src/test/java/org/acegisecurity/vote/UnanimousBasedTests.java
@@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.SecurityConfig;
import org.acegisecurity.providers.TestingAuthenticationToken;
+import org.springframework.context.support.StaticMessageSource;
import java.util.List;
import java.util.Vector;
@@ -59,6 +60,7 @@ public class UnanimousBasedTests extends TestCase {
throws Exception {
TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager();
+ mgr.setMessageSource(new StaticMessageSource());
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
@@ -76,6 +78,7 @@ public class UnanimousBasedTests extends TestCase {
throws Exception {
TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager();
+ mgr.setMessageSource(new StaticMessageSource());
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
@@ -88,6 +91,7 @@ public class UnanimousBasedTests extends TestCase {
throws Exception {
TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager();
+ mgr.setMessageSource(new StaticMessageSource());
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_WE_DO_NOT_HAVE")); // deny
@@ -103,6 +107,7 @@ public class UnanimousBasedTests extends TestCase {
public void testRoleVoterPrefixObserved() throws Exception {
TestingAuthenticationToken auth = makeTestTokenWithFooBarPrefix();
UnanimousBased mgr = makeDecisionManagerWithFooBarPrefix();
+ mgr.setMessageSource(new StaticMessageSource());
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("FOOBAR_1")); // grant
@@ -116,6 +121,7 @@ public class UnanimousBasedTests extends TestCase {
throws Exception {
TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager();
+ mgr.setMessageSource(new StaticMessageSource());
assertTrue(!mgr.isAllowIfAllAbstainDecisions()); // check default
@@ -135,6 +141,7 @@ public class UnanimousBasedTests extends TestCase {
TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager();
mgr.setAllowIfAllAbstainDecisions(true);
+ mgr.setMessageSource(new StaticMessageSource());
assertTrue(mgr.isAllowIfAllAbstainDecisions()); // check changed
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
@@ -148,6 +155,7 @@ public class UnanimousBasedTests extends TestCase {
throws Exception {
TestingAuthenticationToken auth = makeTestToken();
UnanimousBased mgr = makeDecisionManager();
+ mgr.setMessageSource(new StaticMessageSource());
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
@@ -159,6 +167,7 @@ public class UnanimousBasedTests extends TestCase {
private UnanimousBased makeDecisionManager() {
UnanimousBased decisionManager = new UnanimousBased();
+ decisionManager.setMessageSource(new StaticMessageSource());
RoleVoter roleVoter = new RoleVoter();
DenyVoter denyForSureVoter = new DenyVoter();
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
@@ -173,6 +182,7 @@ public class UnanimousBasedTests extends TestCase {
private UnanimousBased makeDecisionManagerWithFooBarPrefix() {
UnanimousBased decisionManager = new UnanimousBased();
+ decisionManager.setMessageSource(new StaticMessageSource());
RoleVoter roleVoter = new RoleVoter();
roleVoter.setRolePrefix("FOOBAR_");