mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-24 13:02:13 +00:00
SEC-56: Add localisation support.
This commit is contained in:
parent
f4c3e2ff8c
commit
fddcd6112e
@ -29,6 +29,8 @@ import org.springframework.jdbc.core.SqlParameter;
|
|||||||
import org.springframework.jdbc.core.support.JdbcDaoSupport;
|
import org.springframework.jdbc.core.support.JdbcDaoSupport;
|
||||||
import org.springframework.jdbc.object.MappingSqlQuery;
|
import org.springframework.jdbc.object.MappingSqlQuery;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
@ -51,9 +53,6 @@ import javax.sql.DataSource;
|
|||||||
* the {@link MappingSqlQuery} instance used, via the {@link
|
* the {@link MappingSqlQuery} instance used, via the {@link
|
||||||
* #initMappingSqlQueries()} extension point.
|
* #initMappingSqlQueries()} extension point.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
@ -79,113 +78,6 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
|||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the ACLs associated with the requested
|
|
||||||
* <code>AclObjectIdentity</code>.
|
|
||||||
*
|
|
||||||
* <P>
|
|
||||||
* The {@link BasicAclEntry}s returned by this method will have
|
|
||||||
* <code>String</code>-based recipients. This will not be a problem if you
|
|
||||||
* are using the <code>GrantedAuthorityEffectiveAclsResolver</code>, which
|
|
||||||
* is the default configured against <code>BasicAclProvider</code>.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <P>
|
|
||||||
* This method will only return ACLs for requests where the
|
|
||||||
* <code>AclObjectIdentity</code> is of type {@link
|
|
||||||
* NamedEntityObjectIdentity}. Of course, you can subclass or replace this
|
|
||||||
* class and support your own custom <code>AclObjectIdentity</code> types.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param aclObjectIdentity for which ACL information is required (cannot
|
|
||||||
* be <code>null</code> and must be an instance of
|
|
||||||
* <code>NamedEntityObjectIdentity</code>)
|
|
||||||
*
|
|
||||||
* @return the ACLs that apply (without any <code>null</code>s inside the
|
|
||||||
* array), or <code>null</code> if not found or if an incompatible
|
|
||||||
* <code>AclObjectIdentity</code> was requested
|
|
||||||
*/
|
|
||||||
public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) {
|
|
||||||
String aclObjectIdentityString;
|
|
||||||
|
|
||||||
try {
|
|
||||||
aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
|
|
||||||
} catch (IllegalArgumentException unsupported) {
|
|
||||||
return null; // pursuant to contract described in JavaDocs above
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lookup the object's main properties from the RDBMS (guaranteed no nulls)
|
|
||||||
List objects = objectProperties.execute(aclObjectIdentityString);
|
|
||||||
|
|
||||||
if (objects.size() == 0) {
|
|
||||||
// this is an unknown object identity string
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cast to an object properties holder (there should only be one record)
|
|
||||||
AclDetailsHolder propertiesInformation = (AclDetailsHolder) objects.get(0);
|
|
||||||
|
|
||||||
// Lookup the object's ACLs from RDBMS (guaranteed no nulls)
|
|
||||||
List acls = aclsByObjectIdentity.execute(propertiesInformation
|
|
||||||
.getForeignKeyId());
|
|
||||||
|
|
||||||
if (acls.size() == 0) {
|
|
||||||
// return merely an inheritence marker (as we know about the object but it has no related ACLs)
|
|
||||||
return new BasicAclEntry[] {createBasicAclEntry(propertiesInformation,
|
|
||||||
null)};
|
|
||||||
} else {
|
|
||||||
// return the individual ACL instances
|
|
||||||
AclDetailsHolder[] aclHolders = (AclDetailsHolder[]) acls.toArray(new AclDetailsHolder[] {});
|
|
||||||
List toReturnAcls = new Vector();
|
|
||||||
|
|
||||||
for (int i = 0; i < aclHolders.length; i++) {
|
|
||||||
toReturnAcls.add(createBasicAclEntry(propertiesInformation,
|
|
||||||
aclHolders[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (BasicAclEntry[]) toReturnAcls.toArray(new BasicAclEntry[] {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAclsByObjectIdentity(
|
|
||||||
MappingSqlQuery aclsByObjectIdentityQuery) {
|
|
||||||
this.aclsByObjectIdentity = aclsByObjectIdentityQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MappingSqlQuery getAclsByObjectIdentity() {
|
|
||||||
return aclsByObjectIdentity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows the default query string used to retrieve ACLs based on object
|
|
||||||
* identity to be overriden, if default table or column names need to be
|
|
||||||
* changed. The default query is {@link
|
|
||||||
* #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying this query, ensure
|
|
||||||
* that all returned columns are mapped back to the same column names as
|
|
||||||
* in the default query.
|
|
||||||
*
|
|
||||||
* @param queryString The query string to set
|
|
||||||
*/
|
|
||||||
public void setAclsByObjectIdentityQuery(String queryString) {
|
|
||||||
aclsByObjectIdentityQuery = queryString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAclsByObjectIdentityQuery() {
|
|
||||||
return aclsByObjectIdentityQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObjectProperties(MappingSqlQuery objectPropertiesQuery) {
|
|
||||||
this.objectProperties = objectPropertiesQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObjectPropertiesQuery(String queryString) {
|
|
||||||
objectPropertiesQuery = queryString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getObjectPropertiesQuery() {
|
|
||||||
return objectPropertiesQuery;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for covering a <code>AclObjectIdentity</code> to a
|
* Responsible for covering a <code>AclObjectIdentity</code> to a
|
||||||
* <code>String</code> that can be located in the RDBMS.
|
* <code>String</code> that can be located in the RDBMS.
|
||||||
@ -193,17 +85,13 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
|||||||
* @param aclObjectIdentity to locate
|
* @param aclObjectIdentity to locate
|
||||||
*
|
*
|
||||||
* @return the object identity as a <code>String</code>
|
* @return the object identity as a <code>String</code>
|
||||||
*
|
|
||||||
* @throws IllegalArgumentException DOCUMENT ME!
|
|
||||||
*/
|
*/
|
||||||
protected String convertAclObjectIdentityToString(
|
protected String convertAclObjectIdentityToString(
|
||||||
AclObjectIdentity aclObjectIdentity) {
|
AclObjectIdentity aclObjectIdentity) {
|
||||||
// Ensure we can process this type of AclObjectIdentity
|
// Ensure we can process this type of AclObjectIdentity
|
||||||
if (!(aclObjectIdentity instanceof NamedEntityObjectIdentity)) {
|
Assert.isInstanceOf(NamedEntityObjectIdentity.class, aclObjectIdentity,
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: "
|
"Only aclObjectIdentity of type NamedEntityObjectIdentity supported (was passed: "
|
||||||
+ aclObjectIdentity + ")");
|
+ aclObjectIdentity + ")");
|
||||||
}
|
|
||||||
|
|
||||||
NamedEntityObjectIdentity neoi = (NamedEntityObjectIdentity) aclObjectIdentity;
|
NamedEntityObjectIdentity neoi = (NamedEntityObjectIdentity) aclObjectIdentity;
|
||||||
|
|
||||||
@ -211,19 +99,6 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
|||||||
return neoi.getClassname() + ":" + neoi.getId();
|
return neoi.getClassname() + ":" + neoi.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initDao() throws ApplicationContextException {
|
|
||||||
initMappingSqlQueries();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extension point to allow other MappingSqlQuery objects to be substituted
|
|
||||||
* in a subclass
|
|
||||||
*/
|
|
||||||
protected void initMappingSqlQueries() {
|
|
||||||
setAclsByObjectIdentity(new AclsByObjectIdentityMapping(getDataSource()));
|
|
||||||
setObjectProperties(new ObjectPropertiesMapping(getDataSource()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an individual <code>BasicAclEntry</code> from the passed
|
* Constructs an individual <code>BasicAclEntry</code> from the passed
|
||||||
* <code>AclDetailsHolder</code>s.
|
* <code>AclDetailsHolder</code>s.
|
||||||
@ -278,21 +153,150 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
|||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~ Inner Classes ==========================================================
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to hold details of a domain object instance's properties, or an
|
* Returns the ACLs associated with the requested
|
||||||
* individual ACL entry.
|
* <code>AclObjectIdentity</code>.
|
||||||
*
|
*
|
||||||
* <P>
|
* <P>
|
||||||
* Not all properties will be set. The actual properties set will depend on
|
* The {@link BasicAclEntry}s returned by this method will have
|
||||||
* which <code>MappingSqlQuery</code> creates the object.
|
* <code>String</code>-based recipients. This will not be a problem if
|
||||||
|
* you are using the
|
||||||
|
* <code>GrantedAuthorityEffectiveAclsResolver</code>, which is the
|
||||||
|
* default configured against <code>BasicAclProvider</code>.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <P>
|
* <P>
|
||||||
* Does not enforce <code>null</code>s or empty <code>String</code>s as
|
* This method will only return ACLs for requests where the
|
||||||
* this is performed by the <code>MappingSqlQuery</code> objects (or
|
* <code>AclObjectIdentity</code> is of type {@link
|
||||||
* preferably the backend RDBMS via schema constraints).
|
* NamedEntityObjectIdentity}. Of course, you can subclass or replace
|
||||||
|
* this class and support your own custom
|
||||||
|
* <code>AclObjectIdentity</code> types.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param aclObjectIdentity for which ACL information is required
|
||||||
|
* (cannot be <code>null</code> and must be an instance of
|
||||||
|
* <code>NamedEntityObjectIdentity</code>)
|
||||||
|
*
|
||||||
|
* @return the ACLs that apply (without any <code>null</code>s inside
|
||||||
|
* the array), or <code>null</code> if not found or if an
|
||||||
|
* incompatible <code>AclObjectIdentity</code> was requested
|
||||||
|
*/
|
||||||
|
public BasicAclEntry[] getAcls(AclObjectIdentity aclObjectIdentity) {
|
||||||
|
String aclObjectIdentityString;
|
||||||
|
|
||||||
|
try {
|
||||||
|
aclObjectIdentityString = convertAclObjectIdentityToString(aclObjectIdentity);
|
||||||
|
} catch (IllegalArgumentException unsupported) {
|
||||||
|
return null; // pursuant to contract described in JavaDocs above
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup the object's main properties from the RDBMS (guaranteed no nulls)
|
||||||
|
List objects = objectProperties.execute(aclObjectIdentityString);
|
||||||
|
|
||||||
|
if (objects.size() == 0) {
|
||||||
|
// this is an unknown object identity string
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cast to an object properties holder (there should only be one record)
|
||||||
|
AclDetailsHolder propertiesInformation = (AclDetailsHolder) objects
|
||||||
|
.get(0);
|
||||||
|
|
||||||
|
// Lookup the object's ACLs from RDBMS (guaranteed no nulls)
|
||||||
|
List acls = aclsByObjectIdentity.execute(propertiesInformation
|
||||||
|
.getForeignKeyId());
|
||||||
|
|
||||||
|
if (acls.size() == 0) {
|
||||||
|
// return merely an inheritence marker (as we know about the object but it has no related ACLs)
|
||||||
|
return new BasicAclEntry[] {createBasicAclEntry(propertiesInformation,
|
||||||
|
null)};
|
||||||
|
} else {
|
||||||
|
// return the individual ACL instances
|
||||||
|
AclDetailsHolder[] aclHolders = (AclDetailsHolder[]) acls
|
||||||
|
.toArray(new AclDetailsHolder[] {});
|
||||||
|
List toReturnAcls = new Vector();
|
||||||
|
|
||||||
|
for (int i = 0; i < aclHolders.length; i++) {
|
||||||
|
toReturnAcls.add(createBasicAclEntry(
|
||||||
|
propertiesInformation, aclHolders[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (BasicAclEntry[]) toReturnAcls.toArray(new BasicAclEntry[] {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MappingSqlQuery getAclsByObjectIdentity() {
|
||||||
|
return aclsByObjectIdentity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAclsByObjectIdentityQuery() {
|
||||||
|
return aclsByObjectIdentityQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getObjectPropertiesQuery() {
|
||||||
|
return objectPropertiesQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initDao() throws ApplicationContextException {
|
||||||
|
initMappingSqlQueries();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension point to allow other MappingSqlQuery objects to be
|
||||||
|
* substituted in a subclass
|
||||||
|
*/
|
||||||
|
protected void initMappingSqlQueries() {
|
||||||
|
setAclsByObjectIdentity(new AclsByObjectIdentityMapping(
|
||||||
|
getDataSource()));
|
||||||
|
setObjectProperties(new ObjectPropertiesMapping(
|
||||||
|
getDataSource()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAclsByObjectIdentity(
|
||||||
|
MappingSqlQuery aclsByObjectIdentityQuery) {
|
||||||
|
this.aclsByObjectIdentity = aclsByObjectIdentityQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the default query string used to retrieve ACLs based
|
||||||
|
* on object identity to be overriden, if default table or
|
||||||
|
* column names need to be changed. The default query is
|
||||||
|
* {@link #DEF_ACLS_BY_OBJECT_IDENTITY_QUERY}; when modifying
|
||||||
|
* this query, ensure that all returned columns are mapped
|
||||||
|
* back to the same column names as in the default query.
|
||||||
|
*
|
||||||
|
* @param queryString The query string to set
|
||||||
|
*/
|
||||||
|
public void setAclsByObjectIdentityQuery(String queryString) {
|
||||||
|
aclsByObjectIdentityQuery = queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setObjectProperties(
|
||||||
|
MappingSqlQuery objectPropertiesQuery) {
|
||||||
|
this.objectProperties = objectPropertiesQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setObjectPropertiesQuery(String queryString) {
|
||||||
|
objectPropertiesQuery = queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~ Inner Classes ==========================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to hold details of a domain object instance's
|
||||||
|
* properties, or an individual ACL entry.
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* Not all properties will be set. The actual properties set
|
||||||
|
* will depend on which <code>MappingSqlQuery</code> creates
|
||||||
|
* the object.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* Does not enforce <code>null</code>s or empty
|
||||||
|
* <code>String</code>s as this is performed by the
|
||||||
|
* <code>MappingSqlQuery</code> objects (or preferably the
|
||||||
|
* backend RDBMS via schema constraints).
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
protected final class AclDetailsHolder {
|
protected final class AclDetailsHolder {
|
||||||
@ -304,8 +308,8 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
|||||||
private long foreignKeyId;
|
private long foreignKeyId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record details of an individual ACL entry (usually from the
|
* Record details of an individual ACL entry (usually from
|
||||||
* ACL_PERMISSION table)
|
* the ACL_PERMISSION table)
|
||||||
*
|
*
|
||||||
* @param recipient the recipient
|
* @param recipient the recipient
|
||||||
* @param mask the integer to be masked
|
* @param mask the integer to be masked
|
||||||
@ -316,23 +320,25 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record details of a domain object instance's properties (usually
|
* Record details of a domain object instance's properties
|
||||||
* from the ACL_OBJECT_IDENTITY table)
|
* (usually from the ACL_OBJECT_IDENTITY table)
|
||||||
*
|
*
|
||||||
* @param foreignKeyId used by the
|
* @param foreignKeyId used by the
|
||||||
* <code>AclsByObjectIdentityMapping</code> to locate the
|
* <code>AclsByObjectIdentityMapping</code> to
|
||||||
* individual ACL entries
|
* locate the individual ACL entries
|
||||||
* @param aclObjectIdentity the object identity of the domain object
|
* @param aclObjectIdentity the object identity of the
|
||||||
* instance
|
* domain object instance
|
||||||
* @param aclObjectParentIdentity the object identity of the domain
|
* @param aclObjectParentIdentity the object identity of
|
||||||
* object instance's parent
|
* the domain object instance's parent
|
||||||
* @param aclClass the class of which a new instance which should be
|
* @param aclClass the class of which a new instance which
|
||||||
* created for each individual ACL entry (or an inheritence
|
* should be created for each individual ACL entry
|
||||||
* "holder" class if there are no ACL entries)
|
* (or an inheritence "holder" class if there are
|
||||||
|
* no ACL entries)
|
||||||
*/
|
*/
|
||||||
public AclDetailsHolder(long foreignKeyId,
|
public AclDetailsHolder(long foreignKeyId,
|
||||||
AclObjectIdentity aclObjectIdentity,
|
AclObjectIdentity aclObjectIdentity,
|
||||||
AclObjectIdentity aclObjectParentIdentity, Class aclClass) {
|
AclObjectIdentity aclObjectParentIdentity,
|
||||||
|
Class aclClass) {
|
||||||
this.foreignKeyId = foreignKeyId;
|
this.foreignKeyId = foreignKeyId;
|
||||||
this.aclObjectIdentity = aclObjectIdentity;
|
this.aclObjectIdentity = aclObjectIdentity;
|
||||||
this.aclObjectParentIdentity = aclObjectParentIdentity;
|
this.aclObjectParentIdentity = aclObjectParentIdentity;
|
||||||
@ -372,16 +378,18 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <P>
|
* <P>
|
||||||
* Guarantees to never return <code>null</code> (exceptions are thrown in
|
* Guarantees to never return <code>null</code> (exceptions are
|
||||||
* the event of any issues).
|
* thrown in the event of any issues).
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <P>
|
* <P>
|
||||||
* The executed SQL requires the following information be made available
|
* The executed SQL requires the following information be made
|
||||||
* from the indicated placeholders: 1. RECIPIENT, 2. MASK.
|
* available from the indicated placeholders: 1. RECIPIENT, 2.
|
||||||
|
* MASK.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
protected class AclsByObjectIdentityMapping extends MappingSqlQuery {
|
protected class AclsByObjectIdentityMapping
|
||||||
|
extends MappingSqlQuery {
|
||||||
protected AclsByObjectIdentityMapping(DataSource ds) {
|
protected AclsByObjectIdentityMapping(DataSource ds) {
|
||||||
super(ds, aclsByObjectIdentityQuery);
|
super(ds, aclsByObjectIdentityQuery);
|
||||||
declareParameter(new SqlParameter(Types.BIGINT));
|
declareParameter(new SqlParameter(Types.BIGINT));
|
||||||
@ -392,10 +400,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
|||||||
throws SQLException {
|
throws SQLException {
|
||||||
String recipient = rs.getString(1);
|
String recipient = rs.getString(1);
|
||||||
int mask = rs.getInt(2);
|
int mask = rs.getInt(2);
|
||||||
|
Assert.hasText(recipient, "recipient required");
|
||||||
if ((recipient == null) || "".equals(recipient)) {
|
|
||||||
throw new IllegalArgumentException("recipient required");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new AclDetailsHolder(recipient, mask);
|
return new AclDetailsHolder(recipient, mask);
|
||||||
}
|
}
|
||||||
@ -409,14 +414,15 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <P>
|
* <P>
|
||||||
* Guarantees to never return <code>null</code> (exceptions are thrown in
|
* Guarantees to never return <code>null</code> (exceptions are
|
||||||
* the event of any issues).
|
* thrown in the event of any issues).
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <P>
|
* <P>
|
||||||
* The executed SQL requires the following information be made available
|
* The executed SQL requires the following information be made
|
||||||
* from the indicated placeholders: 1. ID, 2. OBJECT_IDENTITY, 3.
|
* available from the indicated placeholders: 1. ID, 2.
|
||||||
* ACL_CLASS and 4. PARENT_OBJECT_IDENTITY.
|
* OBJECT_IDENTITY, 3. ACL_CLASS and 4.
|
||||||
|
* PARENT_OBJECT_IDENTITY.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
protected class ObjectPropertiesMapping extends MappingSqlQuery {
|
protected class ObjectPropertiesMapping extends MappingSqlQuery {
|
||||||
@ -426,32 +432,6 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
|||||||
compile();
|
compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Object mapRow(ResultSet rs, int rownum)
|
|
||||||
throws SQLException {
|
|
||||||
long id = rs.getLong(1); // required
|
|
||||||
String objectIdentity = rs.getString(2); // required
|
|
||||||
String aclClass = rs.getString(3); // required
|
|
||||||
String parentObjectIdentity = rs.getString(4); // optional
|
|
||||||
|
|
||||||
if ((objectIdentity == null) || "".equals(objectIdentity)
|
|
||||||
|| (aclClass == null) || "".equals(aclClass)) {
|
|
||||||
// shouldn't happen if DB schema defined NOT NULL columns
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"required DEF_OBJECT_PROPERTIES_QUERY value returned null or empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
Class aclClazz;
|
|
||||||
|
|
||||||
try {
|
|
||||||
aclClazz = this.getClass().getClassLoader().loadClass(aclClass);
|
|
||||||
} catch (ClassNotFoundException cnf) {
|
|
||||||
throw new IllegalArgumentException(cnf.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return new AclDetailsHolder(id, buildIdentity(objectIdentity),
|
|
||||||
buildIdentity(parentObjectIdentity), aclClazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AclObjectIdentity buildIdentity(String identity) {
|
private AclObjectIdentity buildIdentity(String identity) {
|
||||||
if (identity == null) {
|
if (identity == null) {
|
||||||
// Must be an empty parent, so return null
|
// Must be an empty parent, so return null
|
||||||
@ -464,5 +444,30 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements BasicAclDao {
|
|||||||
|
|
||||||
return new NamedEntityObjectIdentity(classname, id);
|
return new NamedEntityObjectIdentity(classname, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Object mapRow(ResultSet rs, int rownum)
|
||||||
|
throws SQLException {
|
||||||
|
long id = rs.getLong(1); // required
|
||||||
|
String objectIdentity = rs.getString(2); // required
|
||||||
|
String aclClass = rs.getString(3); // required
|
||||||
|
String parentObjectIdentity = rs.getString(4); // optional
|
||||||
|
Assert.hasText(objectIdentity,
|
||||||
|
"required DEF_OBJECT_PROPERTIES_QUERY value (objectIdentity) returned null or empty");
|
||||||
|
Assert.hasText(aclClass,
|
||||||
|
"required DEF_OBJECT_PROPERTIES_QUERY value (aclClass) returned null or empty");
|
||||||
|
|
||||||
|
Class aclClazz;
|
||||||
|
|
||||||
|
try {
|
||||||
|
aclClazz = this.getClass().getClassLoader()
|
||||||
|
.loadClass(aclClass);
|
||||||
|
} catch (ClassNotFoundException cnf) {
|
||||||
|
throw new IllegalArgumentException(cnf.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AclDetailsHolder(id,
|
||||||
|
buildIdentity(objectIdentity),
|
||||||
|
buildIdentity(parentObjectIdentity), aclClazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -18,9 +18,15 @@ package org.acegisecurity.adapters;
|
|||||||
import org.acegisecurity.Authentication;
|
import org.acegisecurity.Authentication;
|
||||||
import org.acegisecurity.AuthenticationException;
|
import org.acegisecurity.AuthenticationException;
|
||||||
import org.acegisecurity.BadCredentialsException;
|
import org.acegisecurity.BadCredentialsException;
|
||||||
|
|
||||||
import org.acegisecurity.providers.AuthenticationProvider;
|
import org.acegisecurity.providers.AuthenticationProvider;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
|
||||||
@ -38,28 +44,20 @@ import org.springframework.util.Assert;
|
|||||||
* <P>
|
* <P>
|
||||||
* If the key does not match, a <code>BadCredentialsException</code> is thrown.
|
* If the key does not match, a <code>BadCredentialsException</code> is thrown.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class AuthByAdapterProvider implements InitializingBean,
|
public class AuthByAdapterProvider implements InitializingBean,
|
||||||
AuthenticationProvider {
|
AuthenticationProvider, MessageSourceAware {
|
||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private String key;
|
private String key;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setKey(String key) {
|
|
||||||
this.key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(key, "A Key is required and should match that configured for the adapters");
|
Assert.notNull(key,
|
||||||
|
"A Key is required and should match that configured for the adapters");
|
||||||
|
Assert.notNull(messages, "A message source must be set");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Authentication authenticate(Authentication authentication)
|
public Authentication authenticate(Authentication authentication)
|
||||||
@ -69,11 +67,24 @@ public class AuthByAdapterProvider implements InitializingBean,
|
|||||||
if (token.getKeyHash() == key.hashCode()) {
|
if (token.getKeyHash() == key.hashCode()) {
|
||||||
return authentication;
|
return authentication;
|
||||||
} else {
|
} else {
|
||||||
throw new BadCredentialsException(
|
throw new BadCredentialsException(messages.getMessage(
|
||||||
"The presented AuthByAdapter implementation does not contain the expected key");
|
"AuthByAdapterProvider.incorrectKey",
|
||||||
|
"The presented AuthByAdapter implementation does not contain the expected key"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean supports(Class authentication) {
|
public boolean supports(Class authentication) {
|
||||||
if (AuthByAdapter.class.isAssignableFrom(authentication)) {
|
if (AuthByAdapter.class.isAssignableFrom(authentication)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -19,6 +19,7 @@ import org.acegisecurity.AccessDeniedException;
|
|||||||
import org.acegisecurity.Authentication;
|
import org.acegisecurity.Authentication;
|
||||||
import org.acegisecurity.ConfigAttribute;
|
import org.acegisecurity.ConfigAttribute;
|
||||||
import org.acegisecurity.ConfigAttributeDefinition;
|
import org.acegisecurity.ConfigAttributeDefinition;
|
||||||
|
|
||||||
import org.acegisecurity.acl.AclEntry;
|
import org.acegisecurity.acl.AclEntry;
|
||||||
import org.acegisecurity.acl.AclManager;
|
import org.acegisecurity.acl.AclManager;
|
||||||
import org.acegisecurity.acl.basic.BasicAclEntry;
|
import org.acegisecurity.acl.basic.BasicAclEntry;
|
||||||
@ -28,6 +29,11 @@ import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -45,9 +51,8 @@ import java.util.Iterator;
|
|||||||
* (ACL) permissions associated with a domain object instance for the current
|
* (ACL) permissions associated with a domain object instance for the current
|
||||||
* <code>Authentication</code> object. This class is designed to process
|
* <code>Authentication</code> object. This class is designed to process
|
||||||
* {@link AclEntry}s that are subclasses of {@link
|
* {@link AclEntry}s that are subclasses of {@link
|
||||||
* org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these
|
* org.acegisecurity.acl.basic.BasicAclEntry} only. Generally these are
|
||||||
* are obtained by using the {@link
|
* obtained by using the {@link org.acegisecurity.acl.basic.BasicAclProvider}.
|
||||||
* org.acegisecurity.acl.basic.BasicAclProvider}.
|
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
@ -55,8 +60,8 @@ import java.util.Iterator;
|
|||||||
* ConfigAttribute#getAttribute()} matches the {@link
|
* ConfigAttribute#getAttribute()} matches the {@link
|
||||||
* #processConfigAttribute}. The provider will then lookup the ACLs from the
|
* #processConfigAttribute}. The provider will then lookup the ACLs from the
|
||||||
* <code>AclManager</code> and ensure the principal is {@link
|
* <code>AclManager</code> and ensure the principal is {@link
|
||||||
* org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for
|
* org.acegisecurity.acl.basic.BasicAclEntry#isPermitted(int)} for at least
|
||||||
* at least one of the {@link #requirePermission}s.
|
* one of the {@link #requirePermission}s.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
@ -74,9 +79,8 @@ import java.util.Iterator;
|
|||||||
* <p>
|
* <p>
|
||||||
* The <code>AclManager</code> is allowed to return any implementations of
|
* The <code>AclManager</code> is allowed to return any implementations of
|
||||||
* <code>AclEntry</code> it wishes. However, this provider will only be able
|
* <code>AclEntry</code> it wishes. However, this provider will only be able
|
||||||
* to validate against <code>BasicAclEntry</code>s, and thus access
|
* to validate against <code>BasicAclEntry</code>s, and thus access will be
|
||||||
* will be denied if no <code>AclEntry</code> is of type
|
* denied if no <code>AclEntry</code> is of type <code>BasicAclEntry</code>.
|
||||||
* <code>BasicAclEntry</code>.
|
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
@ -87,12 +91,9 @@ import java.util.Iterator;
|
|||||||
* <p>
|
* <p>
|
||||||
* All comparisons and prefixes are case sensitive.
|
* All comparisons and prefixes are case sensitive.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class BasicAclEntryAfterInvocationProvider
|
public class BasicAclEntryAfterInvocationProvider
|
||||||
implements AfterInvocationProvider, InitializingBean {
|
implements AfterInvocationProvider, InitializingBean, MessageSourceAware {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationProvider.class);
|
protected static final Log logger = LogFactory.getLog(BasicAclEntryAfterInvocationProvider.class);
|
||||||
@ -100,41 +101,21 @@ public class BasicAclEntryAfterInvocationProvider
|
|||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
private AclManager aclManager;
|
private AclManager aclManager;
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private String processConfigAttribute = "AFTER_ACL_READ";
|
private String processConfigAttribute = "AFTER_ACL_READ";
|
||||||
private int[] requirePermission = {SimpleAclEntry.READ};
|
private int[] requirePermission = {SimpleAclEntry.READ};
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setAclManager(AclManager aclManager) {
|
|
||||||
this.aclManager = aclManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AclManager getAclManager() {
|
|
||||||
return aclManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProcessConfigAttribute(String processConfigAttribute) {
|
|
||||||
this.processConfigAttribute = processConfigAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProcessConfigAttribute() {
|
|
||||||
return processConfigAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRequirePermission(int[] requirePermission) {
|
|
||||||
this.requirePermission = requirePermission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getRequirePermission() {
|
|
||||||
return requirePermission;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(processConfigAttribute, "A processConfigAttribute is mandatory");
|
Assert.notNull(processConfigAttribute,
|
||||||
|
"A processConfigAttribute is mandatory");
|
||||||
Assert.notNull(aclManager, "An aclManager is mandatory");
|
Assert.notNull(aclManager, "An aclManager is mandatory");
|
||||||
|
Assert.notNull(messages, "A message source must be set");
|
||||||
|
|
||||||
if ((requirePermission == null) || (requirePermission.length == 0)) {
|
if ((requirePermission == null) || (requirePermission.length == 0)) {
|
||||||
throw new IllegalArgumentException("One or more requirePermission entries is mandatory");
|
throw new IllegalArgumentException(
|
||||||
|
"One or more requirePermission entries is mandatory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,10 +143,10 @@ public class BasicAclEntryAfterInvocationProvider
|
|||||||
authentication);
|
authentication);
|
||||||
|
|
||||||
if ((acls == null) || (acls.length == 0)) {
|
if ((acls == null) || (acls.length == 0)) {
|
||||||
throw new AccessDeniedException("Authentication: "
|
throw new AccessDeniedException(messages.getMessage(
|
||||||
+ authentication.toString()
|
"BasicAclEntryAfterInvocationProvider.noPermission",
|
||||||
+ " has NO permissions at all to the domain object: "
|
new Object[] {authentication.getName(), returnedObject},
|
||||||
+ returnedObject);
|
"Authentication {0} has NO permissions at all to the domain object {1}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < acls.length; i++) {
|
for (int i = 0; i < acls.length; i++) {
|
||||||
@ -190,16 +171,44 @@ public class BasicAclEntryAfterInvocationProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No permissions match
|
// No permissions match
|
||||||
throw new AccessDeniedException("Authentication: "
|
throw new AccessDeniedException(messages.getMessage(
|
||||||
+ authentication.toString()
|
"BasicAclEntryAfterInvocationProvider.insufficientPermission",
|
||||||
+ " has ACL permissions to the domain object, but not the required ACL permission to the domain object: "
|
new Object[] {authentication.getName(), returnedObject},
|
||||||
+ returnedObject);
|
"Authentication {0} has ACL permissions to the domain object, but not the required ACL permission to the domain object {1}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnedObject;
|
return returnedObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AclManager getAclManager() {
|
||||||
|
return aclManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProcessConfigAttribute() {
|
||||||
|
return processConfigAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getRequirePermission() {
|
||||||
|
return requirePermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAclManager(AclManager aclManager) {
|
||||||
|
this.aclManager = aclManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProcessConfigAttribute(String processConfigAttribute) {
|
||||||
|
this.processConfigAttribute = processConfigAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequirePermission(int[] requirePermission) {
|
||||||
|
this.requirePermission = requirePermission;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean supports(ConfigAttribute attribute) {
|
public boolean supports(ConfigAttribute attribute) {
|
||||||
if ((attribute.getAttribute() != null)
|
if ((attribute.getAttribute() != null)
|
||||||
&& attribute.getAttribute().equals(getProcessConfigAttribute())) {
|
&& attribute.getAttribute().equals(getProcessConfigAttribute())) {
|
||||||
|
@ -19,6 +19,11 @@ import org.acegisecurity.Authentication;
|
|||||||
import org.acegisecurity.AuthenticationException;
|
import org.acegisecurity.AuthenticationException;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
|
||||||
@ -30,36 +35,61 @@ import org.springframework.util.Assert;
|
|||||||
* By default uses {@link org.acegisecurity.concurrent.SessionRegistryImpl},
|
* By default uses {@link org.acegisecurity.concurrent.SessionRegistryImpl},
|
||||||
* although any <code>SessionRegistry</code> may be used.
|
* although any <code>SessionRegistry</code> may be used.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class ConcurrentSessionControllerImpl
|
public class ConcurrentSessionControllerImpl
|
||||||
implements ConcurrentSessionController, InitializingBean {
|
implements ConcurrentSessionController, InitializingBean,
|
||||||
|
MessageSourceAware {
|
||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private SessionRegistry sessionRegistry = new SessionRegistryImpl();
|
private SessionRegistry sessionRegistry = new SessionRegistryImpl();
|
||||||
private int maximumSessions = 1;
|
|
||||||
private boolean exceptionIfMaximumExceeded = false;
|
private boolean exceptionIfMaximumExceeded = false;
|
||||||
|
private int maximumSessions = 1;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setMaximumSessions(int maximumSessions) {
|
|
||||||
this.maximumSessions = maximumSessions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSessionRegistry(SessionRegistry sessionRegistry) {
|
|
||||||
this.sessionRegistry = sessionRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExceptionIfMaximumExceeded(boolean exceptionIfMaximumExceeded) {
|
|
||||||
this.exceptionIfMaximumExceeded = exceptionIfMaximumExceeded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(sessionRegistry, "SessionRegistry required");
|
Assert.notNull(sessionRegistry, "SessionRegistry required");
|
||||||
Assert.isTrue(maximumSessions != 0,
|
Assert.isTrue(maximumSessions != 0,
|
||||||
"MaximumLogins must be either -1 to allow unlimited logins, or a positive integer to specify a maximum");
|
"MaximumLogins must be either -1 to allow unlimited logins, or a positive integer to specify a maximum");
|
||||||
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows subclasses to customise behaviour when too many sessions are
|
||||||
|
* detected.
|
||||||
|
*
|
||||||
|
* @param sessionId the session ID of the present request
|
||||||
|
* @param sessions either <code>null</code> or all unexpired sessions
|
||||||
|
* associated with the principal
|
||||||
|
* @param allowableSessions DOCUMENT ME!
|
||||||
|
* @param registry an instance of the <code>SessionRegistry</code> for
|
||||||
|
* subclass use
|
||||||
|
*
|
||||||
|
* @throws ConcurrentLoginException DOCUMENT ME!
|
||||||
|
*/
|
||||||
|
protected void allowableSessionsExceeded(String sessionId,
|
||||||
|
SessionInformation[] sessions, int allowableSessions,
|
||||||
|
SessionRegistry registry) {
|
||||||
|
if (exceptionIfMaximumExceeded || (sessions == null)) {
|
||||||
|
throw new ConcurrentLoginException(messages.getMessage(
|
||||||
|
"ConcurrentSessionControllerImpl.exceededAllowed",
|
||||||
|
new Object[] {new Integer(allowableSessions)},
|
||||||
|
"Maximum sessions of {0} for this principal exceeded"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine least recently used session, and mark it for invalidation
|
||||||
|
SessionInformation leastRecentlyUsed = null;
|
||||||
|
|
||||||
|
for (int i = 0; i < sessions.length; i++) {
|
||||||
|
if ((leastRecentlyUsed == null)
|
||||||
|
|| sessions[i].getLastRequest()
|
||||||
|
.before(leastRecentlyUsed.getLastRequest())) {
|
||||||
|
leastRecentlyUsed = sessions[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
leastRecentlyUsed.expireNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkAuthenticationAllowed(Authentication request)
|
public void checkAuthenticationAllowed(Authentication request)
|
||||||
@ -95,35 +125,28 @@ public class ConcurrentSessionControllerImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allowableSessionsExceeded(sessionId, sessions, allowableSessions, sessionRegistry);
|
allowableSessionsExceeded(sessionId, sessions,
|
||||||
|
allowableSessions, sessionRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows subclasses to customise behaviour when too many sessions are
|
* Method intended for use by subclasses to override the maximum
|
||||||
* detected.
|
* number of sessions that are permitted for a particular
|
||||||
|
* authentication. The default implementation simply returns the
|
||||||
|
* <code>maximumSessions</code> value for the bean.
|
||||||
*
|
*
|
||||||
* @param sessionId the session ID of the present request
|
* @param authentication to determine the maximum sessions for
|
||||||
* @param sessions either <code>null</code> or all unexpired sessions associated with the principal
|
*
|
||||||
* @param registry an instance of the <code>SessionRegistry</code> for subclass use
|
* @return either -1 meaning unlimited, or a positive integer to
|
||||||
|
* limit (never zero)
|
||||||
*/
|
*/
|
||||||
protected void allowableSessionsExceeded(String sessionId, SessionInformation[] sessions, int allowableSessions, SessionRegistry registry) {
|
protected int getMaximumSessionsForThisUser(
|
||||||
if (exceptionIfMaximumExceeded || sessions == null) {
|
Authentication authentication) {
|
||||||
throw new ConcurrentLoginException("Maximum sessions of "
|
return maximumSessions;
|
||||||
+ allowableSessions + " for this principal exceeded");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine least recently used session, and mark it for invalidation
|
public void registerSuccessfulAuthentication(
|
||||||
SessionInformation leastRecentlyUsed = null;
|
Authentication authentication) {
|
||||||
for (int i = 0; i < sessions.length; i++) {
|
|
||||||
if (leastRecentlyUsed == null || sessions[i].getLastRequest().before(leastRecentlyUsed.getLastRequest())) {
|
|
||||||
leastRecentlyUsed = sessions[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
leastRecentlyUsed.expireNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerSuccessfulAuthentication(Authentication authentication) {
|
|
||||||
Assert.notNull(authentication,
|
Assert.notNull(authentication,
|
||||||
"Authentication cannot be null (violation of interface contract)");
|
"Authentication cannot be null (violation of interface contract)");
|
||||||
|
|
||||||
@ -136,18 +159,21 @@ public class ConcurrentSessionControllerImpl
|
|||||||
sessionRegistry.registerNewSession(sessionId, principal);
|
sessionRegistry.registerNewSession(sessionId, principal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setExceptionIfMaximumExceeded(
|
||||||
* Method intended for use by subclasses to override the maximum number of
|
boolean exceptionIfMaximumExceeded) {
|
||||||
* sessions that are permitted for a particular authentication. The
|
this.exceptionIfMaximumExceeded = exceptionIfMaximumExceeded;
|
||||||
* default implementation simply returns the <code>maximumSessions</code>
|
}
|
||||||
* value for the bean.
|
|
||||||
*
|
public void setMaximumSessions(int maximumSessions) {
|
||||||
* @param authentication to determine the maximum sessions for
|
this.maximumSessions = maximumSessions;
|
||||||
*
|
}
|
||||||
* @return either -1 meaning unlimited, or a positive integer to limit
|
|
||||||
* (never zero)
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
*/
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
protected int getMaximumSessionsForThisUser(Authentication authentication) {
|
}
|
||||||
return maximumSessions;
|
|
||||||
|
public void setSessionRegistry(
|
||||||
|
SessionRegistry sessionRegistry) {
|
||||||
|
this.sessionRegistry = sessionRegistry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -42,6 +42,9 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.context.ApplicationEventPublisherAware;
|
import org.springframework.context.ApplicationEventPublisherAware;
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
@ -135,12 +138,9 @@ import java.util.Set;
|
|||||||
* </li>
|
* </li>
|
||||||
* </ol>
|
* </ol>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
||||||
ApplicationEventPublisherAware {
|
ApplicationEventPublisherAware, MessageSourceAware {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
protected static final Log logger = LogFactory.getLog(AbstractSecurityInterceptor.class);
|
protected static final Log logger = LogFactory.getLog(AbstractSecurityInterceptor.class);
|
||||||
@ -151,6 +151,7 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
|||||||
private AfterInvocationManager afterInvocationManager;
|
private AfterInvocationManager afterInvocationManager;
|
||||||
private ApplicationEventPublisher eventPublisher;
|
private ApplicationEventPublisher eventPublisher;
|
||||||
private AuthenticationManager authenticationManager;
|
private AuthenticationManager authenticationManager;
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private RunAsManager runAsManager = new NullRunAsManager();
|
private RunAsManager runAsManager = new NullRunAsManager();
|
||||||
private boolean alwaysReauthenticate = false;
|
private boolean alwaysReauthenticate = false;
|
||||||
private boolean rejectPublicInvocations = false;
|
private boolean rejectPublicInvocations = false;
|
||||||
@ -158,115 +159,49 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
|||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setAfterInvocationManager(
|
|
||||||
AfterInvocationManager afterInvocationManager) {
|
|
||||||
this.afterInvocationManager = afterInvocationManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AfterInvocationManager getAfterInvocationManager() {
|
|
||||||
return afterInvocationManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the <code>AbstractSecurityInterceptor</code> should
|
* Completes the work of the <code>AbstractSecurityInterceptor</code> after
|
||||||
* ignore the {@link Authentication#isAuthenticated()} property. Defaults
|
* the secure object invocation has been complete
|
||||||
* to <code>false</code>, meaning by default the
|
|
||||||
* <code>Authentication.isAuthenticated()</code> property is trusted and
|
|
||||||
* re-authentication will not occur if the principal has already been
|
|
||||||
* authenticated.
|
|
||||||
*
|
*
|
||||||
* @param alwaysReauthenticate <code>true</code> to force
|
* @param token as returned by the {@link #beforeInvocation(Object)}}
|
||||||
* <code>AbstractSecurityInterceptor</code> to disregard the value
|
* method
|
||||||
* of <code>Authentication.isAuthenticated()</code> and always
|
* @param returnedObject any object returned from the secure object
|
||||||
* re-authenticate the request (defaults to <code>false</code>).
|
* invocation (may be<code>null</code>)
|
||||||
*/
|
|
||||||
public void setAlwaysReauthenticate(boolean alwaysReauthenticate) {
|
|
||||||
this.alwaysReauthenticate = alwaysReauthenticate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAlwaysReauthenticate() {
|
|
||||||
return alwaysReauthenticate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApplicationEventPublisher(
|
|
||||||
ApplicationEventPublisher eventPublisher) {
|
|
||||||
this.eventPublisher = eventPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates the type of secure objects the subclass will be presenting to
|
|
||||||
* the abstract parent for processing. This is used to ensure
|
|
||||||
* collaborators wired to the <code>AbstractSecurityInterceptor</code> all
|
|
||||||
* support the indicated secure object class.
|
|
||||||
*
|
*
|
||||||
* @return the type of secure object the subclass provides services for
|
* @return the object the secure object invocation should ultimately return
|
||||||
|
* to its caller (may be <code>null</code>)
|
||||||
*/
|
*/
|
||||||
public abstract Class getSecureObjectClass();
|
protected Object afterInvocation(InterceptorStatusToken token,
|
||||||
|
Object returnedObject) {
|
||||||
public abstract ObjectDefinitionSource obtainObjectDefinitionSource();
|
if (token == null) {
|
||||||
|
// public object
|
||||||
public void setAccessDecisionManager(
|
return returnedObject;
|
||||||
AccessDecisionManager accessDecisionManager) {
|
|
||||||
this.accessDecisionManager = accessDecisionManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccessDecisionManager getAccessDecisionManager() {
|
if (token.isContextHolderRefreshRequired()) {
|
||||||
return accessDecisionManager;
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Reverting to original Authentication: "
|
||||||
|
+ token.getAuthentication().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthenticationManager(AuthenticationManager newManager) {
|
SecurityContextHolder.getContext()
|
||||||
this.authenticationManager = newManager;
|
.setAuthentication(token.getAuthentication());
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthenticationManager getAuthenticationManager() {
|
if (afterInvocationManager != null) {
|
||||||
return this.authenticationManager;
|
returnedObject = afterInvocationManager.decide(token
|
||||||
|
.getAuthentication(), token.getSecureObject(),
|
||||||
|
token.getAttr(), returnedObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return returnedObject;
|
||||||
* By rejecting public invocations (and setting this property to
|
|
||||||
* <code>true</code>), essentially you are ensuring that every secure
|
|
||||||
* object invocation advised by <code>AbstractSecurityInterceptor</code>
|
|
||||||
* has a configuration attribute defined. This is useful to ensure a "fail
|
|
||||||
* safe" mode where undeclared secure objects will be rejected and
|
|
||||||
* configuration omissions detected early. An
|
|
||||||
* <code>IllegalArgumentException</code> will be thrown by the
|
|
||||||
* <code>AbstractSecurityInterceptor</code> if you set this property to
|
|
||||||
* <code>true</code> and an attempt is made to invoke a secure object that
|
|
||||||
* has no configuration attributes.
|
|
||||||
*
|
|
||||||
* @param rejectPublicInvocations set to <code>true</code> to reject
|
|
||||||
* invocations of secure objects that have no configuration
|
|
||||||
* attributes (by default it is <code>true</code> which treats
|
|
||||||
* undeclared secure objects as "public" or unauthorized)
|
|
||||||
*/
|
|
||||||
public void setRejectPublicInvocations(boolean rejectPublicInvocations) {
|
|
||||||
this.rejectPublicInvocations = rejectPublicInvocations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRejectPublicInvocations() {
|
|
||||||
return rejectPublicInvocations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRunAsManager(RunAsManager runAsManager) {
|
|
||||||
this.runAsManager = runAsManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RunAsManager getRunAsManager() {
|
|
||||||
return runAsManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValidateConfigAttributes(boolean validateConfigAttributes) {
|
|
||||||
this.validateConfigAttributes = validateConfigAttributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isValidateConfigAttributes() {
|
|
||||||
return validateConfigAttributes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(getSecureObjectClass(),
|
Assert.notNull(getSecureObjectClass(),
|
||||||
"Subclass must provide a non-null response to getSecureObjectClass()");
|
"Subclass must provide a non-null response to getSecureObjectClass()");
|
||||||
|
|
||||||
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
Assert.notNull(this.authenticationManager,
|
Assert.notNull(this.authenticationManager,
|
||||||
"An AuthenticationManager is required");
|
"An AuthenticationManager is required");
|
||||||
|
|
||||||
@ -278,7 +213,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
|||||||
Assert.notNull(this.obtainObjectDefinitionSource(),
|
Assert.notNull(this.obtainObjectDefinitionSource(),
|
||||||
"An ObjectDefinitionSource is required");
|
"An ObjectDefinitionSource is required");
|
||||||
|
|
||||||
if (!this.obtainObjectDefinitionSource().supports(getSecureObjectClass())) {
|
if (!this.obtainObjectDefinitionSource()
|
||||||
|
.supports(getSecureObjectClass())) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"ObjectDefinitionSource does not support secure object class: "
|
"ObjectDefinitionSource does not support secure object class: "
|
||||||
+ getSecureObjectClass());
|
+ getSecureObjectClass());
|
||||||
@ -346,47 +282,10 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Completes the work of the <code>AbstractSecurityInterceptor</code> after
|
|
||||||
* the secure object invocation has been complete
|
|
||||||
*
|
|
||||||
* @param token as returned by the {@link #beforeInvocation(Object)}}
|
|
||||||
* method
|
|
||||||
* @param returnedObject any object returned from the secure object
|
|
||||||
* invocation (may be<code>null</code>)
|
|
||||||
*
|
|
||||||
* @return the object the secure object invocation should ultimately return
|
|
||||||
* to its caller (may be <code>null</code>)
|
|
||||||
*/
|
|
||||||
protected Object afterInvocation(InterceptorStatusToken token,
|
|
||||||
Object returnedObject) {
|
|
||||||
if (token == null) {
|
|
||||||
// public object
|
|
||||||
return returnedObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (token.isContextHolderRefreshRequired()) {
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Reverting to original Authentication: "
|
|
||||||
+ token.getAuthentication().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(token
|
|
||||||
.getAuthentication());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (afterInvocationManager != null) {
|
|
||||||
returnedObject = afterInvocationManager.decide(token
|
|
||||||
.getAuthentication(), token.getSecureObject(),
|
|
||||||
token.getAttr(), returnedObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnedObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected InterceptorStatusToken beforeInvocation(Object object) {
|
protected InterceptorStatusToken beforeInvocation(Object object) {
|
||||||
Assert.notNull(object, "Object was null");
|
Assert.notNull(object, "Object was null");
|
||||||
Assert.isTrue(getSecureObjectClass().isAssignableFrom(object.getClass()),
|
Assert.isTrue(getSecureObjectClass()
|
||||||
|
.isAssignableFrom(object.getClass()),
|
||||||
"Security invocation attempted for object "
|
"Security invocation attempted for object "
|
||||||
+ object.getClass().getName()
|
+ object.getClass().getName()
|
||||||
+ " but AbstractSecurityInterceptor only configured to support secure objects of type: "
|
+ " but AbstractSecurityInterceptor only configured to support secure objects of type: "
|
||||||
@ -409,7 +308,9 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
|||||||
// We check for just the property we're interested in (we do
|
// We check for just the property we're interested in (we do
|
||||||
// not call Context.validate() like the ContextInterceptor)
|
// not call Context.validate() like the ContextInterceptor)
|
||||||
if (SecurityContextHolder.getContext().getAuthentication() == null) {
|
if (SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||||
credentialsNotFound("Authentication credentials were not found in the SecurityContext",
|
credentialsNotFound(messages.getMessage(
|
||||||
|
"AbstractSecurityInterceptor.authenticationNotFound",
|
||||||
|
"An Authentication object was not found in the SecurityContext"),
|
||||||
object, attr);
|
object, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,7 +333,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
|||||||
+ authenticated.toString());
|
+ authenticated.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(authenticated);
|
SecurityContextHolder.getContext()
|
||||||
|
.setAuthentication(authenticated);
|
||||||
} else {
|
} else {
|
||||||
authenticated = SecurityContextHolder.getContext()
|
authenticated = SecurityContextHolder.getContext()
|
||||||
.getAuthentication();
|
.getAuthentication();
|
||||||
@ -445,7 +347,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
|||||||
|
|
||||||
// Attempt authorization
|
// Attempt authorization
|
||||||
try {
|
try {
|
||||||
this.accessDecisionManager.decide(authenticated, object, attr);
|
this.accessDecisionManager.decide(authenticated, object,
|
||||||
|
attr);
|
||||||
} catch (AccessDeniedException accessDeniedException) {
|
} catch (AccessDeniedException accessDeniedException) {
|
||||||
AuthorizationFailureEvent event = new AuthorizationFailureEvent(object,
|
AuthorizationFailureEvent event = new AuthorizationFailureEvent(object,
|
||||||
attr, authenticated, accessDeniedException);
|
attr, authenticated, accessDeniedException);
|
||||||
@ -472,8 +375,8 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
|||||||
"RunAsManager did not change Authentication object");
|
"RunAsManager did not change Authentication object");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new InterceptorStatusToken(authenticated, false, attr,
|
return new InterceptorStatusToken(authenticated, false,
|
||||||
object); // no further work post-invocation
|
attr, object); // no further work post-invocation
|
||||||
} else {
|
} else {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Switching to RunAs Authentication: "
|
logger.debug("Switching to RunAs Authentication: "
|
||||||
@ -482,23 +385,24 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
|||||||
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(runAs);
|
SecurityContextHolder.getContext().setAuthentication(runAs);
|
||||||
|
|
||||||
return new InterceptorStatusToken(authenticated, true, attr,
|
return new InterceptorStatusToken(authenticated, true,
|
||||||
object); // revert to token.Authenticated post-invocation
|
attr, object); // revert to token.Authenticated post-invocation
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Public object - authentication not attempted");
|
logger.debug("Public object - authentication not attempted");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.eventPublisher.publishEvent(new PublicInvocationEvent(object));
|
this.eventPublisher.publishEvent(new PublicInvocationEvent(
|
||||||
|
object));
|
||||||
|
|
||||||
return null; // no further work post-invocation
|
return null; // no further work post-invocation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method which generates an exception containing the passed reason,
|
* Helper method which generates an exception containing the passed
|
||||||
* and publishes an event to the application context.
|
* reason, and publishes an event to the application context.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Always throws an exception.
|
* Always throws an exception.
|
||||||
@ -518,4 +422,115 @@ public abstract class AbstractSecurityInterceptor implements InitializingBean,
|
|||||||
|
|
||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public AccessDecisionManager getAccessDecisionManager() {
|
||||||
|
return accessDecisionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AfterInvocationManager getAfterInvocationManager() {
|
||||||
|
return afterInvocationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticationManager getAuthenticationManager() {
|
||||||
|
return this.authenticationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RunAsManager getRunAsManager() {
|
||||||
|
return runAsManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the type of secure objects the subclass will be presenting
|
||||||
|
* to the abstract parent for processing. This is used to ensure
|
||||||
|
* collaborators wired to the <code>AbstractSecurityInterceptor</code>
|
||||||
|
* all support the indicated secure object class.
|
||||||
|
*
|
||||||
|
* @return the type of secure object the subclass provides services for
|
||||||
|
*/
|
||||||
|
public abstract Class getSecureObjectClass();
|
||||||
|
|
||||||
|
public boolean isAlwaysReauthenticate() {
|
||||||
|
return alwaysReauthenticate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRejectPublicInvocations() {
|
||||||
|
return rejectPublicInvocations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValidateConfigAttributes() {
|
||||||
|
return validateConfigAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ObjectDefinitionSource obtainObjectDefinitionSource();
|
||||||
|
|
||||||
|
public void setAccessDecisionManager(
|
||||||
|
AccessDecisionManager accessDecisionManager) {
|
||||||
|
this.accessDecisionManager = accessDecisionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAfterInvocationManager(
|
||||||
|
AfterInvocationManager afterInvocationManager) {
|
||||||
|
this.afterInvocationManager = afterInvocationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the <code>AbstractSecurityInterceptor</code>
|
||||||
|
* should ignore the {@link Authentication#isAuthenticated()}
|
||||||
|
* property. Defaults to <code>false</code>, meaning by default the
|
||||||
|
* <code>Authentication.isAuthenticated()</code> property is trusted
|
||||||
|
* and re-authentication will not occur if the principal has already
|
||||||
|
* been authenticated.
|
||||||
|
*
|
||||||
|
* @param alwaysReauthenticate <code>true</code> to force
|
||||||
|
* <code>AbstractSecurityInterceptor</code> to disregard the
|
||||||
|
* value of <code>Authentication.isAuthenticated()</code> and
|
||||||
|
* always re-authenticate the request (defaults to
|
||||||
|
* <code>false</code>).
|
||||||
|
*/
|
||||||
|
public void setAlwaysReauthenticate(boolean alwaysReauthenticate) {
|
||||||
|
this.alwaysReauthenticate = alwaysReauthenticate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApplicationEventPublisher(
|
||||||
|
ApplicationEventPublisher eventPublisher) {
|
||||||
|
this.eventPublisher = eventPublisher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticationManager(AuthenticationManager newManager) {
|
||||||
|
this.authenticationManager = newManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By rejecting public invocations (and setting this property to
|
||||||
|
* <code>true</code>), essentially you are ensuring that every secure
|
||||||
|
* object invocation advised by
|
||||||
|
* <code>AbstractSecurityInterceptor</code> has a configuration
|
||||||
|
* attribute defined. This is useful to ensure a "fail safe" mode
|
||||||
|
* where undeclared secure objects will be rejected and configuration
|
||||||
|
* omissions detected early. An <code>IllegalArgumentException</code>
|
||||||
|
* will be thrown by the <code>AbstractSecurityInterceptor</code> if
|
||||||
|
* you set this property to <code>true</code> and an attempt is made
|
||||||
|
* to invoke a secure object that has no configuration attributes.
|
||||||
|
*
|
||||||
|
* @param rejectPublicInvocations set to <code>true</code> to reject
|
||||||
|
* invocations of secure objects that have no configuration
|
||||||
|
* attributes (by default it is <code>true</code> which treats
|
||||||
|
* undeclared secure objects as "public" or unauthorized)
|
||||||
|
*/
|
||||||
|
public void setRejectPublicInvocations(boolean rejectPublicInvocations) {
|
||||||
|
this.rejectPublicInvocations = rejectPublicInvocations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRunAsManager(RunAsManager runAsManager) {
|
||||||
|
this.runAsManager = runAsManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValidateConfigAttributes(
|
||||||
|
boolean validateConfigAttributes) {
|
||||||
|
this.validateConfigAttributes = validateConfigAttributes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
39
core/src/main/java/org/acegisecurity/messages.properties
Normal file
39
core/src/main/java/org/acegisecurity/messages.properties
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
AuthByAdapterProvider.incorrectKey=The presented AuthByAdapter implementation does not contain the expected key
|
||||||
|
BasicAclEntryAfterInvocationProvider.noPermission=Authentication {0} has NO permissions at all to the domain object {1}
|
||||||
|
BasicAclEntryAfterInvocationProvider.insufficientPermission=Authentication {0} has ACL permissions to the domain object, but not the required ACL permission to the domain object {1}
|
||||||
|
ConcurrentSessionControllerImpl.exceededAllowed=Maximum sessions of {0} for this principal exceeded
|
||||||
|
ProviderManager.providerNotFound=No AuthenticationProvider found for {0}
|
||||||
|
AnonymousAuthenticationProvider.incorrectKey=The presented AnonymousAuthenticationToken does not contain the expected key
|
||||||
|
CasAuthenticationProvider.incorrectKey=The presented CasAuthenticationToken does not contain the expected key
|
||||||
|
CasAuthenticationProvider.noServiceTicket=Failed to provide a CAS service ticket to validate
|
||||||
|
NamedCasProxyDecider.untrusted=Nearest proxy {0} is untrusted
|
||||||
|
RejectProxyTickets.reject=Proxy tickets are rejected
|
||||||
|
AbstractSecurityInterceptor.authenticationNotFound=An Authentication object was not found in the SecurityContext
|
||||||
|
AbstractUserDetailsAuthenticationProvider.onlySupports=Only UsernamePasswordAuthenticationToken is supported
|
||||||
|
AbstractUserDetailsAuthenticationProvider.locked=User account is locked
|
||||||
|
AbstractUserDetailsAuthenticationProvider.disabled=User is disabled
|
||||||
|
AbstractUserDetailsAuthenticationProvider.expired=User account has expired
|
||||||
|
AbstractUserDetailsAuthenticationProvider.credentialsExpired=User credentials have expired
|
||||||
|
AbstractUserDetailsAuthenticationProvider.badCredentials=Bad credentials
|
||||||
|
X509AuthenticationProvider.certificateNull=Certificate is null
|
||||||
|
DaoX509AuthoritiesPopulator.noMatching=No matching pattern was found in subjectDN: {0}
|
||||||
|
RememberMeAuthenticationProvider.incorrectKey=The presented RememberMeAuthenticationToken does not contain the expected key
|
||||||
|
RunAsImplAuthenticationProvider.incorrectKey=The presented RunAsUserToken does not contain the expected key
|
||||||
|
DigestProcessingFilter.missingMandatory=Missing mandatory digest value; received header {0}
|
||||||
|
DigestProcessingFilter.missingAuth=Missing mandatory digest value for 'auth' QOP; received header {0}
|
||||||
|
DigestProcessingFilter.incorrectRealm=Response realm name {0} does not match system realm name of {1}
|
||||||
|
DigestProcessingFilter.nonceExpired=Nonce has expired/timed out
|
||||||
|
DigestProcessingFilter.nonceEncoding=Nonce is not encoded in Base64; received nonce {0}
|
||||||
|
DigestProcessingFilter.nonceNotTwoTokens=Nonce should have yielded two tokens but was {0}
|
||||||
|
DigestProcessingFilter.nonceNotNumeric=Nonce token should have yielded a numeric first token, but was {0}
|
||||||
|
DigestProcessingFilter.nonceCompromised=Nonce token compromised {0}
|
||||||
|
DigestProcessingFilter.usernameNotFound=Username {0} not found
|
||||||
|
DigestProcessingFilter.incorrectResponse=Incorrect response
|
||||||
|
SwitchUserProcessingFilter.noCurrentUser=No current user associated with this request
|
||||||
|
SwitchUserProcessingFilter.noOriginalAuthentication=Could not find original Authentication object
|
||||||
|
SwitchUserProcessingFilter.usernameNotFound=Username {0} not found
|
||||||
|
SwitchUserProcessingFilter.locked=User account is locked
|
||||||
|
SwitchUserProcessingFilter.disabled=User is disabled
|
||||||
|
SwitchUserProcessingFilter.expired=User account has expired
|
||||||
|
SwitchUserProcessingFilter.credentialsExpired=User credentials have expired
|
||||||
|
AbstractAccessDecisionManager.accessDenied=Access is denied
|
@ -24,9 +24,11 @@ import org.acegisecurity.BadCredentialsException;
|
|||||||
import org.acegisecurity.CredentialsExpiredException;
|
import org.acegisecurity.CredentialsExpiredException;
|
||||||
import org.acegisecurity.DisabledException;
|
import org.acegisecurity.DisabledException;
|
||||||
import org.acegisecurity.LockedException;
|
import org.acegisecurity.LockedException;
|
||||||
|
|
||||||
import org.acegisecurity.concurrent.ConcurrentLoginException;
|
import org.acegisecurity.concurrent.ConcurrentLoginException;
|
||||||
import org.acegisecurity.concurrent.ConcurrentSessionController;
|
import org.acegisecurity.concurrent.ConcurrentSessionController;
|
||||||
import org.acegisecurity.concurrent.NullConcurrentSessionController;
|
import org.acegisecurity.concurrent.NullConcurrentSessionController;
|
||||||
|
|
||||||
import org.acegisecurity.event.authentication.AbstractAuthenticationEvent;
|
import org.acegisecurity.event.authentication.AbstractAuthenticationEvent;
|
||||||
import org.acegisecurity.event.authentication.AuthenticationFailureBadCredentialsEvent;
|
import org.acegisecurity.event.authentication.AuthenticationFailureBadCredentialsEvent;
|
||||||
import org.acegisecurity.event.authentication.AuthenticationFailureConcurrentLoginEvent;
|
import org.acegisecurity.event.authentication.AuthenticationFailureConcurrentLoginEvent;
|
||||||
@ -38,6 +40,7 @@ import org.acegisecurity.event.authentication.AuthenticationFailureProviderNotFo
|
|||||||
import org.acegisecurity.event.authentication.AuthenticationFailureProxyUntrustedEvent;
|
import org.acegisecurity.event.authentication.AuthenticationFailureProxyUntrustedEvent;
|
||||||
import org.acegisecurity.event.authentication.AuthenticationFailureServiceExceptionEvent;
|
import org.acegisecurity.event.authentication.AuthenticationFailureServiceExceptionEvent;
|
||||||
import org.acegisecurity.event.authentication.AuthenticationSuccessEvent;
|
import org.acegisecurity.event.authentication.AuthenticationSuccessEvent;
|
||||||
|
|
||||||
import org.acegisecurity.providers.cas.ProxyUntrustedException;
|
import org.acegisecurity.providers.cas.ProxyUntrustedException;
|
||||||
import org.acegisecurity.providers.dao.UsernameNotFoundException;
|
import org.acegisecurity.providers.dao.UsernameNotFoundException;
|
||||||
|
|
||||||
@ -48,6 +51,9 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.context.ApplicationEventPublisherAware;
|
import org.springframework.context.ApplicationEventPublisherAware;
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
@ -85,8 +91,8 @@ import java.util.Properties;
|
|||||||
* If a valid <code>Authentication</code> is returned by an
|
* If a valid <code>Authentication</code> is returned by an
|
||||||
* <code>AuthenticationProvider</code>, the <code>ProviderManager</code> will
|
* <code>AuthenticationProvider</code>, the <code>ProviderManager</code> will
|
||||||
* publish an {@link
|
* publish an {@link
|
||||||
* org.acegisecurity.event.authentication.AuthenticationSuccessEvent}. If
|
* org.acegisecurity.event.authentication.AuthenticationSuccessEvent}. If an
|
||||||
* an <code>AuthenticationException</code> is detected, the final
|
* <code>AuthenticationException</code> is detected, the final
|
||||||
* <code>AuthenticationException</code> thrown will be used to publish an
|
* <code>AuthenticationException</code> thrown will be used to publish an
|
||||||
* appropriate failure event. By default <code>ProviderManager</code> maps
|
* appropriate failure event. By default <code>ProviderManager</code> maps
|
||||||
* common exceptions to events, but this can be fine-tuned by providing a new
|
* common exceptions to events, but this can be fine-tuned by providing a new
|
||||||
@ -98,15 +104,11 @@ import java.util.Properties;
|
|||||||
* and provides its constructor.
|
* and provides its constructor.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Ben Alex
|
|
||||||
* @author Wesley Hall
|
|
||||||
* @author Ray Krueger
|
|
||||||
* @version $Id$
|
|
||||||
*
|
|
||||||
* @see ConcurrentSessionController
|
* @see ConcurrentSessionController
|
||||||
*/
|
*/
|
||||||
public class ProviderManager extends AbstractAuthenticationManager
|
public class ProviderManager extends AbstractAuthenticationManager
|
||||||
implements InitializingBean, ApplicationEventPublisherAware {
|
implements InitializingBean, ApplicationEventPublisherAware,
|
||||||
|
MessageSourceAware {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(ProviderManager.class);
|
private static final Log logger = LogFactory.getLog(ProviderManager.class);
|
||||||
@ -116,74 +118,14 @@ public class ProviderManager extends AbstractAuthenticationManager
|
|||||||
private ApplicationEventPublisher applicationEventPublisher;
|
private ApplicationEventPublisher applicationEventPublisher;
|
||||||
private ConcurrentSessionController sessionController = new NullConcurrentSessionController();
|
private ConcurrentSessionController sessionController = new NullConcurrentSessionController();
|
||||||
private List providers;
|
private List providers;
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private Properties exceptionMappings;
|
private Properties exceptionMappings;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setApplicationEventPublisher(
|
|
||||||
ApplicationEventPublisher applicationEventPublisher) {
|
|
||||||
this.applicationEventPublisher = applicationEventPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the {@link AuthenticationProvider} objects to be used for
|
|
||||||
* authentication.
|
|
||||||
*
|
|
||||||
* @param newList
|
|
||||||
*
|
|
||||||
* @throws IllegalArgumentException DOCUMENT ME!
|
|
||||||
*/
|
|
||||||
public void setProviders(List newList) {
|
|
||||||
checkIfValidList(newList);
|
|
||||||
|
|
||||||
Iterator iter = newList.iterator();
|
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
|
||||||
Object currentObject = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
currentObject = iter.next();
|
|
||||||
|
|
||||||
AuthenticationProvider attemptToCast = (AuthenticationProvider) currentObject;
|
|
||||||
} catch (ClassCastException cce) {
|
|
||||||
throw new IllegalArgumentException("AuthenticationProvider "
|
|
||||||
+ currentObject.getClass().getName()
|
|
||||||
+ " must implement AuthenticationProvider");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.providers = newList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List getProviders() {
|
|
||||||
return this.providers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the {@link ConcurrentSessionController} to be used for limiting
|
|
||||||
* user's sessions. The {@link NullConcurrentSessionController} is used
|
|
||||||
* by default
|
|
||||||
*
|
|
||||||
* @param sessionController {@link ConcurrentSessionController}
|
|
||||||
*/
|
|
||||||
public void setSessionController(
|
|
||||||
ConcurrentSessionController sessionController) {
|
|
||||||
this.sessionController = sessionController;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The configured {@link ConcurrentSessionController} is returned or the
|
|
||||||
* {@link NullConcurrentSessionController} if a specific one has not been
|
|
||||||
* set.
|
|
||||||
*
|
|
||||||
* @return {@link ConcurrentSessionController} instance
|
|
||||||
*/
|
|
||||||
public ConcurrentSessionController getSessionController() {
|
|
||||||
return sessionController;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
checkIfValidList(this.providers);
|
checkIfValidList(this.providers);
|
||||||
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
|
|
||||||
if (exceptionMappings == null) {
|
if (exceptionMappings == null) {
|
||||||
exceptionMappings = new Properties();
|
exceptionMappings = new Properties();
|
||||||
@ -211,6 +153,23 @@ public class ProviderManager extends AbstractAuthenticationManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkIfValidList(List listToCheck) {
|
||||||
|
if ((listToCheck == null) || (listToCheck.size() == 0)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"A list of AuthenticationManagers is required");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provided so subclasses can add extra exception mappings during startup
|
||||||
|
* if no exception mappings are injected by the IoC container.
|
||||||
|
*
|
||||||
|
* @param exceptionMappings the properties object, which already has
|
||||||
|
* entries in it
|
||||||
|
*/
|
||||||
|
protected void doAddExtraDefaultExceptionMappings(
|
||||||
|
Properties exceptionMappings) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to authenticate the passed {@link Authentication} object.
|
* Attempts to authenticate the passed {@link Authentication} object.
|
||||||
*
|
*
|
||||||
@ -244,8 +203,7 @@ public class ProviderManager extends AbstractAuthenticationManager
|
|||||||
AuthenticationException lastException = null;
|
AuthenticationException lastException = null;
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
AuthenticationProvider provider = (AuthenticationProvider) iter
|
AuthenticationProvider provider = (AuthenticationProvider) iter.next();
|
||||||
.next();
|
|
||||||
|
|
||||||
if (provider.supports(toTest)) {
|
if (provider.supports(toTest)) {
|
||||||
logger.debug("Authentication attempt using "
|
logger.debug("Authentication attempt using "
|
||||||
@ -272,8 +230,10 @@ public class ProviderManager extends AbstractAuthenticationManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lastException == null) {
|
if (lastException == null) {
|
||||||
lastException = new ProviderNotFoundException(
|
lastException = new ProviderNotFoundException(messages.getMessage(
|
||||||
"No authentication provider for " + toTest.getName());
|
"ProviderManager.providerNotFound",
|
||||||
|
new Object[] {toTest.getName()},
|
||||||
|
"No AuthenticationProvider found for {0}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish the event
|
// Publish the event
|
||||||
@ -309,20 +269,69 @@ public class ProviderManager extends AbstractAuthenticationManager
|
|||||||
throw lastException;
|
throw lastException;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public List getProviders() {
|
||||||
* Provided so subclasses can add extra exception mappings during startup
|
return this.providers;
|
||||||
* if no exception mappings are injected by the IoC container.
|
|
||||||
*
|
|
||||||
* @param exceptionMappings the properties object, which already has
|
|
||||||
* entries in it
|
|
||||||
*/
|
|
||||||
protected void doAddExtraDefaultExceptionMappings(
|
|
||||||
Properties exceptionMappings) {}
|
|
||||||
|
|
||||||
private void checkIfValidList(List listToCheck) {
|
|
||||||
if ((listToCheck == null) || (listToCheck.size() == 0)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"A list of AuthenticationManagers is required");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The configured {@link ConcurrentSessionController} is returned or the
|
||||||
|
* {@link NullConcurrentSessionController} if a specific one has not been
|
||||||
|
* set.
|
||||||
|
*
|
||||||
|
* @return {@link ConcurrentSessionController} instance
|
||||||
|
*/
|
||||||
|
public ConcurrentSessionController getSessionController() {
|
||||||
|
return sessionController;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApplicationEventPublisher(
|
||||||
|
ApplicationEventPublisher applicationEventPublisher) {
|
||||||
|
this.applicationEventPublisher = applicationEventPublisher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link AuthenticationProvider} objects to be used for
|
||||||
|
* authentication.
|
||||||
|
*
|
||||||
|
* @param newList
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException DOCUMENT ME!
|
||||||
|
*/
|
||||||
|
public void setProviders(List newList) {
|
||||||
|
checkIfValidList(newList);
|
||||||
|
|
||||||
|
Iterator iter = newList.iterator();
|
||||||
|
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Object currentObject = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
currentObject = iter.next();
|
||||||
|
|
||||||
|
AuthenticationProvider attemptToCast = (AuthenticationProvider) currentObject;
|
||||||
|
} catch (ClassCastException cce) {
|
||||||
|
throw new IllegalArgumentException("AuthenticationProvider "
|
||||||
|
+ currentObject.getClass().getName()
|
||||||
|
+ " must implement AuthenticationProvider");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.providers = newList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the {@link ConcurrentSessionController} to be used for limiting
|
||||||
|
* user's sessions. The {@link NullConcurrentSessionController} is used
|
||||||
|
* by default
|
||||||
|
*
|
||||||
|
* @param sessionController {@link ConcurrentSessionController}
|
||||||
|
*/
|
||||||
|
public void setSessionController(
|
||||||
|
ConcurrentSessionController sessionController) {
|
||||||
|
this.sessionController = sessionController;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package org.acegisecurity.providers.anonymous;
|
|||||||
import org.acegisecurity.Authentication;
|
import org.acegisecurity.Authentication;
|
||||||
import org.acegisecurity.AuthenticationException;
|
import org.acegisecurity.AuthenticationException;
|
||||||
import org.acegisecurity.BadCredentialsException;
|
import org.acegisecurity.BadCredentialsException;
|
||||||
|
|
||||||
import org.acegisecurity.providers.AuthenticationProvider;
|
import org.acegisecurity.providers.AuthenticationProvider;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@ -25,6 +26,10 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
|
||||||
@ -37,32 +42,23 @@ import org.springframework.util.Assert;
|
|||||||
* org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken#getKeyHash()}
|
* org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken#getKeyHash()}
|
||||||
* must match this class' {@link #getKey()}.
|
* must match this class' {@link #getKey()}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class AnonymousAuthenticationProvider implements AuthenticationProvider,
|
public class AnonymousAuthenticationProvider implements AuthenticationProvider,
|
||||||
InitializingBean {
|
InitializingBean, MessageSourceAware {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(AnonymousAuthenticationProvider.class);
|
private static final Log logger = LogFactory.getLog(AnonymousAuthenticationProvider.class);
|
||||||
|
|
||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private String key;
|
private String key;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setKey(String key) {
|
|
||||||
this.key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.hasLength(key);
|
Assert.hasLength(key, "A Key is required");
|
||||||
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Authentication authenticate(Authentication authentication)
|
public Authentication authenticate(Authentication authentication)
|
||||||
@ -73,13 +69,26 @@ public class AnonymousAuthenticationProvider implements AuthenticationProvider,
|
|||||||
|
|
||||||
if (this.key.hashCode() != ((AnonymousAuthenticationToken) authentication)
|
if (this.key.hashCode() != ((AnonymousAuthenticationToken) authentication)
|
||||||
.getKeyHash()) {
|
.getKeyHash()) {
|
||||||
throw new BadCredentialsException(
|
throw new BadCredentialsException(messages.getMessage(
|
||||||
"The presented AnonymousAuthenticationToken does not contain the expected key");
|
"AnonymousAuthenticationProvider.incorrectKey",
|
||||||
|
"The presented AnonymousAuthenticationToken does not contain the expected key"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return authentication;
|
return authentication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean supports(Class authentication) {
|
public boolean supports(Class authentication) {
|
||||||
return (AnonymousAuthenticationToken.class.isAssignableFrom(authentication));
|
return (AnonymousAuthenticationToken.class.isAssignableFrom(authentication));
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -19,14 +19,21 @@ import org.acegisecurity.Authentication;
|
|||||||
import org.acegisecurity.AuthenticationException;
|
import org.acegisecurity.AuthenticationException;
|
||||||
import org.acegisecurity.BadCredentialsException;
|
import org.acegisecurity.BadCredentialsException;
|
||||||
import org.acegisecurity.UserDetails;
|
import org.acegisecurity.UserDetails;
|
||||||
|
|
||||||
import org.acegisecurity.providers.AuthenticationProvider;
|
import org.acegisecurity.providers.AuthenticationProvider;
|
||||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
|
|
||||||
import org.acegisecurity.ui.cas.CasProcessingFilter;
|
import org.acegisecurity.ui.cas.CasProcessingFilter;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
|
||||||
@ -42,12 +49,9 @@ import org.springframework.util.Assert;
|
|||||||
* CasProcessingFilter#CAS_STATELESS_IDENTIFIER}. It can also validate a
|
* CasProcessingFilter#CAS_STATELESS_IDENTIFIER}. It can also validate a
|
||||||
* previously created {@link CasAuthenticationToken}.
|
* previously created {@link CasAuthenticationToken}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class CasAuthenticationProvider implements AuthenticationProvider,
|
public class CasAuthenticationProvider implements AuthenticationProvider,
|
||||||
InitializingBean {
|
InitializingBean, MessageSourceAware {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(CasAuthenticationProvider.class);
|
private static final Log logger = LogFactory.getLog(CasAuthenticationProvider.class);
|
||||||
@ -56,60 +60,23 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||||||
|
|
||||||
private CasAuthoritiesPopulator casAuthoritiesPopulator;
|
private CasAuthoritiesPopulator casAuthoritiesPopulator;
|
||||||
private CasProxyDecider casProxyDecider;
|
private CasProxyDecider casProxyDecider;
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private StatelessTicketCache statelessTicketCache;
|
private StatelessTicketCache statelessTicketCache;
|
||||||
private String key;
|
private String key;
|
||||||
private TicketValidator ticketValidator;
|
private TicketValidator ticketValidator;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setCasAuthoritiesPopulator(
|
|
||||||
CasAuthoritiesPopulator casAuthoritiesPopulator) {
|
|
||||||
this.casAuthoritiesPopulator = casAuthoritiesPopulator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CasAuthoritiesPopulator getCasAuthoritiesPopulator() {
|
|
||||||
return casAuthoritiesPopulator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCasProxyDecider(CasProxyDecider casProxyDecider) {
|
|
||||||
this.casProxyDecider = casProxyDecider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CasProxyDecider getCasProxyDecider() {
|
|
||||||
return casProxyDecider;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setKey(String key) {
|
|
||||||
this.key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatelessTicketCache(
|
|
||||||
StatelessTicketCache statelessTicketCache) {
|
|
||||||
this.statelessTicketCache = statelessTicketCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StatelessTicketCache getStatelessTicketCache() {
|
|
||||||
return statelessTicketCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTicketValidator(TicketValidator ticketValidator) {
|
|
||||||
this.ticketValidator = ticketValidator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TicketValidator getTicketValidator() {
|
|
||||||
return ticketValidator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(this.casAuthoritiesPopulator, "A casAuthoritiesPopulator must be set");
|
Assert.notNull(this.casAuthoritiesPopulator,
|
||||||
|
"A casAuthoritiesPopulator must be set");
|
||||||
Assert.notNull(this.ticketValidator, "A ticketValidator must be set");
|
Assert.notNull(this.ticketValidator, "A ticketValidator must be set");
|
||||||
Assert.notNull(this.casProxyDecider, "A casProxyDecider must be set");
|
Assert.notNull(this.casProxyDecider, "A casProxyDecider must be set");
|
||||||
Assert.notNull(this.statelessTicketCache, "A statelessTicketCache must be set");
|
Assert.notNull(this.statelessTicketCache,
|
||||||
Assert.notNull(key, "A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated");
|
"A statelessTicketCache must be set");
|
||||||
|
Assert.notNull(key,
|
||||||
|
"A Key is required so CasAuthenticationProvider can identify tokens it previously authenticated");
|
||||||
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Authentication authenticate(Authentication authentication)
|
public Authentication authenticate(Authentication authentication)
|
||||||
@ -133,16 +100,18 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||||||
.getKeyHash()) {
|
.getKeyHash()) {
|
||||||
return authentication;
|
return authentication;
|
||||||
} else {
|
} else {
|
||||||
throw new BadCredentialsException(
|
throw new BadCredentialsException(messages.getMessage(
|
||||||
"The presented CasAuthenticationToken does not contain the expected key");
|
"CasAuthenticationProvider.incorrectKey",
|
||||||
|
"The presented CasAuthenticationToken does not contain the expected key"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure credentials are presented
|
// Ensure credentials are presented
|
||||||
if ((authentication.getCredentials() == null)
|
if ((authentication.getCredentials() == null)
|
||||||
|| "".equals(authentication.getCredentials())) {
|
|| "".equals(authentication.getCredentials())) {
|
||||||
throw new BadCredentialsException(
|
throw new BadCredentialsException(messages.getMessage(
|
||||||
"Failed to provide a CAS service ticket to validate");
|
"CasAuthenticationProvider.noServiceTicket",
|
||||||
|
"Failed to provide a CAS service ticket to validate"));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean stateless = false;
|
boolean stateless = false;
|
||||||
@ -173,17 +142,6 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supports(Class authentication) {
|
|
||||||
if (UsernamePasswordAuthenticationToken.class.isAssignableFrom(
|
|
||||||
authentication)) {
|
|
||||||
return true;
|
|
||||||
} else if (CasAuthenticationToken.class.isAssignableFrom(authentication)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private CasAuthenticationToken authenticateNow(
|
private CasAuthenticationToken authenticateNow(
|
||||||
Authentication authentication) throws AuthenticationException {
|
Authentication authentication) throws AuthenticationException {
|
||||||
// Validate
|
// Validate
|
||||||
@ -203,4 +161,61 @@ public class CasAuthenticationProvider implements AuthenticationProvider,
|
|||||||
userDetails, response.getProxyList(),
|
userDetails, response.getProxyList(),
|
||||||
response.getProxyGrantingTicketIou());
|
response.getProxyGrantingTicketIou());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CasAuthoritiesPopulator getCasAuthoritiesPopulator() {
|
||||||
|
return casAuthoritiesPopulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CasProxyDecider getCasProxyDecider() {
|
||||||
|
return casProxyDecider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatelessTicketCache getStatelessTicketCache() {
|
||||||
|
return statelessTicketCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TicketValidator getTicketValidator() {
|
||||||
|
return ticketValidator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCasAuthoritiesPopulator(
|
||||||
|
CasAuthoritiesPopulator casAuthoritiesPopulator) {
|
||||||
|
this.casAuthoritiesPopulator = casAuthoritiesPopulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCasProxyDecider(CasProxyDecider casProxyDecider) {
|
||||||
|
this.casProxyDecider = casProxyDecider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatelessTicketCache(
|
||||||
|
StatelessTicketCache statelessTicketCache) {
|
||||||
|
this.statelessTicketCache = statelessTicketCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTicketValidator(TicketValidator ticketValidator) {
|
||||||
|
this.ticketValidator = ticketValidator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supports(Class authentication) {
|
||||||
|
if (UsernamePasswordAuthenticationToken.class.isAssignableFrom(
|
||||||
|
authentication)) {
|
||||||
|
return true;
|
||||||
|
} else if (CasAuthenticationToken.class.isAssignableFrom(authentication)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -22,6 +22,11 @@ import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -35,11 +40,9 @@ import java.util.List;
|
|||||||
* Also accepts the request if there was no proxy (ie the user directly
|
* Also accepts the request if there was no proxy (ie the user directly
|
||||||
* authenticated against this service).
|
* authenticated against this service).
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean {
|
public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean,
|
||||||
|
MessageSourceAware {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(NamedCasProxyDecider.class);
|
private static final Log logger = LogFactory.getLog(NamedCasProxyDecider.class);
|
||||||
@ -47,19 +50,13 @@ public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean {
|
|||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
private List validProxies;
|
private List validProxies;
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setValidProxies(List validProxies) {
|
|
||||||
this.validProxies = validProxies;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List getValidProxies() {
|
|
||||||
return validProxies;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(this.validProxies, "A validProxies list must be set");
|
Assert.notNull(this.validProxies, "A validProxies list must be set");
|
||||||
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void confirmProxyListTrusted(List proxyList)
|
public void confirmProxyListTrusted(List proxyList)
|
||||||
@ -76,8 +73,22 @@ public class NamedCasProxyDecider implements CasProxyDecider, InitializingBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!validProxies.contains(proxyList.get(0))) {
|
if (!validProxies.contains(proxyList.get(0))) {
|
||||||
throw new ProxyUntrustedException("Nearest proxy '"
|
throw new ProxyUntrustedException(messages.getMessage(
|
||||||
+ proxyList.get(0) + "' is untrusted");
|
"NamedCasProxyDecider.untrusted",
|
||||||
|
new Object[] {proxyList.get(0)},
|
||||||
|
"Nearest proxy {0} is untrusted"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List getValidProxies() {
|
||||||
|
return validProxies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValidProxies(List validProxies) {
|
||||||
|
this.validProxies = validProxies;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -20,6 +20,13 @@ import org.acegisecurity.providers.cas.ProxyUntrustedException;
|
|||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -32,17 +39,23 @@ import java.util.List;
|
|||||||
* This class should be used if only service tickets wish to be accepted (ie no
|
* This class should be used if only service tickets wish to be accepted (ie no
|
||||||
* proxy tickets at all).
|
* proxy tickets at all).
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class RejectProxyTickets implements CasProxyDecider {
|
public class RejectProxyTickets implements CasProxyDecider, MessageSourceAware,
|
||||||
|
InitializingBean {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(RejectProxyTickets.class);
|
private static final Log logger = LogFactory.getLog(RejectProxyTickets.class);
|
||||||
|
|
||||||
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
|
}
|
||||||
|
|
||||||
public void confirmProxyListTrusted(List proxyList)
|
public void confirmProxyListTrusted(List proxyList)
|
||||||
throws ProxyUntrustedException {
|
throws ProxyUntrustedException {
|
||||||
Assert.notNull(proxyList, "proxyList cannot be null");
|
Assert.notNull(proxyList, "proxyList cannot be null");
|
||||||
@ -57,6 +70,11 @@ public class RejectProxyTickets implements CasProxyDecider {
|
|||||||
+ proxyList.toString());
|
+ proxyList.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new ProxyUntrustedException("Proxy tickets are rejected");
|
throw new ProxyUntrustedException(messages.getMessage(
|
||||||
|
"RejectProxyTickets.reject", "Proxy tickets are rejected"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,17 @@ import org.acegisecurity.CredentialsExpiredException;
|
|||||||
import org.acegisecurity.DisabledException;
|
import org.acegisecurity.DisabledException;
|
||||||
import org.acegisecurity.LockedException;
|
import org.acegisecurity.LockedException;
|
||||||
import org.acegisecurity.UserDetails;
|
import org.acegisecurity.UserDetails;
|
||||||
|
|
||||||
import org.acegisecurity.providers.AuthenticationProvider;
|
import org.acegisecurity.providers.AuthenticationProvider;
|
||||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
import org.acegisecurity.providers.dao.cache.NullUserCache;
|
import org.acegisecurity.providers.dao.cache.NullUserCache;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
|
||||||
@ -62,110 +67,17 @@ import org.springframework.util.Assert;
|
|||||||
* incorrect password, the {@link AuthenticationDao} will be queried to
|
* incorrect password, the {@link AuthenticationDao} will be queried to
|
||||||
* confirm the most up-to-date password was used for comparison.
|
* confirm the most up-to-date password was used for comparison.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractUserDetailsAuthenticationProvider
|
public abstract class AbstractUserDetailsAuthenticationProvider
|
||||||
implements AuthenticationProvider, InitializingBean {
|
implements AuthenticationProvider, InitializingBean, MessageSourceAware {
|
||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private UserCache userCache = new NullUserCache();
|
private UserCache userCache = new NullUserCache();
|
||||||
private boolean forcePrincipalAsString = false;
|
private boolean forcePrincipalAsString = false;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setForcePrincipalAsString(boolean forcePrincipalAsString) {
|
|
||||||
this.forcePrincipalAsString = forcePrincipalAsString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isForcePrincipalAsString() {
|
|
||||||
return forcePrincipalAsString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserCache(UserCache userCache) {
|
|
||||||
this.userCache = userCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserCache getUserCache() {
|
|
||||||
return userCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void afterPropertiesSet() throws Exception {
|
|
||||||
Assert.notNull(this.userCache, "A user cache must be set");
|
|
||||||
doAfterPropertiesSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Authentication authenticate(Authentication authentication)
|
|
||||||
throws AuthenticationException {
|
|
||||||
Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class,
|
|
||||||
authentication,
|
|
||||||
"Only UsernamePasswordAuthenticationToken is supported");
|
|
||||||
|
|
||||||
// Determine username
|
|
||||||
String username = (authentication.getPrincipal() == null)
|
|
||||||
? "NONE_PROVIDED" : authentication.getName();
|
|
||||||
|
|
||||||
boolean cacheWasUsed = true;
|
|
||||||
UserDetails user = this.userCache.getUserFromCache(username);
|
|
||||||
|
|
||||||
if (user == null) {
|
|
||||||
cacheWasUsed = false;
|
|
||||||
user = retrieveUser(username,
|
|
||||||
(UsernamePasswordAuthenticationToken) authentication);
|
|
||||||
Assert.notNull(user,
|
|
||||||
"retrieveUser returned null - a violation of the interface contract");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user.isAccountNonLocked()) {
|
|
||||||
throw new LockedException("User account is locked");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user.isEnabled()) {
|
|
||||||
throw new DisabledException("User is disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user.isAccountNonExpired()) {
|
|
||||||
throw new AccountExpiredException("User account has expired");
|
|
||||||
}
|
|
||||||
|
|
||||||
// This check must come here, as we don't want to tell users
|
|
||||||
// about account status unless they presented the correct credentials
|
|
||||||
try {
|
|
||||||
additionalAuthenticationChecks(user,
|
|
||||||
(UsernamePasswordAuthenticationToken) authentication);
|
|
||||||
} catch (AuthenticationException exception) {
|
|
||||||
// There was a problem, so try again after checking we're using latest data
|
|
||||||
cacheWasUsed = false;
|
|
||||||
user = retrieveUser(username,
|
|
||||||
(UsernamePasswordAuthenticationToken) authentication);
|
|
||||||
additionalAuthenticationChecks(user,
|
|
||||||
(UsernamePasswordAuthenticationToken) authentication);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user.isCredentialsNonExpired()) {
|
|
||||||
throw new CredentialsExpiredException(
|
|
||||||
"User credentials have expired");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cacheWasUsed) {
|
|
||||||
this.userCache.putUserInCache(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object principalToReturn = user;
|
|
||||||
|
|
||||||
if (forcePrincipalAsString) {
|
|
||||||
principalToReturn = user.getUsername();
|
|
||||||
}
|
|
||||||
|
|
||||||
return createSuccessAuthentication(principalToReturn, authentication,
|
|
||||||
user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean supports(Class authentication) {
|
|
||||||
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows subclasses to perform any additional checks of a returned (or
|
* Allows subclasses to perform any additional checks of a returned (or
|
||||||
* cached) <code>UserDetails</code> for a given authentication request.
|
* cached) <code>UserDetails</code> for a given authentication request.
|
||||||
@ -190,8 +102,132 @@ public abstract class AbstractUserDetailsAuthenticationProvider
|
|||||||
UsernamePasswordAuthenticationToken authentication)
|
UsernamePasswordAuthenticationToken authentication)
|
||||||
throws AuthenticationException;
|
throws AuthenticationException;
|
||||||
|
|
||||||
|
public final void afterPropertiesSet() throws Exception {
|
||||||
|
Assert.notNull(this.userCache, "A user cache must be set");
|
||||||
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
|
doAfterPropertiesSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Authentication authenticate(Authentication authentication)
|
||||||
|
throws AuthenticationException {
|
||||||
|
Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class,
|
||||||
|
authentication,
|
||||||
|
messages.getMessage(
|
||||||
|
"AbstractUserDetailsAuthenticationProvider.onlySupports",
|
||||||
|
"Only UsernamePasswordAuthenticationToken is supported"));
|
||||||
|
|
||||||
|
// Determine username
|
||||||
|
String username = (authentication.getPrincipal() == null)
|
||||||
|
? "NONE_PROVIDED" : authentication.getName();
|
||||||
|
|
||||||
|
boolean cacheWasUsed = true;
|
||||||
|
UserDetails user = this.userCache.getUserFromCache(username);
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
cacheWasUsed = false;
|
||||||
|
user = retrieveUser(username,
|
||||||
|
(UsernamePasswordAuthenticationToken) authentication);
|
||||||
|
Assert.notNull(user,
|
||||||
|
"retrieveUser returned null - a violation of the interface contract");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user.isAccountNonLocked()) {
|
||||||
|
throw new LockedException(messages.getMessage(
|
||||||
|
"AbstractUserDetailsAuthenticationProvider.locked",
|
||||||
|
"User account is locked"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user.isEnabled()) {
|
||||||
|
throw new DisabledException(messages.getMessage(
|
||||||
|
"AbstractUserDetailsAuthenticationProvider.disabled",
|
||||||
|
"User is disabled"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user.isAccountNonExpired()) {
|
||||||
|
throw new AccountExpiredException(messages.getMessage(
|
||||||
|
"AbstractUserDetailsAuthenticationProvider.expired",
|
||||||
|
"User account has expired"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This check must come here, as we don't want to tell users
|
||||||
|
// about account status unless they presented the correct credentials
|
||||||
|
try {
|
||||||
|
additionalAuthenticationChecks(user,
|
||||||
|
(UsernamePasswordAuthenticationToken) authentication);
|
||||||
|
} catch (AuthenticationException exception) {
|
||||||
|
// There was a problem, so try again after checking we're using latest data
|
||||||
|
cacheWasUsed = false;
|
||||||
|
user = retrieveUser(username,
|
||||||
|
(UsernamePasswordAuthenticationToken) authentication);
|
||||||
|
additionalAuthenticationChecks(user,
|
||||||
|
(UsernamePasswordAuthenticationToken) authentication);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user.isCredentialsNonExpired()) {
|
||||||
|
throw new CredentialsExpiredException(messages.getMessage(
|
||||||
|
"AbstractUserDetailsAuthenticationProvider.credentialsExpired",
|
||||||
|
"User credentials have expired"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cacheWasUsed) {
|
||||||
|
this.userCache.putUserInCache(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object principalToReturn = user;
|
||||||
|
|
||||||
|
if (forcePrincipalAsString) {
|
||||||
|
principalToReturn = user.getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
return createSuccessAuthentication(principalToReturn, authentication,
|
||||||
|
user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a successful {@link Authentication} object.
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* Protected so subclasses can override.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* Subclasses will usually store the original credentials the user supplied
|
||||||
|
* (not salted or encoded passwords) in the returned
|
||||||
|
* <code>Authentication</code> object.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param principal that should be the principal in the returned object
|
||||||
|
* (defined by the {@link #isForcePrincipalAsString()} method)
|
||||||
|
* @param authentication that was presented to the
|
||||||
|
* <code>DaoAuthenticationProvider</code> for validation
|
||||||
|
* @param user that was loaded by the <code>AuthenticationDao</code>
|
||||||
|
*
|
||||||
|
* @return the successful authentication token
|
||||||
|
*/
|
||||||
|
protected Authentication createSuccessAuthentication(Object principal,
|
||||||
|
Authentication authentication, UserDetails user) {
|
||||||
|
// Ensure we return the original credentials the user supplied,
|
||||||
|
// so subsequent attempts are successful even with encoded passwords.
|
||||||
|
// Also ensure we return the original getDetails(), so that future
|
||||||
|
// authentication events after cache expiry contain the details
|
||||||
|
UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(principal,
|
||||||
|
authentication.getCredentials(), user.getAuthorities());
|
||||||
|
result.setDetails((authentication.getDetails() != null)
|
||||||
|
? authentication.getDetails() : null);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
protected void doAfterPropertiesSet() throws Exception {}
|
protected void doAfterPropertiesSet() throws Exception {}
|
||||||
|
|
||||||
|
public UserCache getUserCache() {
|
||||||
|
return userCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForcePrincipalAsString() {
|
||||||
|
return forcePrincipalAsString;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows subclasses to actually retrieve the <code>UserDetails</code> from
|
* Allows subclasses to actually retrieve the <code>UserDetails</code> from
|
||||||
* an implementation-specific location, with the option of throwing an
|
* an implementation-specific location, with the option of throwing an
|
||||||
@ -243,38 +279,19 @@ public abstract class AbstractUserDetailsAuthenticationProvider
|
|||||||
UsernamePasswordAuthenticationToken authentication)
|
UsernamePasswordAuthenticationToken authentication)
|
||||||
throws AuthenticationException;
|
throws AuthenticationException;
|
||||||
|
|
||||||
/**
|
public void setForcePrincipalAsString(boolean forcePrincipalAsString) {
|
||||||
* Creates a successful {@link Authentication} object.
|
this.forcePrincipalAsString = forcePrincipalAsString;
|
||||||
*
|
}
|
||||||
* <P>
|
|
||||||
* Protected so subclasses can override.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <P>
|
|
||||||
* Subclasses will usually store the original credentials the user supplied
|
|
||||||
* (not salted or encoded passwords) in the returned
|
|
||||||
* <code>Authentication</code> object.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param principal that should be the principal in the returned object
|
|
||||||
* (defined by the {@link #isForcePrincipalAsString()} method)
|
|
||||||
* @param authentication that was presented to the
|
|
||||||
* <code>DaoAuthenticationProvider</code> for validation
|
|
||||||
* @param user that was loaded by the <code>AuthenticationDao</code>
|
|
||||||
*
|
|
||||||
* @return the successful authentication token
|
|
||||||
*/
|
|
||||||
protected Authentication createSuccessAuthentication(Object principal,
|
|
||||||
Authentication authentication, UserDetails user) {
|
|
||||||
// Ensure we return the original credentials the user supplied,
|
|
||||||
// so subsequent attempts are successful even with encoded passwords.
|
|
||||||
// Also ensure we return the original getDetails(), so that future
|
|
||||||
// authentication events after cache expiry contain the details
|
|
||||||
UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(principal,
|
|
||||||
authentication.getCredentials(), user.getAuthorities());
|
|
||||||
result.setDetails((authentication.getDetails() != null)
|
|
||||||
? authentication.getDetails() : null);
|
|
||||||
|
|
||||||
return result;
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserCache(UserCache userCache) {
|
||||||
|
this.userCache = userCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supports(Class authentication) {
|
||||||
|
return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import org.acegisecurity.AuthenticationException;
|
|||||||
import org.acegisecurity.AuthenticationServiceException;
|
import org.acegisecurity.AuthenticationServiceException;
|
||||||
import org.acegisecurity.BadCredentialsException;
|
import org.acegisecurity.BadCredentialsException;
|
||||||
import org.acegisecurity.UserDetails;
|
import org.acegisecurity.UserDetails;
|
||||||
|
|
||||||
import org.acegisecurity.providers.AuthenticationProvider;
|
import org.acegisecurity.providers.AuthenticationProvider;
|
||||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
import org.acegisecurity.providers.encoding.PasswordEncoder;
|
import org.acegisecurity.providers.encoding.PasswordEncoder;
|
||||||
@ -32,9 +33,6 @@ import org.springframework.util.Assert;
|
|||||||
/**
|
/**
|
||||||
* An {@link AuthenticationProvider} implementation that retrieves user details
|
* An {@link AuthenticationProvider} implementation that retrieves user details
|
||||||
* from an {@link AuthenticationDao}.
|
* from an {@link AuthenticationDao}.
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class DaoAuthenticationProvider
|
public class DaoAuthenticationProvider
|
||||||
extends AbstractUserDetailsAuthenticationProvider {
|
extends AbstractUserDetailsAuthenticationProvider {
|
||||||
@ -47,68 +45,6 @@ public class DaoAuthenticationProvider
|
|||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
|
|
||||||
this.authenticationDao = authenticationDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationDao getAuthenticationDao() {
|
|
||||||
return authenticationDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default the <code>DaoAuthenticationProvider</code> throws a
|
|
||||||
* <code>BadCredentialsException</code> if a username is not found or the
|
|
||||||
* password is incorrect. Setting this property to <code>false</code> will
|
|
||||||
* cause <code>UsernameNotFoundException</code>s to be thrown instead for
|
|
||||||
* the former. Note this is considered less secure than throwing
|
|
||||||
* <code>BadCredentialsException</code> for both exceptions.
|
|
||||||
*
|
|
||||||
* @param hideUserNotFoundExceptions set to <code>false</code> if you wish
|
|
||||||
* <code>UsernameNotFoundException</code>s to be thrown instead of
|
|
||||||
* the non-specific <code>BadCredentialsException</code> (defaults
|
|
||||||
* to <code>true</code>)
|
|
||||||
*/
|
|
||||||
public void setHideUserNotFoundExceptions(
|
|
||||||
boolean hideUserNotFoundExceptions) {
|
|
||||||
this.hideUserNotFoundExceptions = hideUserNotFoundExceptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isHideUserNotFoundExceptions() {
|
|
||||||
return hideUserNotFoundExceptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the PasswordEncoder instance to be used to encode and validate
|
|
||||||
* passwords. If not set, {@link PlaintextPasswordEncoder} will be used by
|
|
||||||
* default.
|
|
||||||
*
|
|
||||||
* @param passwordEncoder The passwordEncoder to use
|
|
||||||
*/
|
|
||||||
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
|
|
||||||
this.passwordEncoder = passwordEncoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PasswordEncoder getPasswordEncoder() {
|
|
||||||
return passwordEncoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The source of salts to use when decoding passwords. <code>null</code>
|
|
||||||
* is a valid value, meaning the <code>DaoAuthenticationProvider</code>
|
|
||||||
* will present <code>null</code> to the relevant
|
|
||||||
* <code>PasswordEncoder</code>.
|
|
||||||
*
|
|
||||||
* @param saltSource to use when attempting to decode passwords via the
|
|
||||||
* <code>PasswordEncoder</code>
|
|
||||||
*/
|
|
||||||
public void setSaltSource(SaltSource saltSource) {
|
|
||||||
this.saltSource = saltSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SaltSource getSaltSource() {
|
|
||||||
return saltSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void additionalAuthenticationChecks(UserDetails userDetails,
|
protected void additionalAuthenticationChecks(UserDetails userDetails,
|
||||||
UsernamePasswordAuthenticationToken authentication)
|
UsernamePasswordAuthenticationToken authentication)
|
||||||
throws AuthenticationException {
|
throws AuthenticationException {
|
||||||
@ -120,7 +56,9 @@ public class DaoAuthenticationProvider
|
|||||||
|
|
||||||
if (!passwordEncoder.isPasswordValid(userDetails.getPassword(),
|
if (!passwordEncoder.isPasswordValid(userDetails.getPassword(),
|
||||||
authentication.getCredentials().toString(), salt)) {
|
authentication.getCredentials().toString(), salt)) {
|
||||||
throw new BadCredentialsException("Bad credentials", userDetails);
|
throw new BadCredentialsException(messages.getMessage(
|
||||||
|
"AbstractUserDetailsAuthenticationProvider.badCredentials",
|
||||||
|
"Bad credentials"), userDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,6 +67,22 @@ public class DaoAuthenticationProvider
|
|||||||
"An Authentication DAO must be set");
|
"An Authentication DAO must be set");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AuthenticationDao getAuthenticationDao() {
|
||||||
|
return authenticationDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PasswordEncoder getPasswordEncoder() {
|
||||||
|
return passwordEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SaltSource getSaltSource() {
|
||||||
|
return saltSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHideUserNotFoundExceptions() {
|
||||||
|
return hideUserNotFoundExceptions;
|
||||||
|
}
|
||||||
|
|
||||||
protected final UserDetails retrieveUser(String username,
|
protected final UserDetails retrieveUser(String username,
|
||||||
UsernamePasswordAuthenticationToken authentication)
|
UsernamePasswordAuthenticationToken authentication)
|
||||||
throws AuthenticationException {
|
throws AuthenticationException {
|
||||||
@ -138,7 +92,9 @@ public class DaoAuthenticationProvider
|
|||||||
loadedUser = this.authenticationDao.loadUserByUsername(username);
|
loadedUser = this.authenticationDao.loadUserByUsername(username);
|
||||||
} catch (UsernameNotFoundException notFound) {
|
} catch (UsernameNotFoundException notFound) {
|
||||||
if (hideUserNotFoundExceptions) {
|
if (hideUserNotFoundExceptions) {
|
||||||
throw new BadCredentialsException("Bad credentials presented");
|
throw new BadCredentialsException(messages.getMessage(
|
||||||
|
"AbstractUserDetailsAuthenticationProvider.badCredentials",
|
||||||
|
"Bad credentials"));
|
||||||
} else {
|
} else {
|
||||||
throw notFound;
|
throw notFound;
|
||||||
}
|
}
|
||||||
@ -154,4 +110,52 @@ public class DaoAuthenticationProvider
|
|||||||
|
|
||||||
return loadedUser;
|
return loadedUser;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
|
||||||
|
this.authenticationDao = authenticationDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default the <code>DaoAuthenticationProvider</code> throws a
|
||||||
|
* <code>BadCredentialsException</code> if a username is not found or
|
||||||
|
* the password is incorrect. Setting this property to
|
||||||
|
* <code>false</code> will cause
|
||||||
|
* <code>UsernameNotFoundException</code>s to be thrown instead for
|
||||||
|
* the former. Note this is considered less secure than throwing
|
||||||
|
* <code>BadCredentialsException</code> for both exceptions.
|
||||||
|
*
|
||||||
|
* @param hideUserNotFoundExceptions set to <code>false</code> if you
|
||||||
|
* wish <code>UsernameNotFoundException</code>s to be thrown
|
||||||
|
* instead of the non-specific
|
||||||
|
* <code>BadCredentialsException</code> (defaults to
|
||||||
|
* <code>true</code>)
|
||||||
|
*/
|
||||||
|
public void setHideUserNotFoundExceptions(
|
||||||
|
boolean hideUserNotFoundExceptions) {
|
||||||
|
this.hideUserNotFoundExceptions = hideUserNotFoundExceptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the PasswordEncoder instance to be used to encode and validate
|
||||||
|
* passwords. If not set, {@link PlaintextPasswordEncoder} will be
|
||||||
|
* used by default.
|
||||||
|
*
|
||||||
|
* @param passwordEncoder The passwordEncoder to use
|
||||||
|
*/
|
||||||
|
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
|
||||||
|
this.passwordEncoder = passwordEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The source of salts to use when decoding passwords.
|
||||||
|
* <code>null</code> is a valid value, meaning the
|
||||||
|
* <code>DaoAuthenticationProvider</code> will present
|
||||||
|
* <code>null</code> to the relevant <code>PasswordEncoder</code>.
|
||||||
|
*
|
||||||
|
* @param saltSource to use when attempting to decode passwords via the
|
||||||
|
* <code>PasswordEncoder</code>
|
||||||
|
*/
|
||||||
|
public void setSaltSource(SaltSource saltSource) {
|
||||||
|
this.saltSource = saltSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,6 +18,7 @@ package org.acegisecurity.providers.rememberme;
|
|||||||
import org.acegisecurity.Authentication;
|
import org.acegisecurity.Authentication;
|
||||||
import org.acegisecurity.AuthenticationException;
|
import org.acegisecurity.AuthenticationException;
|
||||||
import org.acegisecurity.BadCredentialsException;
|
import org.acegisecurity.BadCredentialsException;
|
||||||
|
|
||||||
import org.acegisecurity.providers.AuthenticationProvider;
|
import org.acegisecurity.providers.AuthenticationProvider;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@ -25,6 +26,10 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
|
||||||
@ -37,32 +42,23 @@ import org.springframework.util.Assert;
|
|||||||
* org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken#getKeyHash()}
|
* org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken#getKeyHash()}
|
||||||
* must match this class' {@link #getKey()}.
|
* must match this class' {@link #getKey()}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class RememberMeAuthenticationProvider implements AuthenticationProvider,
|
public class RememberMeAuthenticationProvider implements AuthenticationProvider,
|
||||||
InitializingBean {
|
InitializingBean, MessageSourceAware {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(RememberMeAuthenticationProvider.class);
|
private static final Log logger = LogFactory.getLog(RememberMeAuthenticationProvider.class);
|
||||||
|
|
||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private String key;
|
private String key;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setKey(String key) {
|
|
||||||
this.key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.hasLength(key);
|
Assert.hasLength(key);
|
||||||
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Authentication authenticate(Authentication authentication)
|
public Authentication authenticate(Authentication authentication)
|
||||||
@ -73,13 +69,26 @@ public class RememberMeAuthenticationProvider implements AuthenticationProvider,
|
|||||||
|
|
||||||
if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication)
|
if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication)
|
||||||
.getKeyHash()) {
|
.getKeyHash()) {
|
||||||
throw new BadCredentialsException(
|
throw new BadCredentialsException(messages.getMessage(
|
||||||
"The presented RememberMeAuthenticationToken does not contain the expected key");
|
"RememberMeAuthenticationProvider.incorrectKey",
|
||||||
|
"The presented RememberMeAuthenticationToken does not contain the expected key"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return authentication;
|
return authentication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean supports(Class authentication) {
|
public boolean supports(Class authentication) {
|
||||||
return (RememberMeAuthenticationToken.class.isAssignableFrom(authentication));
|
return (RememberMeAuthenticationToken.class.isAssignableFrom(authentication));
|
||||||
}
|
}
|
||||||
|
@ -15,71 +15,81 @@
|
|||||||
|
|
||||||
package org.acegisecurity.providers.x509;
|
package org.acegisecurity.providers.x509;
|
||||||
|
|
||||||
import org.acegisecurity.providers.AuthenticationProvider;
|
|
||||||
import org.acegisecurity.providers.x509.cache.NullX509UserCache;
|
|
||||||
import org.acegisecurity.Authentication;
|
import org.acegisecurity.Authentication;
|
||||||
import org.acegisecurity.AuthenticationException;
|
import org.acegisecurity.AuthenticationException;
|
||||||
import org.acegisecurity.UserDetails;
|
|
||||||
import org.acegisecurity.BadCredentialsException;
|
import org.acegisecurity.BadCredentialsException;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.acegisecurity.UserDetails;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
import org.acegisecurity.providers.AuthenticationProvider;
|
||||||
|
import org.acegisecurity.providers.x509.cache.NullX509UserCache;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes an X.509 authentication request.
|
* Processes an X.509 authentication request.
|
||||||
* <p>
|
|
||||||
* The request will typically originate from
|
|
||||||
* {@link org.acegisecurity.ui.x509.X509ProcessingFilter}).
|
|
||||||
* </p>
|
|
||||||
*
|
*
|
||||||
* @author Luke Taylor
|
* <p>
|
||||||
* @version $Id$
|
* The request will typically originate from {@link
|
||||||
|
* org.acegisecurity.ui.x509.X509ProcessingFilter}).
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class X509AuthenticationProvider implements AuthenticationProvider,
|
public class X509AuthenticationProvider implements AuthenticationProvider,
|
||||||
InitializingBean {
|
InitializingBean, MessageSourceAware {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(X509AuthenticationProvider.class);
|
private static final Log logger = LogFactory.getLog(X509AuthenticationProvider.class);
|
||||||
|
|
||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private X509AuthoritiesPopulator x509AuthoritiesPopulator;
|
private X509AuthoritiesPopulator x509AuthoritiesPopulator;
|
||||||
private X509UserCache userCache = new NullX509UserCache();
|
private X509UserCache userCache = new NullX509UserCache();
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setX509AuthoritiesPopulator(X509AuthoritiesPopulator x509AuthoritiesPopulator) {
|
|
||||||
this.x509AuthoritiesPopulator = x509AuthoritiesPopulator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setX509UserCache(X509UserCache cache) {
|
|
||||||
this.userCache = cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(userCache, "An x509UserCache must be set");
|
Assert.notNull(userCache, "An x509UserCache must be set");
|
||||||
Assert.notNull(x509AuthoritiesPopulator, "An X509AuthoritiesPopulator must be set");
|
Assert.notNull(x509AuthoritiesPopulator,
|
||||||
|
"An X509AuthoritiesPopulator must be set");
|
||||||
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the supplied authentication token contains a certificate then this will be passed
|
* If the supplied authentication token contains a certificate then this
|
||||||
* to the configured {@link X509AuthoritiesPopulator}
|
* will be passed to the configured {@link X509AuthoritiesPopulator} to
|
||||||
* to obtain the user details and authorities for the user identified by the certificate.
|
* obtain the user details and authorities for the user identified by the
|
||||||
|
* certificate.
|
||||||
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* If no certificate is present (for example, if the filter is applied to an HttpRequest for which
|
* If no certificate is present (for example, if the filter is applied to
|
||||||
* client authentication hasn't been configured in the container) then a BadCredentialsException will be raised.
|
* an HttpRequest for which client authentication hasn't been configured
|
||||||
|
* in the container) then a BadCredentialsException will be raised.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param authentication the authentication request.
|
* @param authentication the authentication request.
|
||||||
* @return an X509AuthenticationToken containing the authorities of the principal represented by the
|
*
|
||||||
* certificate.
|
* @return an X509AuthenticationToken containing the authorities of the
|
||||||
* @throws AuthenticationException if the {@link X509AuthoritiesPopulator} rejects the certficate.
|
* principal represented by the certificate.
|
||||||
* @throws BadCredentialsException if no certificate was presented in the authentication request.
|
*
|
||||||
|
* @throws AuthenticationException if the {@link X509AuthoritiesPopulator}
|
||||||
|
* rejects the certficate.
|
||||||
|
* @throws BadCredentialsException if no certificate was presented in the
|
||||||
|
* authentication request.
|
||||||
*/
|
*/
|
||||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
public Authentication authenticate(Authentication authentication)
|
||||||
|
throws AuthenticationException {
|
||||||
if (!supports(authentication.getClass())) {
|
if (!supports(authentication.getClass())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -88,25 +98,42 @@ public class X509AuthenticationProvider implements AuthenticationProvider,
|
|||||||
logger.debug("X509 authentication request: " + authentication);
|
logger.debug("X509 authentication request: " + authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
X509Certificate clientCertificate = (X509Certificate)authentication.getCredentials();
|
X509Certificate clientCertificate = (X509Certificate) authentication
|
||||||
|
.getCredentials();
|
||||||
|
|
||||||
if(clientCertificate == null) {
|
if (clientCertificate == null) {
|
||||||
throw new BadCredentialsException("Certificate is null.");
|
throw new BadCredentialsException(messages.getMessage(
|
||||||
|
"X509AuthenticationProvider.certificateNull",
|
||||||
|
"Certificate is null"));
|
||||||
}
|
}
|
||||||
|
|
||||||
UserDetails user = userCache.getUserFromCache(clientCertificate);
|
UserDetails user = userCache.getUserFromCache(clientCertificate);
|
||||||
|
|
||||||
if(user == null) {
|
if (user == null) {
|
||||||
logger.debug("Authenticating with certificate " + clientCertificate);
|
logger.debug("Authenticating with certificate "
|
||||||
|
+ clientCertificate);
|
||||||
user = x509AuthoritiesPopulator.getUserDetails(clientCertificate);
|
user = x509AuthoritiesPopulator.getUserDetails(clientCertificate);
|
||||||
userCache.putUserInCache(clientCertificate, user);
|
userCache.putUserInCache(clientCertificate, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new X509AuthenticationToken(user, clientCertificate, user.getAuthorities());
|
return new X509AuthenticationToken(user, clientCertificate,
|
||||||
|
user.getAuthorities());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX509AuthoritiesPopulator(
|
||||||
|
X509AuthoritiesPopulator x509AuthoritiesPopulator) {
|
||||||
|
this.x509AuthoritiesPopulator = x509AuthoritiesPopulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setX509UserCache(X509UserCache cache) {
|
||||||
|
this.userCache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supports(Class authentication) {
|
public boolean supports(Class authentication) {
|
||||||
return X509AuthenticationToken.class.isAssignableFrom(authentication);
|
return X509AuthenticationToken.class.isAssignableFrom(authentication);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -16,29 +16,34 @@
|
|||||||
package org.acegisecurity.providers.x509.populator;
|
package org.acegisecurity.providers.x509.populator;
|
||||||
|
|
||||||
import org.acegisecurity.AuthenticationException;
|
import org.acegisecurity.AuthenticationException;
|
||||||
import org.acegisecurity.UserDetails;
|
|
||||||
import org.acegisecurity.BadCredentialsException;
|
import org.acegisecurity.BadCredentialsException;
|
||||||
|
import org.acegisecurity.UserDetails;
|
||||||
|
|
||||||
import org.acegisecurity.providers.dao.AuthenticationDao;
|
import org.acegisecurity.providers.dao.AuthenticationDao;
|
||||||
import org.acegisecurity.providers.x509.X509AuthoritiesPopulator;
|
import org.acegisecurity.providers.x509.X509AuthoritiesPopulator;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.apache.oro.text.regex.*;
|
import org.apache.oro.text.regex.*;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populates the X509 authorities via an {@link org.acegisecurity.providers.dao.AuthenticationDao}.
|
* Populates the X509 authorities via an {@link
|
||||||
*
|
* org.acegisecurity.providers.dao.AuthenticationDao}.
|
||||||
* @author Luke Taylor
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator,
|
public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator,
|
||||||
InitializingBean {
|
InitializingBean, MessageSourceAware {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(DaoX509AuthoritiesPopulator.class);
|
private static final Log logger = LogFactory.getLog(DaoX509AuthoritiesPopulator.class);
|
||||||
@ -46,18 +51,64 @@ public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator,
|
|||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
private AuthenticationDao authenticationDao;
|
private AuthenticationDao authenticationDao;
|
||||||
private String subjectDNRegex = "CN=(.*?),";
|
protected MessageSourceAccessor messages;
|
||||||
private Pattern subjectDNPattern;
|
private Pattern subjectDNPattern;
|
||||||
|
private String subjectDNRegex = "CN=(.*?),";
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
|
public void afterPropertiesSet() throws Exception {
|
||||||
|
Assert.notNull(authenticationDao, "An authenticationDao must be set");
|
||||||
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
|
|
||||||
|
Perl5Compiler compiler = new Perl5Compiler();
|
||||||
|
|
||||||
|
try {
|
||||||
|
subjectDNPattern = compiler.compile(subjectDNRegex,
|
||||||
|
Perl5Compiler.READ_ONLY_MASK
|
||||||
|
| Perl5Compiler.CASE_INSENSITIVE_MASK);
|
||||||
|
} catch (MalformedPatternException mpe) {
|
||||||
|
throw new IllegalArgumentException("Malformed regular expression: "
|
||||||
|
+ subjectDNRegex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserDetails getUserDetails(X509Certificate clientCert)
|
||||||
|
throws AuthenticationException {
|
||||||
|
String subjectDN = clientCert.getSubjectDN().getName();
|
||||||
|
PatternMatcher matcher = new Perl5Matcher();
|
||||||
|
|
||||||
|
if (!matcher.contains(subjectDN, subjectDNPattern)) {
|
||||||
|
throw new BadCredentialsException(messages.getMessage(
|
||||||
|
"DaoX509AuthoritiesPopulator.noMatching",
|
||||||
|
new Object[] {subjectDN},
|
||||||
|
"No matching pattern was found in subjectDN: {0}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
MatchResult match = matcher.getMatch();
|
||||||
|
|
||||||
|
if (match.groups() != 2) { // 2 = 1 + the entire match
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Regular expression must contain a single group ");
|
||||||
|
}
|
||||||
|
|
||||||
|
String userName = match.group(1);
|
||||||
|
|
||||||
|
return this.authenticationDao.loadUserByUsername(userName);
|
||||||
|
}
|
||||||
|
|
||||||
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
|
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
|
||||||
this.authenticationDao = authenticationDao;
|
this.authenticationDao = authenticationDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the regular expression which will by used to extract the user name
|
* Sets the regular expression which will by used to extract the user name
|
||||||
* from the certificate's Subject DN.
|
* from the certificate's Subject DN.
|
||||||
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* It should contain a single group; for example the default expression
|
* It should contain a single group; for example the default expression
|
||||||
* "CN=(.*?)," matches the common name field. So "CN=Jimi Hendrix, OU=..."
|
* "CN=(.*?)," matches the common name field. So "CN=Jimi Hendrix, OU=..."
|
||||||
@ -73,36 +124,4 @@ public class DaoX509AuthoritiesPopulator implements X509AuthoritiesPopulator,
|
|||||||
public void setSubjectDNRegex(String subjectDNRegex) {
|
public void setSubjectDNRegex(String subjectDNRegex) {
|
||||||
this.subjectDNRegex = subjectDNRegex;
|
this.subjectDNRegex = subjectDNRegex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserDetails getUserDetails(X509Certificate clientCert)
|
|
||||||
throws AuthenticationException {
|
|
||||||
|
|
||||||
String subjectDN = clientCert.getSubjectDN().getName();
|
|
||||||
PatternMatcher matcher = new Perl5Matcher();
|
|
||||||
|
|
||||||
if(!matcher.contains(subjectDN , subjectDNPattern)) {
|
|
||||||
throw new BadCredentialsException("No matching pattern was found in subjectDN: " + subjectDN);
|
|
||||||
}
|
|
||||||
|
|
||||||
MatchResult match = matcher.getMatch();
|
|
||||||
if(match.groups() != 2) { // 2 = 1 + the entire match
|
|
||||||
throw new IllegalArgumentException("Regular expression must contain a single group ");
|
|
||||||
}
|
|
||||||
String userName = match.group(1);
|
|
||||||
|
|
||||||
return this.authenticationDao.loadUserByUsername(userName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
|
||||||
Assert.notNull(authenticationDao, "An authenticationDao must be set");
|
|
||||||
|
|
||||||
Perl5Compiler compiler = new Perl5Compiler();
|
|
||||||
|
|
||||||
try {
|
|
||||||
subjectDNPattern = compiler.compile(subjectDNRegex,
|
|
||||||
Perl5Compiler.READ_ONLY_MASK | Perl5Compiler.CASE_INSENSITIVE_MASK);
|
|
||||||
} catch (MalformedPatternException mpe) {
|
|
||||||
throw new IllegalArgumentException("Malformed regular expression: " + subjectDNRegex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -18,9 +18,15 @@ package org.acegisecurity.runas;
|
|||||||
import org.acegisecurity.Authentication;
|
import org.acegisecurity.Authentication;
|
||||||
import org.acegisecurity.AuthenticationException;
|
import org.acegisecurity.AuthenticationException;
|
||||||
import org.acegisecurity.BadCredentialsException;
|
import org.acegisecurity.BadCredentialsException;
|
||||||
|
|
||||||
import org.acegisecurity.providers.AuthenticationProvider;
|
import org.acegisecurity.providers.AuthenticationProvider;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
|
||||||
@ -38,28 +44,19 @@ import org.springframework.util.Assert;
|
|||||||
* <P>
|
* <P>
|
||||||
* If the key does not match, a <code>BadCredentialsException</code> is thrown.
|
* If the key does not match, a <code>BadCredentialsException</code> is thrown.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class RunAsImplAuthenticationProvider implements InitializingBean,
|
public class RunAsImplAuthenticationProvider implements InitializingBean,
|
||||||
AuthenticationProvider {
|
AuthenticationProvider, MessageSourceAware {
|
||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private String key;
|
private String key;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setKey(String key) {
|
|
||||||
this.key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(key, "A Key is required and should match that configured for the RunAsManagerImpl");
|
Assert.notNull(key,
|
||||||
|
"A Key is required and should match that configured for the RunAsManagerImpl");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Authentication authenticate(Authentication authentication)
|
public Authentication authenticate(Authentication authentication)
|
||||||
@ -69,11 +66,24 @@ public class RunAsImplAuthenticationProvider implements InitializingBean,
|
|||||||
if (token.getKeyHash() == key.hashCode()) {
|
if (token.getKeyHash() == key.hashCode()) {
|
||||||
return authentication;
|
return authentication;
|
||||||
} else {
|
} else {
|
||||||
throw new BadCredentialsException(
|
throw new BadCredentialsException(messages.getMessage(
|
||||||
"The presented RunAsUserToken does not contain the expected key");
|
"RunAsImplAuthenticationProvider.incorrectKey",
|
||||||
|
"The presented RunAsUserToken does not contain the expected key"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean supports(Class authentication) {
|
public boolean supports(Class authentication) {
|
||||||
if (RunAsUserToken.class.isAssignableFrom(authentication)) {
|
if (RunAsUserToken.class.isAssignableFrom(authentication)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -15,7 +15,32 @@
|
|||||||
|
|
||||||
package org.acegisecurity.ui;
|
package org.acegisecurity.ui;
|
||||||
|
|
||||||
|
import org.acegisecurity.Authentication;
|
||||||
|
import org.acegisecurity.AuthenticationException;
|
||||||
|
import org.acegisecurity.AuthenticationManager;
|
||||||
|
|
||||||
|
import org.acegisecurity.context.SecurityContextHolder;
|
||||||
|
|
||||||
|
import org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent;
|
||||||
|
|
||||||
|
import org.acegisecurity.ui.rememberme.NullRememberMeServices;
|
||||||
|
import org.acegisecurity.ui.rememberme.RememberMeServices;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.context.ApplicationEventPublisherAware;
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.servlet.Filter;
|
import javax.servlet.Filter;
|
||||||
@ -27,21 +52,6 @@ import javax.servlet.ServletResponse;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.acegisecurity.Authentication;
|
|
||||||
import org.acegisecurity.AuthenticationException;
|
|
||||||
import org.acegisecurity.AuthenticationManager;
|
|
||||||
import org.acegisecurity.context.SecurityContextHolder;
|
|
||||||
import org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent;
|
|
||||||
import org.acegisecurity.ui.rememberme.NullRememberMeServices;
|
|
||||||
import org.acegisecurity.ui.rememberme.RememberMeServices;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
|
||||||
import org.springframework.context.ApplicationEventPublisherAware;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract processor of browser-based HTTP-based authentication requests.
|
* Abstract processor of browser-based HTTP-based authentication requests.
|
||||||
@ -115,20 +125,16 @@ import org.springframework.util.Assert;
|
|||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* If authentication is successful, an {@link
|
* If authentication is successful, an {@link
|
||||||
* org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent} will be
|
* org.acegisecurity.event.authentication.InteractiveAuthenticationSuccessEvent}
|
||||||
* published to the application context. No events will be published if
|
* will be published to the application context. No events will be published
|
||||||
* authentication was unsuccessful, because this would generally be recorded
|
* if authentication was unsuccessful, because this would generally be
|
||||||
* via an <code>AuthenticationManager</code>-specific application event.
|
* recorded via an <code>AuthenticationManager</code>-specific application
|
||||||
|
* event.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @author colin sampaleanu
|
|
||||||
* @author Ray Krueger
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractProcessingFilter implements Filter,
|
public abstract class AbstractProcessingFilter implements Filter,
|
||||||
InitializingBean, ApplicationEventPublisherAware {
|
InitializingBean, ApplicationEventPublisherAware, MessageSourceAware {
|
||||||
//~ Static fields/initializersApplicationContextAware =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
public static final String ACEGI_SECURITY_TARGET_URL_KEY = "ACEGI_SECURITY_TARGET_URL";
|
public static final String ACEGI_SECURITY_TARGET_URL_KEY = "ACEGI_SECURITY_TARGET_URL";
|
||||||
public static final String ACEGI_SECURITY_LAST_EXCEPTION_KEY = "ACEGI_SECURITY_LAST_EXCEPTION";
|
public static final String ACEGI_SECURITY_LAST_EXCEPTION_KEY = "ACEGI_SECURITY_LAST_EXCEPTION";
|
||||||
@ -138,6 +144,7 @@ public abstract class AbstractProcessingFilter implements Filter,
|
|||||||
|
|
||||||
private ApplicationEventPublisher eventPublisher;
|
private ApplicationEventPublisher eventPublisher;
|
||||||
private AuthenticationManager authenticationManager;
|
private AuthenticationManager authenticationManager;
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private Properties exceptionMappings = new Properties();
|
private Properties exceptionMappings = new Properties();
|
||||||
private RememberMeServices rememberMeServices = new NullRememberMeServices();
|
private RememberMeServices rememberMeServices = new NullRememberMeServices();
|
||||||
|
|
||||||
@ -173,65 +180,15 @@ public abstract class AbstractProcessingFilter implements Filter,
|
|||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setAlwaysUseDefaultTargetUrl(boolean alwaysUseDefaultTargetUrl) {
|
public void afterPropertiesSet() throws Exception {
|
||||||
this.alwaysUseDefaultTargetUrl = alwaysUseDefaultTargetUrl;
|
Assert.hasLength(filterProcessesUrl,
|
||||||
}
|
"filterProcessesUrl must be specified");
|
||||||
|
Assert.hasLength(defaultTargetUrl, "defaultTargetUrl must be specified");
|
||||||
public boolean isAlwaysUseDefaultTargetUrl() {
|
Assert.hasLength(authenticationFailureUrl,
|
||||||
return alwaysUseDefaultTargetUrl;
|
"authenticationFailureUrl must be specified");
|
||||||
}
|
Assert.notNull(authenticationManager,
|
||||||
|
"authenticationManager must be specified");
|
||||||
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
|
Assert.notNull(this.rememberMeServices);
|
||||||
this.eventPublisher = eventPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContinueChainBeforeSuccessfulAuthentication(
|
|
||||||
boolean continueChainBeforeSuccessfulAuthentication) {
|
|
||||||
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isContinueChainBeforeSuccessfulAuthentication() {
|
|
||||||
return continueChainBeforeSuccessfulAuthentication;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the default <code>filterProcessesUrl</code> for the
|
|
||||||
* implementation.
|
|
||||||
*
|
|
||||||
* @return the default <code>filterProcessesUrl</code>
|
|
||||||
*/
|
|
||||||
public abstract String getDefaultFilterProcessesUrl();
|
|
||||||
|
|
||||||
public void setDefaultTargetUrl(String defaultTargetUrl) {
|
|
||||||
this.defaultTargetUrl = defaultTargetUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDefaultTargetUrl() {
|
|
||||||
return defaultTargetUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setExceptionMappings(Properties exceptionMappings) {
|
|
||||||
this.exceptionMappings = exceptionMappings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Properties getExceptionMappings() {
|
|
||||||
return new Properties(exceptionMappings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFilterProcessesUrl(String filterProcessesUrl) {
|
|
||||||
this.filterProcessesUrl = filterProcessesUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFilterProcessesUrl() {
|
|
||||||
return filterProcessesUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRememberMeServices(RememberMeServices rememberMeServices) {
|
|
||||||
this.rememberMeServices = rememberMeServices;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RememberMeServices getRememberMeServices() {
|
|
||||||
return rememberMeServices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -247,34 +204,6 @@ public abstract class AbstractProcessingFilter implements Filter,
|
|||||||
public abstract Authentication attemptAuthentication(
|
public abstract Authentication attemptAuthentication(
|
||||||
HttpServletRequest request) throws AuthenticationException;
|
HttpServletRequest request) throws AuthenticationException;
|
||||||
|
|
||||||
public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
|
|
||||||
this.authenticationFailureUrl = authenticationFailureUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthenticationFailureUrl() {
|
|
||||||
return authenticationFailureUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthenticationManager(
|
|
||||||
AuthenticationManager authenticationManager) {
|
|
||||||
this.authenticationManager = authenticationManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationManager getAuthenticationManager() {
|
|
||||||
return authenticationManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
|
||||||
Assert.hasLength(filterProcessesUrl,
|
|
||||||
"filterProcessesUrl must be specified");
|
|
||||||
Assert.hasLength(defaultTargetUrl, "defaultTargetUrl must be specified");
|
|
||||||
Assert.hasLength(authenticationFailureUrl,
|
|
||||||
"authenticationFailureUrl must be specified");
|
|
||||||
Assert.notNull(authenticationManager,
|
|
||||||
"authenticationManager must be specified");
|
|
||||||
Assert.notNull(this.rememberMeServices);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does nothing. We use IoC container lifecycle services instead.
|
* Does nothing. We use IoC container lifecycle services instead.
|
||||||
*/
|
*/
|
||||||
@ -324,6 +253,38 @@ public abstract class AbstractProcessingFilter implements Filter,
|
|||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAuthenticationFailureUrl() {
|
||||||
|
return authenticationFailureUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AuthenticationManager getAuthenticationManager() {
|
||||||
|
return authenticationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the default <code>filterProcessesUrl</code> for the
|
||||||
|
* implementation.
|
||||||
|
*
|
||||||
|
* @return the default <code>filterProcessesUrl</code>
|
||||||
|
*/
|
||||||
|
public abstract String getDefaultFilterProcessesUrl();
|
||||||
|
|
||||||
|
public String getDefaultTargetUrl() {
|
||||||
|
return defaultTargetUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Properties getExceptionMappings() {
|
||||||
|
return new Properties(exceptionMappings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilterProcessesUrl() {
|
||||||
|
return filterProcessesUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RememberMeServices getRememberMeServices() {
|
||||||
|
return rememberMeServices;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does nothing. We use IoC container lifecycle services instead.
|
* Does nothing. We use IoC container lifecycle services instead.
|
||||||
*
|
*
|
||||||
@ -333,6 +294,14 @@ public abstract class AbstractProcessingFilter implements Filter,
|
|||||||
*/
|
*/
|
||||||
public void init(FilterConfig arg0) throws ServletException {}
|
public void init(FilterConfig arg0) throws ServletException {}
|
||||||
|
|
||||||
|
public boolean isAlwaysUseDefaultTargetUrl() {
|
||||||
|
return alwaysUseDefaultTargetUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isContinueChainBeforeSuccessfulAuthentication() {
|
||||||
|
return continueChainBeforeSuccessfulAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
protected void onPreAuthentication(HttpServletRequest request,
|
protected void onPreAuthentication(HttpServletRequest request,
|
||||||
HttpServletResponse response) throws IOException {}
|
HttpServletResponse response) throws IOException {}
|
||||||
|
|
||||||
@ -380,6 +349,49 @@ public abstract class AbstractProcessingFilter implements Filter,
|
|||||||
return uri.endsWith(request.getContextPath() + filterProcessesUrl);
|
return uri.endsWith(request.getContextPath() + filterProcessesUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAlwaysUseDefaultTargetUrl(boolean alwaysUseDefaultTargetUrl) {
|
||||||
|
this.alwaysUseDefaultTargetUrl = alwaysUseDefaultTargetUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApplicationEventPublisher(
|
||||||
|
ApplicationEventPublisher eventPublisher) {
|
||||||
|
this.eventPublisher = eventPublisher;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
|
||||||
|
this.authenticationFailureUrl = authenticationFailureUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAuthenticationManager(
|
||||||
|
AuthenticationManager authenticationManager) {
|
||||||
|
this.authenticationManager = authenticationManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContinueChainBeforeSuccessfulAuthentication(
|
||||||
|
boolean continueChainBeforeSuccessfulAuthentication) {
|
||||||
|
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultTargetUrl(String defaultTargetUrl) {
|
||||||
|
this.defaultTargetUrl = defaultTargetUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExceptionMappings(Properties exceptionMappings) {
|
||||||
|
this.exceptionMappings = exceptionMappings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilterProcessesUrl(String filterProcessesUrl) {
|
||||||
|
this.filterProcessesUrl = filterProcessesUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRememberMeServices(RememberMeServices rememberMeServices) {
|
||||||
|
this.rememberMeServices = rememberMeServices;
|
||||||
|
}
|
||||||
|
|
||||||
protected void successfulAuthentication(HttpServletRequest request,
|
protected void successfulAuthentication(HttpServletRequest request,
|
||||||
HttpServletResponse response, Authentication authResult)
|
HttpServletResponse response, Authentication authResult)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
@ -395,7 +407,8 @@ public abstract class AbstractProcessingFilter implements Filter,
|
|||||||
+ authResult + "'");
|
+ authResult + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
String targetUrl = (String) request.getSession().getAttribute(ACEGI_SECURITY_TARGET_URL_KEY);
|
String targetUrl = (String) request.getSession()
|
||||||
|
.getAttribute(ACEGI_SECURITY_TARGET_URL_KEY);
|
||||||
request.getSession().removeAttribute(ACEGI_SECURITY_TARGET_URL_KEY);
|
request.getSession().removeAttribute(ACEGI_SECURITY_TARGET_URL_KEY);
|
||||||
|
|
||||||
if (alwaysUseDefaultTargetUrl == true) {
|
if (alwaysUseDefaultTargetUrl == true) {
|
||||||
@ -444,8 +457,8 @@ public abstract class AbstractProcessingFilter implements Filter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
request.getSession().setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY,
|
request.getSession()
|
||||||
failed);
|
.setAttribute(ACEGI_SECURITY_LAST_EXCEPTION_KEY, failed);
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {}
|
||||||
|
|
||||||
onUnsuccessfulAuthentication(request, response);
|
onUnsuccessfulAuthentication(request, response);
|
||||||
|
@ -19,13 +19,17 @@ import org.acegisecurity.AuthenticationException;
|
|||||||
import org.acegisecurity.AuthenticationServiceException;
|
import org.acegisecurity.AuthenticationServiceException;
|
||||||
import org.acegisecurity.BadCredentialsException;
|
import org.acegisecurity.BadCredentialsException;
|
||||||
import org.acegisecurity.UserDetails;
|
import org.acegisecurity.UserDetails;
|
||||||
|
|
||||||
import org.acegisecurity.context.SecurityContextHolder;
|
import org.acegisecurity.context.SecurityContextHolder;
|
||||||
|
|
||||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
import org.acegisecurity.providers.dao.AuthenticationDao;
|
import org.acegisecurity.providers.dao.AuthenticationDao;
|
||||||
import org.acegisecurity.providers.dao.UserCache;
|
import org.acegisecurity.providers.dao.UserCache;
|
||||||
import org.acegisecurity.providers.dao.UsernameNotFoundException;
|
import org.acegisecurity.providers.dao.UsernameNotFoundException;
|
||||||
import org.acegisecurity.providers.dao.cache.NullUserCache;
|
import org.acegisecurity.providers.dao.cache.NullUserCache;
|
||||||
|
|
||||||
import org.acegisecurity.ui.WebAuthenticationDetails;
|
import org.acegisecurity.ui.WebAuthenticationDetails;
|
||||||
|
|
||||||
import org.acegisecurity.util.StringSplitUtils;
|
import org.acegisecurity.util.StringSplitUtils;
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
@ -35,6 +39,10 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
@ -72,19 +80,22 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
* <p>
|
* <p>
|
||||||
* This Digest implementation has been designed to avoid needing to store
|
* This Digest implementation has been designed to avoid needing to store
|
||||||
* session state between invocations. All session management information is
|
* session state between invocations. All session management information is
|
||||||
* stored in the "nonce" that is sent to the client by the {@link DigestProcessingFilterEntryPoint}.
|
* stored in the "nonce" that is sent to the client by the {@link
|
||||||
|
* DigestProcessingFilterEntryPoint}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <P>
|
* <P>
|
||||||
* If authentication is successful, the resulting {@link org.acegisecurity.Authentication Authentication}
|
* If authentication is successful, the resulting {@link
|
||||||
* object will be placed into the <code>SecurityContextHolder</code>.
|
* org.acegisecurity.Authentication Authentication} object will be placed into
|
||||||
|
* the <code>SecurityContextHolder</code>.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* If authentication fails, an
|
* If authentication fails, an {@link
|
||||||
* {@link org.acegisecurity.intercept.web.AuthenticationEntryPoint AuthenticationEntryPoint}
|
* org.acegisecurity.intercept.web.AuthenticationEntryPoint
|
||||||
* implementation is called. This must always be {@link DigestProcessingFilterEntryPoint},
|
* AuthenticationEntryPoint} implementation is called. This must always be
|
||||||
* which will prompt the user to authenticate again via Digest authentication.
|
* {@link DigestProcessingFilterEntryPoint}, which will prompt the user to
|
||||||
|
* authenticate again via Digest authentication.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <P>
|
* <P>
|
||||||
@ -100,11 +111,9 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
* <code>web.xml</code> to use the {@link
|
* <code>web.xml</code> to use the {@link
|
||||||
* org.acegisecurity.util.FilterToBeanProxy}.
|
* org.acegisecurity.util.FilterToBeanProxy}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class DigestProcessingFilter implements Filter, InitializingBean {
|
public class DigestProcessingFilter implements Filter, InitializingBean,
|
||||||
|
MessageSourceAware {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(DigestProcessingFilter.class);
|
private static final Log logger = LogFactory.getLog(DigestProcessingFilter.class);
|
||||||
@ -113,32 +122,12 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
|
|
||||||
private AuthenticationDao authenticationDao;
|
private AuthenticationDao authenticationDao;
|
||||||
private DigestProcessingFilterEntryPoint authenticationEntryPoint;
|
private DigestProcessingFilterEntryPoint authenticationEntryPoint;
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private UserCache userCache = new NullUserCache();
|
private UserCache userCache = new NullUserCache();
|
||||||
private boolean passwordAlreadyEncoded = false;
|
private boolean passwordAlreadyEncoded = false;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setPasswordAlreadyEncoded(boolean passwordAlreadyEncoded) {
|
|
||||||
this.passwordAlreadyEncoded = passwordAlreadyEncoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
|
|
||||||
this.authenticationDao = authenticationDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthenticationDao getAuthenticationDao() {
|
|
||||||
return authenticationDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthenticationEntryPoint(
|
|
||||||
DigestProcessingFilterEntryPoint authenticationEntryPoint) {
|
|
||||||
this.authenticationEntryPoint = authenticationEntryPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DigestProcessingFilterEntryPoint getAuthenticationEntryPoint() {
|
|
||||||
return authenticationEntryPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.notNull(authenticationDao, "An AuthenticationDao is required");
|
Assert.notNull(authenticationDao, "An AuthenticationDao is required");
|
||||||
Assert.notNull(authenticationEntryPoint,
|
Assert.notNull(authenticationEntryPoint,
|
||||||
@ -169,8 +158,7 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
if ((header != null) && header.startsWith("Digest ")) {
|
if ((header != null) && header.startsWith("Digest ")) {
|
||||||
String section212response = header.substring(7);
|
String section212response = header.substring(7);
|
||||||
|
|
||||||
String[] headerEntries = StringUtils
|
String[] headerEntries = StringUtils.commaDelimitedListToStringArray(section212response);
|
||||||
.commaDelimitedListToStringArray(section212response);
|
|
||||||
Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries,
|
Map headerMap = StringSplitUtils.splitEachArrayElementAndCreateMap(headerEntries,
|
||||||
"=", "\"");
|
"=", "\"");
|
||||||
|
|
||||||
@ -194,9 +182,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fail(request, response,
|
fail(request, response,
|
||||||
new BadCredentialsException(
|
new BadCredentialsException(messages.getMessage(
|
||||||
"Missing mandatory digest value; received header '"
|
"DigestProcessingFilter.missingMandatory",
|
||||||
+ section212response + "'"));
|
new Object[] {section212response},
|
||||||
|
"Missing mandatory digest value; received header {0}")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -210,9 +199,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fail(request, response,
|
fail(request, response,
|
||||||
new BadCredentialsException(
|
new BadCredentialsException(messages.getMessage(
|
||||||
"Missing mandatory digest value for 'auth' QOP; received header '"
|
"DigestProcessingFilter.missingAuth",
|
||||||
+ section212response + "'"));
|
new Object[] {section212response},
|
||||||
|
"Missing mandatory digest value; received header {0}")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -221,10 +211,11 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
// Check realm name equals what we expected
|
// Check realm name equals what we expected
|
||||||
if (!this.getAuthenticationEntryPoint().getRealmName().equals(realm)) {
|
if (!this.getAuthenticationEntryPoint().getRealmName().equals(realm)) {
|
||||||
fail(request, response,
|
fail(request, response,
|
||||||
new BadCredentialsException("Response realm name '" + realm
|
new BadCredentialsException(messages.getMessage(
|
||||||
+ "' does not match system realm name of '"
|
"DigestProcessingFilter.incorrectRealm",
|
||||||
+ this.getAuthenticationEntryPoint().getRealmName()
|
new Object[] {realm, this.getAuthenticationEntryPoint()
|
||||||
+ "'"));
|
.getRealmName()},
|
||||||
|
"Response realm name '{0}' does not match system realm name of '{1}'")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -232,9 +223,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
// Check nonce was a Base64 encoded (as sent by DigestProcessingFilterEntryPoint)
|
// Check nonce was a Base64 encoded (as sent by DigestProcessingFilterEntryPoint)
|
||||||
if (!Base64.isArrayByteBase64(nonce.getBytes())) {
|
if (!Base64.isArrayByteBase64(nonce.getBytes())) {
|
||||||
fail(request, response,
|
fail(request, response,
|
||||||
new BadCredentialsException(
|
new BadCredentialsException(messages.getMessage(
|
||||||
"Nonce is not encoded in Base64; received nonce: '"
|
"DigestProcessingFilter.nonceEncoding",
|
||||||
+ nonce + "'"));
|
new Object[] {nonce},
|
||||||
|
"Nonce is not encoded in Base64; received nonce {0}")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -249,9 +241,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
|
|
||||||
if (nonceTokens.length != 2) {
|
if (nonceTokens.length != 2) {
|
||||||
fail(request, response,
|
fail(request, response,
|
||||||
new BadCredentialsException(
|
new BadCredentialsException(messages.getMessage(
|
||||||
"Nonce should have yielded two tokens but was: '"
|
"DigestProcessingFilter.nonceNotTwoTokens",
|
||||||
+ nonceAsPlainText + "'"));
|
new Object[] {nonceAsPlainText},
|
||||||
|
"Nonce should have yielded two tokens but was {0}")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -263,9 +256,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
nonceExpiryTime = new Long(nonceTokens[0]).longValue();
|
nonceExpiryTime = new Long(nonceTokens[0]).longValue();
|
||||||
} catch (NumberFormatException nfe) {
|
} catch (NumberFormatException nfe) {
|
||||||
fail(request, response,
|
fail(request, response,
|
||||||
new BadCredentialsException(
|
new BadCredentialsException(messages.getMessage(
|
||||||
"Nonce token should have yielded a numeric first token, but was: '"
|
"DigestProcessingFilter.nonceNotNumeric",
|
||||||
+ nonceAsPlainText + "'"));
|
new Object[] {nonceAsPlainText},
|
||||||
|
"Nonce token should have yielded a numeric first token, but was {0}")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -276,14 +270,17 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
|
|
||||||
if (!expectedNonceSignature.equals(nonceTokens[1])) {
|
if (!expectedNonceSignature.equals(nonceTokens[1])) {
|
||||||
fail(request, response,
|
fail(request, response,
|
||||||
new BadCredentialsException("Nonce token compromised: '"
|
new BadCredentialsException(messages.getMessage(
|
||||||
+ nonceAsPlainText + "'"));
|
"DigestProcessingFilter.nonceCompromised",
|
||||||
|
new Object[] {nonceAsPlainText},
|
||||||
|
"Nonce token compromised {0}")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup password for presented username
|
// Lookup password for presented username
|
||||||
// NB: DAO-provided password MUST be clear text - not encoded/salted
|
// NB: DAO-provided password MUST be clear text - not encoded/salted
|
||||||
|
// (unless this instance's passwordAlreadyEncoded property is 'false')
|
||||||
boolean loadedFromDao = false;
|
boolean loadedFromDao = false;
|
||||||
UserDetails user = userCache.getUserFromCache(username);
|
UserDetails user = userCache.getUserFromCache(username);
|
||||||
|
|
||||||
@ -294,8 +291,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
user = authenticationDao.loadUserByUsername(username);
|
user = authenticationDao.loadUserByUsername(username);
|
||||||
} catch (UsernameNotFoundException notFound) {
|
} catch (UsernameNotFoundException notFound) {
|
||||||
fail(request, response,
|
fail(request, response,
|
||||||
new BadCredentialsException("Username '" + username
|
new BadCredentialsException(messages.getMessage(
|
||||||
+ "' not known"));
|
"DigestProcessingFilter.usernameNotFound",
|
||||||
|
new Object[] {username},
|
||||||
|
"Username {0} not found")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -312,8 +311,8 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
String serverDigestMd5;
|
String serverDigestMd5;
|
||||||
|
|
||||||
// Don't catch IllegalArgumentException (already checked validity)
|
// Don't catch IllegalArgumentException (already checked validity)
|
||||||
serverDigestMd5 = generateDigest(passwordAlreadyEncoded, username, realm,
|
serverDigestMd5 = generateDigest(passwordAlreadyEncoded, username,
|
||||||
user.getPassword(),
|
realm, user.getPassword(),
|
||||||
((HttpServletRequest) request).getMethod(), uri, qop,
|
((HttpServletRequest) request).getMethod(), uri, qop,
|
||||||
nonce, nc, cnonce);
|
nonce, nc, cnonce);
|
||||||
|
|
||||||
@ -329,15 +328,17 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
} catch (UsernameNotFoundException notFound) {
|
} catch (UsernameNotFoundException notFound) {
|
||||||
// Would very rarely happen, as user existed earlier
|
// Would very rarely happen, as user existed earlier
|
||||||
fail(request, response,
|
fail(request, response,
|
||||||
new BadCredentialsException("Username '" + username
|
new BadCredentialsException(messages.getMessage(
|
||||||
+ "' not known"));
|
"DigestProcessingFilter.usernameNotFound",
|
||||||
|
new Object[] {username},
|
||||||
|
"Username {0} not found")));
|
||||||
}
|
}
|
||||||
|
|
||||||
userCache.putUserInCache(user);
|
userCache.putUserInCache(user);
|
||||||
|
|
||||||
// Don't catch IllegalArgumentException (already checked validity)
|
// Don't catch IllegalArgumentException (already checked validity)
|
||||||
serverDigestMd5 = generateDigest(passwordAlreadyEncoded, username, realm,
|
serverDigestMd5 = generateDigest(passwordAlreadyEncoded,
|
||||||
user.getPassword(),
|
username, realm, user.getPassword(),
|
||||||
((HttpServletRequest) request).getMethod(), uri, qop,
|
((HttpServletRequest) request).getMethod(), uri, qop,
|
||||||
nonce, nc, cnonce);
|
nonce, nc, cnonce);
|
||||||
}
|
}
|
||||||
@ -351,7 +352,9 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fail(request, response,
|
fail(request, response,
|
||||||
new BadCredentialsException("Incorrect response"));
|
new BadCredentialsException(messages.getMessage(
|
||||||
|
"DigestProcessingFilter.incorrectResponse",
|
||||||
|
"Incorrect response")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -362,7 +365,9 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
// but the request was otherwise appearing to be valid
|
// but the request was otherwise appearing to be valid
|
||||||
if (nonceExpiryTime < System.currentTimeMillis()) {
|
if (nonceExpiryTime < System.currentTimeMillis()) {
|
||||||
fail(request, response,
|
fail(request, response,
|
||||||
new NonceExpiredException("Nonce has expired/timed out"));
|
new NonceExpiredException(messages.getMessage(
|
||||||
|
"DigestProcessingFilter.nonceExpired",
|
||||||
|
"Nonce has expired/timed out")));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -382,18 +387,32 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String encodePasswordInA1Format(String username, String realm, String password) {
|
public static String encodePasswordInA1Format(String username,
|
||||||
|
String realm, String password) {
|
||||||
String a1 = username + ":" + realm + ":" + password;
|
String a1 = username + ":" + realm + ":" + password;
|
||||||
String a1Md5 = new String(DigestUtils.md5Hex(a1));
|
String a1Md5 = new String(DigestUtils.md5Hex(a1));
|
||||||
|
|
||||||
return a1Md5;
|
return a1Md5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fail(ServletRequest request, ServletResponse response,
|
||||||
|
AuthenticationException failed) throws IOException, ServletException {
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(null);
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(failed);
|
||||||
|
}
|
||||||
|
|
||||||
|
authenticationEntryPoint.commence(request, response, failed);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the <code>response</code> portion of a Digest authentication
|
* Computes the <code>response</code> portion of a Digest authentication
|
||||||
* header. Both the server and user agent should compute the
|
* header. Both the server and user agent should compute the
|
||||||
* <code>response</code> independently. Provided as a static method to
|
* <code>response</code> independently. Provided as a static method to
|
||||||
* simplify the coding of user agents.
|
* simplify the coding of user agents.
|
||||||
*
|
*
|
||||||
|
* @param passwordAlreadyEncoded DOCUMENT ME!
|
||||||
* @param username DOCUMENT ME!
|
* @param username DOCUMENT ME!
|
||||||
* @param realm DOCUMENT ME!
|
* @param realm DOCUMENT ME!
|
||||||
* @param password DOCUMENT ME!
|
* @param password DOCUMENT ME!
|
||||||
@ -408,9 +427,10 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
*
|
*
|
||||||
* @throws IllegalArgumentException DOCUMENT ME!
|
* @throws IllegalArgumentException DOCUMENT ME!
|
||||||
*/
|
*/
|
||||||
public static String generateDigest(boolean passwordAlreadyEncoded, String username, String realm,
|
public static String generateDigest(boolean passwordAlreadyEncoded,
|
||||||
String password, String httpMethod, String uri, String qop,
|
String username, String realm, String password, String httpMethod,
|
||||||
String nonce, String nc, String cnonce) throws IllegalArgumentException {
|
String uri, String qop, String nonce, String nc, String cnonce)
|
||||||
|
throws IllegalArgumentException {
|
||||||
String a1Md5 = null;
|
String a1Md5 = null;
|
||||||
String a2 = httpMethod + ":" + uri;
|
String a2 = httpMethod + ":" + uri;
|
||||||
String a2Md5 = new String(DigestUtils.md5Hex(a2));
|
String a2Md5 = new String(DigestUtils.md5Hex(a2));
|
||||||
@ -440,8 +460,12 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
return digestMd5;
|
return digestMd5;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserCache(UserCache userCache) {
|
public AuthenticationDao getAuthenticationDao() {
|
||||||
this.userCache = userCache;
|
return authenticationDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DigestProcessingFilterEntryPoint getAuthenticationEntryPoint() {
|
||||||
|
return authenticationEntryPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserCache getUserCache() {
|
public UserCache getUserCache() {
|
||||||
@ -450,14 +474,24 @@ public class DigestProcessingFilter implements Filter, InitializingBean {
|
|||||||
|
|
||||||
public void init(FilterConfig ignored) throws ServletException {}
|
public void init(FilterConfig ignored) throws ServletException {}
|
||||||
|
|
||||||
private void fail(ServletRequest request, ServletResponse response,
|
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
|
||||||
AuthenticationException failed) throws IOException, ServletException {
|
this.authenticationDao = authenticationDao;
|
||||||
SecurityContextHolder.getContext().setAuthentication(null);
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug(failed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
authenticationEntryPoint.commence(request, response, failed);
|
public void setAuthenticationEntryPoint(
|
||||||
|
DigestProcessingFilterEntryPoint authenticationEntryPoint) {
|
||||||
|
this.authenticationEntryPoint = authenticationEntryPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPasswordAlreadyEncoded(boolean passwordAlreadyEncoded) {
|
||||||
|
this.passwordAlreadyEncoded = passwordAlreadyEncoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserCache(UserCache userCache) {
|
||||||
|
this.userCache = userCache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,17 @@ import org.acegisecurity.AuthenticationException;
|
|||||||
import org.acegisecurity.CredentialsExpiredException;
|
import org.acegisecurity.CredentialsExpiredException;
|
||||||
import org.acegisecurity.DisabledException;
|
import org.acegisecurity.DisabledException;
|
||||||
import org.acegisecurity.GrantedAuthority;
|
import org.acegisecurity.GrantedAuthority;
|
||||||
|
import org.acegisecurity.LockedException;
|
||||||
import org.acegisecurity.UserDetails;
|
import org.acegisecurity.UserDetails;
|
||||||
|
|
||||||
import org.acegisecurity.context.SecurityContextHolder;
|
import org.acegisecurity.context.SecurityContextHolder;
|
||||||
|
|
||||||
import org.acegisecurity.event.authentication.AuthenticationSwitchUserEvent;
|
import org.acegisecurity.event.authentication.AuthenticationSwitchUserEvent;
|
||||||
|
|
||||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
import org.acegisecurity.providers.dao.AuthenticationDao;
|
import org.acegisecurity.providers.dao.AuthenticationDao;
|
||||||
import org.acegisecurity.providers.dao.UsernameNotFoundException;
|
import org.acegisecurity.providers.dao.UsernameNotFoundException;
|
||||||
|
|
||||||
import org.acegisecurity.ui.WebAuthenticationDetails;
|
import org.acegisecurity.ui.WebAuthenticationDetails;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@ -36,8 +41,11 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationEventPublisherAware;
|
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.context.ApplicationEventPublisherAware;
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
@ -80,8 +88,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
* <p>
|
* <p>
|
||||||
* On successful switch, the user's <code>SecurityContextHolder</code> will be
|
* On successful switch, the user's <code>SecurityContextHolder</code> will be
|
||||||
* updated to reflect the specified user and will also contain an additinal
|
* updated to reflect the specified user and will also contain an additinal
|
||||||
* {@link org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority }
|
* {@link org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority } which
|
||||||
* which contains the original user.
|
* contains the original user.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
@ -104,13 +112,10 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
* </pre>
|
* </pre>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Mark St.Godard
|
|
||||||
* @version $Id$
|
|
||||||
*
|
|
||||||
* @see org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority
|
* @see org.acegisecurity.ui.switchuser.SwitchUserGrantedAuthority
|
||||||
*/
|
*/
|
||||||
public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
||||||
ApplicationEventPublisherAware {
|
ApplicationEventPublisherAware, MessageSourceAware {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(SwitchUserProcessingFilter.class);
|
private static final Log logger = LogFactory.getLog(SwitchUserProcessingFilter.class);
|
||||||
@ -127,105 +132,21 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
|||||||
// ~ Instance fields
|
// ~ Instance fields
|
||||||
// ========================================================
|
// ========================================================
|
||||||
private AuthenticationDao authenticationDao;
|
private AuthenticationDao authenticationDao;
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private String exitUserUrl = "/j_acegi_exit_user";
|
private String exitUserUrl = "/j_acegi_exit_user";
|
||||||
private String switchUserUrl = "/j_acegi_switch_user";
|
private String switchUserUrl = "/j_acegi_switch_user";
|
||||||
private String targetUrl;
|
private String targetUrl;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher)
|
|
||||||
throws BeansException {
|
|
||||||
this.eventPublisher = eventPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the authentication data access object.
|
|
||||||
*
|
|
||||||
* @param authenticationDao The authentication dao
|
|
||||||
*/
|
|
||||||
public void setAuthenticationDao(AuthenticationDao authenticationDao) {
|
|
||||||
this.authenticationDao = authenticationDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the URL to respond to exit user processing.
|
|
||||||
*
|
|
||||||
* @param exitUserUrl The exit user URL.
|
|
||||||
*/
|
|
||||||
public void setExitUserUrl(String exitUserUrl) {
|
|
||||||
this.exitUserUrl = exitUserUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the URL to respond to switch user processing.
|
|
||||||
*
|
|
||||||
* @param switchUserUrl The switch user URL.
|
|
||||||
*/
|
|
||||||
public void setSwitchUserUrl(String switchUserUrl) {
|
|
||||||
this.switchUserUrl = switchUserUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the URL to go to after a successful switch / exit user request.
|
|
||||||
*
|
|
||||||
* @param targetUrl The target url.
|
|
||||||
*/
|
|
||||||
public void setTargetUrl(String targetUrl) {
|
|
||||||
this.targetUrl = targetUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.hasLength(switchUserUrl, "switchUserUrl must be specified");
|
Assert.hasLength(switchUserUrl, "switchUserUrl must be specified");
|
||||||
Assert.hasLength(exitUserUrl, "exitUserUrl must be specified");
|
Assert.hasLength(exitUserUrl, "exitUserUrl must be specified");
|
||||||
Assert.hasLength(targetUrl, "targetUrl must be specified");
|
Assert.hasLength(targetUrl, "targetUrl must be specified");
|
||||||
Assert.notNull(authenticationDao, "authenticationDao must be specified");
|
Assert.notNull(authenticationDao, "authenticationDao must be specified");
|
||||||
|
Assert.notNull(messages, "A message source must be set");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see javax.servlet.Filter#doFilter
|
|
||||||
*/
|
|
||||||
public void doFilter(ServletRequest request, ServletResponse response,
|
|
||||||
FilterChain chain) throws IOException, ServletException {
|
|
||||||
Assert.isInstanceOf(HttpServletRequest.class, request);
|
|
||||||
Assert.isInstanceOf(HttpServletResponse.class, response);
|
|
||||||
|
|
||||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
|
||||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
|
||||||
|
|
||||||
// check for switch or exit request
|
|
||||||
if (requiresSwitchUser(httpRequest)) {
|
|
||||||
// if set, attempt switch and store original
|
|
||||||
Authentication targetUser = attemptSwitchUser(httpRequest);
|
|
||||||
|
|
||||||
// update the current context to the new target user
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(targetUser);
|
|
||||||
|
|
||||||
// redirect to target url
|
|
||||||
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest
|
|
||||||
.getContextPath() + targetUrl));
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else if (requiresExitUser(httpRequest)) {
|
|
||||||
// get the original authentication object (if exists)
|
|
||||||
Authentication originalUser = attemptExitUser(httpRequest);
|
|
||||||
|
|
||||||
// update the current context back to the original user
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(originalUser);
|
|
||||||
|
|
||||||
// redirect to target url
|
|
||||||
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(httpRequest
|
|
||||||
.getContextPath() + targetUrl));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain.doFilter(request, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(FilterConfig ignored) throws ServletException {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to exit from an already switched user.
|
* Attempt to exit from an already switched user.
|
||||||
*
|
*
|
||||||
@ -244,8 +165,9 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
|||||||
.getAuthentication();
|
.getAuthentication();
|
||||||
|
|
||||||
if (null == current) {
|
if (null == current) {
|
||||||
throw new AuthenticationCredentialsNotFoundException(
|
throw new AuthenticationCredentialsNotFoundException(messages
|
||||||
"No current user associated with this request!");
|
.getMessage("SwitchUserProcessingFilter.noCurrentUser",
|
||||||
|
"No current user associated with this request"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if the current user did actual switch to another user
|
// check to see if the current user did actual switch to another user
|
||||||
@ -253,9 +175,12 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
|||||||
Authentication original = getSourceAuthentication(current);
|
Authentication original = getSourceAuthentication(current);
|
||||||
|
|
||||||
if (original == null) {
|
if (original == null) {
|
||||||
logger.error("Could not find original user Authentication object!");
|
logger.error(
|
||||||
throw new AuthenticationCredentialsNotFoundException(
|
"Could not find original user Authentication object!");
|
||||||
"Could not find original Authentication object!");
|
throw new AuthenticationCredentialsNotFoundException(messages
|
||||||
|
.getMessage(
|
||||||
|
"SwitchUserProcessingFilter.noOriginalAuthentication",
|
||||||
|
"Could not find original Authentication object"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the source user details
|
// get the source user details
|
||||||
@ -268,31 +193,35 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
|||||||
|
|
||||||
// publish event
|
// publish event
|
||||||
if (this.eventPublisher != null) {
|
if (this.eventPublisher != null) {
|
||||||
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(current,
|
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
|
||||||
originalUser));
|
current, originalUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to switch to another user. If the user does not exist or is not
|
* Attempt to switch to another user. If the user does not exist or
|
||||||
* active, return null.
|
* is not active, return null.
|
||||||
*
|
*
|
||||||
* @param request The http request
|
* @param request The http request
|
||||||
*
|
*
|
||||||
* @return The new <code>Authentication</code> request if successfully
|
* @return The new <code>Authentication</code> request if
|
||||||
* switched to another user, <code>null</code> otherwise.
|
* successfully switched to another user,
|
||||||
|
* <code>null</code> otherwise.
|
||||||
*
|
*
|
||||||
* @throws AuthenticationException
|
* @throws AuthenticationException
|
||||||
* @throws UsernameNotFoundException If the target user is not found.
|
* @throws UsernameNotFoundException If the target user is not
|
||||||
|
* found.
|
||||||
|
* @throws LockedException DOCUMENT ME!
|
||||||
* @throws DisabledException If the target user is disabled.
|
* @throws DisabledException If the target user is disabled.
|
||||||
* @throws AccountExpiredException If the target user account is expired.
|
* @throws AccountExpiredException If the target user account is
|
||||||
* @throws CredentialsExpiredException If the target user credentials are
|
|
||||||
* expired.
|
* expired.
|
||||||
|
* @throws CredentialsExpiredException If the target user
|
||||||
|
* credentials are expired.
|
||||||
*/
|
*/
|
||||||
protected Authentication attemptSwitchUser(HttpServletRequest request)
|
protected Authentication attemptSwitchUser(
|
||||||
throws AuthenticationException {
|
HttpServletRequest request) throws AuthenticationException {
|
||||||
UsernamePasswordAuthenticationToken targetUserRequest = null;
|
UsernamePasswordAuthenticationToken targetUserRequest = null;
|
||||||
|
|
||||||
String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
|
String username = request.getParameter(ACEGI_SECURITY_SWITCH_USERNAME_KEY);
|
||||||
@ -306,126 +235,66 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load the user by name
|
// load the user by name
|
||||||
UserDetails targetUser = this.authenticationDao.loadUserByUsername(username);
|
UserDetails targetUser = this.authenticationDao
|
||||||
|
.loadUserByUsername(username);
|
||||||
|
|
||||||
// user not found
|
// user not found
|
||||||
if (targetUser == null) {
|
if (targetUser == null) {
|
||||||
throw new UsernameNotFoundException("User [" + username
|
throw new UsernameNotFoundException(messages.getMessage(
|
||||||
+ "] cannot be found!");
|
"SwitchUserProcessingFilter.usernameNotFound",
|
||||||
|
new Object[] {username},
|
||||||
|
"Username {0} not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// account is expired
|
||||||
|
if (!targetUser.isAccountNonLocked()) {
|
||||||
|
throw new LockedException(messages.getMessage(
|
||||||
|
"SwitchUserProcessingFilter.locked",
|
||||||
|
"User account is locked"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// user is disabled
|
// user is disabled
|
||||||
if (!targetUser.isEnabled()) {
|
if (!targetUser.isEnabled()) {
|
||||||
throw new DisabledException("User is disabled");
|
throw new DisabledException(messages.getMessage(
|
||||||
|
"SwitchUserProcessingFilter.disabled",
|
||||||
|
"User is disabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// account is expired
|
// account is expired
|
||||||
if (!targetUser.isAccountNonExpired()) {
|
if (!targetUser.isAccountNonExpired()) {
|
||||||
throw new AccountExpiredException("User account has expired");
|
throw new AccountExpiredException(messages.getMessage(
|
||||||
|
"SwitchUserProcessingFilter.expired",
|
||||||
|
"User account has expired"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// credentials expired
|
// credentials expired
|
||||||
if (!targetUser.isCredentialsNonExpired()) {
|
if (!targetUser.isCredentialsNonExpired()) {
|
||||||
throw new CredentialsExpiredException("User credentials expired");
|
throw new CredentialsExpiredException(messages
|
||||||
|
.getMessage(
|
||||||
|
"SwitchUserProcessingFilter.credentialsExpired",
|
||||||
|
"User credentials have expired"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok, create the switch user token
|
// ok, create the switch user token
|
||||||
targetUserRequest = createSwitchUserToken(request, username, targetUser);
|
targetUserRequest = createSwitchUserToken(request,
|
||||||
|
username, targetUser);
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Switch User Token [" + targetUserRequest + "]");
|
logger.debug("Switch User Token ["
|
||||||
|
+ targetUserRequest + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish event
|
// publish event
|
||||||
if (this.eventPublisher != null) {
|
if (this.eventPublisher != null) {
|
||||||
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
|
eventPublisher.publishEvent(new AuthenticationSwitchUserEvent(
|
||||||
SecurityContextHolder.getContext().getAuthentication(),
|
SecurityContextHolder.getContext()
|
||||||
|
.getAuthentication(),
|
||||||
targetUser));
|
targetUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
return targetUserRequest;
|
return targetUserRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the request URI for the presence of <tt>exitUserUrl</tt>.
|
|
||||||
*
|
|
||||||
* @param request The http servlet request
|
|
||||||
*
|
|
||||||
* @return <code>true</code> if the request requires a exit user,
|
|
||||||
* <code>false</code> otherwise.
|
|
||||||
*
|
|
||||||
* @see SwitchUserProcessingFilter#exitUserUrl
|
|
||||||
*/
|
|
||||||
protected boolean requiresExitUser(HttpServletRequest request) {
|
|
||||||
String uri = stripUri(request);
|
|
||||||
|
|
||||||
return uri.endsWith(request.getContextPath() + exitUserUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the request URI for the presence of <tt>switchUserUrl</tt>.
|
|
||||||
*
|
|
||||||
* @param request The http servlet request
|
|
||||||
*
|
|
||||||
* @return <code>true</code> if the request requires a switch,
|
|
||||||
* <code>false</code> otherwise.
|
|
||||||
*
|
|
||||||
* @see SwitchUserProcessingFilter#switchUserUrl
|
|
||||||
*/
|
|
||||||
protected boolean requiresSwitchUser(HttpServletRequest request) {
|
|
||||||
String uri = stripUri(request);
|
|
||||||
|
|
||||||
return uri.endsWith(request.getContextPath() + switchUserUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Strips any content after the ';' in the request URI
|
|
||||||
*
|
|
||||||
* @param request The http request
|
|
||||||
*
|
|
||||||
* @return The stripped uri
|
|
||||||
*/
|
|
||||||
private static String stripUri(HttpServletRequest request) {
|
|
||||||
String uri = request.getRequestURI();
|
|
||||||
int idx = uri.indexOf(';');
|
|
||||||
|
|
||||||
if (idx > 0) {
|
|
||||||
uri = uri.substring(0, idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the original <code>Authentication</code> object from the current
|
|
||||||
* user's granted authorities. A successfully switched user should have a
|
|
||||||
* <code>SwitchUserGrantedAuthority</code> that contains the original
|
|
||||||
* source user <code>Authentication</code> object.
|
|
||||||
*
|
|
||||||
* @param current The current <code>Authentication</code> object
|
|
||||||
*
|
|
||||||
* @return The source user <code>Authentication</code> object or
|
|
||||||
* <code>null</code> otherwise.
|
|
||||||
*/
|
|
||||||
private Authentication getSourceAuthentication(Authentication current) {
|
|
||||||
Authentication original = null;
|
|
||||||
|
|
||||||
// iterate over granted authorities and find the 'switch user' authority
|
|
||||||
GrantedAuthority[] authorities = current.getAuthorities();
|
|
||||||
|
|
||||||
for (int i = 0; i < authorities.length; i++) {
|
|
||||||
// check for switch user type of authority
|
|
||||||
if (authorities[i] instanceof SwitchUserGrantedAuthority) {
|
|
||||||
original = ((SwitchUserGrantedAuthority) authorities[i])
|
|
||||||
.getSource();
|
|
||||||
logger.debug("Found original switch user granted authority ["
|
|
||||||
+ original + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return original;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a switch user token that contains an additional
|
* Create a switch user token that contains an additional
|
||||||
* <tt>GrantedAuthority</tt> that contains the original
|
* <tt>GrantedAuthority</tt> that contains the original
|
||||||
@ -440,7 +309,8 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
|||||||
* @see SwitchUserGrantedAuthority
|
* @see SwitchUserGrantedAuthority
|
||||||
*/
|
*/
|
||||||
private UsernamePasswordAuthenticationToken createSwitchUserToken(
|
private UsernamePasswordAuthenticationToken createSwitchUserToken(
|
||||||
HttpServletRequest request, String username, UserDetails targetUser) {
|
HttpServletRequest request, String username,
|
||||||
|
UserDetails targetUser) {
|
||||||
UsernamePasswordAuthenticationToken targetUserRequest;
|
UsernamePasswordAuthenticationToken targetUserRequest;
|
||||||
|
|
||||||
// grant an additional authority that contains the original Authentication object
|
// grant an additional authority that contains the original Authentication object
|
||||||
@ -465,8 +335,227 @@ public class SwitchUserProcessingFilter implements Filter, InitializingBean,
|
|||||||
targetUser.getPassword(), authorities);
|
targetUser.getPassword(), authorities);
|
||||||
|
|
||||||
// set details
|
// set details
|
||||||
targetUserRequest.setDetails(new WebAuthenticationDetails(request));
|
targetUserRequest.setDetails(new WebAuthenticationDetails(
|
||||||
|
request));
|
||||||
|
|
||||||
return targetUserRequest;
|
return targetUserRequest;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public void destroy() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see javax.servlet.Filter#doFilter
|
||||||
|
*/
|
||||||
|
public void doFilter(ServletRequest request,
|
||||||
|
ServletResponse response, FilterChain chain)
|
||||||
|
throws IOException, ServletException {
|
||||||
|
Assert.isInstanceOf(HttpServletRequest.class, request);
|
||||||
|
Assert.isInstanceOf(HttpServletResponse.class, response);
|
||||||
|
|
||||||
|
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||||
|
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||||
|
|
||||||
|
// check for switch or exit request
|
||||||
|
if (requiresSwitchUser(httpRequest)) {
|
||||||
|
// if set, attempt switch and store original
|
||||||
|
Authentication targetUser = attemptSwitchUser(httpRequest);
|
||||||
|
|
||||||
|
// update the current context to the new target user
|
||||||
|
SecurityContextHolder.getContext()
|
||||||
|
.setAuthentication(targetUser);
|
||||||
|
|
||||||
|
// redirect to target url
|
||||||
|
httpResponse.sendRedirect(httpResponse
|
||||||
|
.encodeRedirectURL(httpRequest
|
||||||
|
.getContextPath() + targetUrl));
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else if (requiresExitUser(httpRequest)) {
|
||||||
|
// get the original authentication object (if exists)
|
||||||
|
Authentication originalUser = attemptExitUser(httpRequest);
|
||||||
|
|
||||||
|
// update the current context back to the original user
|
||||||
|
SecurityContextHolder.getContext()
|
||||||
|
.setAuthentication(originalUser);
|
||||||
|
|
||||||
|
// redirect to target url
|
||||||
|
httpResponse.sendRedirect(httpResponse
|
||||||
|
.encodeRedirectURL(httpRequest
|
||||||
|
.getContextPath()
|
||||||
|
+ targetUrl));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the original
|
||||||
|
* <code>Authentication</code> object from
|
||||||
|
* the current user's granted authorities.
|
||||||
|
* A successfully switched user should
|
||||||
|
* have a
|
||||||
|
* <code>SwitchUserGrantedAuthority</code>
|
||||||
|
* that contains the original source user
|
||||||
|
* <code>Authentication</code> object.
|
||||||
|
*
|
||||||
|
* @param current The current
|
||||||
|
* <code>Authentication</code>
|
||||||
|
* object
|
||||||
|
*
|
||||||
|
* @return The source user
|
||||||
|
* <code>Authentication</code>
|
||||||
|
* object or <code>null</code>
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
private Authentication getSourceAuthentication(
|
||||||
|
Authentication current) {
|
||||||
|
Authentication original = null;
|
||||||
|
|
||||||
|
// iterate over granted authorities and find the 'switch user' authority
|
||||||
|
GrantedAuthority[] authorities = current
|
||||||
|
.getAuthorities();
|
||||||
|
|
||||||
|
for (int i = 0; i < authorities.length;
|
||||||
|
i++) {
|
||||||
|
// check for switch user type of authority
|
||||||
|
if (authorities[i] instanceof SwitchUserGrantedAuthority) {
|
||||||
|
original = ((SwitchUserGrantedAuthority) authorities[i])
|
||||||
|
.getSource();
|
||||||
|
logger.debug(
|
||||||
|
"Found original switch user granted authority ["
|
||||||
|
+ original + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(FilterConfig ignored)
|
||||||
|
throws ServletException {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the request URI for the presence
|
||||||
|
* of <tt>exitUserUrl</tt>.
|
||||||
|
*
|
||||||
|
* @param request The http servlet request
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the request
|
||||||
|
* requires a exit user,
|
||||||
|
* <code>false</code> otherwise.
|
||||||
|
*
|
||||||
|
* @see SwitchUserProcessingFilter#exitUserUrl
|
||||||
|
*/
|
||||||
|
protected boolean requiresExitUser(
|
||||||
|
HttpServletRequest request) {
|
||||||
|
String uri = stripUri(request);
|
||||||
|
|
||||||
|
return uri.endsWith(request
|
||||||
|
.getContextPath() + exitUserUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the request URI for the
|
||||||
|
* presence of <tt>switchUserUrl</tt>.
|
||||||
|
*
|
||||||
|
* @param request The http servlet
|
||||||
|
* request
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the
|
||||||
|
* request requires a switch,
|
||||||
|
* <code>false</code>
|
||||||
|
* otherwise.
|
||||||
|
*
|
||||||
|
* @see SwitchUserProcessingFilter#switchUserUrl
|
||||||
|
*/
|
||||||
|
protected boolean requiresSwitchUser(
|
||||||
|
HttpServletRequest request) {
|
||||||
|
String uri = stripUri(request);
|
||||||
|
|
||||||
|
return uri.endsWith(request
|
||||||
|
.getContextPath()
|
||||||
|
+ switchUserUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApplicationEventPublisher(
|
||||||
|
ApplicationEventPublisher eventPublisher)
|
||||||
|
throws BeansException {
|
||||||
|
this.eventPublisher = eventPublisher;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the authentication data
|
||||||
|
* access object.
|
||||||
|
*
|
||||||
|
* @param authenticationDao The
|
||||||
|
* authentication dao
|
||||||
|
*/
|
||||||
|
public void setAuthenticationDao(
|
||||||
|
AuthenticationDao authenticationDao) {
|
||||||
|
this.authenticationDao = authenticationDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the URL to respond to exit
|
||||||
|
* user processing.
|
||||||
|
*
|
||||||
|
* @param exitUserUrl The exit user
|
||||||
|
* URL.
|
||||||
|
*/
|
||||||
|
public void setExitUserUrl(
|
||||||
|
String exitUserUrl) {
|
||||||
|
this.exitUserUrl = exitUserUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageSource(
|
||||||
|
MessageSource messageSource) {
|
||||||
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the URL to respond to switch
|
||||||
|
* user processing.
|
||||||
|
*
|
||||||
|
* @param switchUserUrl The switch
|
||||||
|
* user URL.
|
||||||
|
*/
|
||||||
|
public void setSwitchUserUrl(
|
||||||
|
String switchUserUrl) {
|
||||||
|
this.switchUserUrl = switchUserUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the URL to go to after a
|
||||||
|
* successful switch / exit user
|
||||||
|
* request.
|
||||||
|
*
|
||||||
|
* @param targetUrl The target url.
|
||||||
|
*/
|
||||||
|
public void setTargetUrl(
|
||||||
|
String targetUrl) {
|
||||||
|
this.targetUrl = targetUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strips any content after the ';'
|
||||||
|
* in the request URI
|
||||||
|
*
|
||||||
|
* @param request The http request
|
||||||
|
*
|
||||||
|
* @return The stripped uri
|
||||||
|
*/
|
||||||
|
private static String stripUri(
|
||||||
|
HttpServletRequest request) {
|
||||||
|
String uri = request
|
||||||
|
.getRequestURI();
|
||||||
|
int idx = uri.indexOf(';');
|
||||||
|
|
||||||
|
if (idx > 0) {
|
||||||
|
uri = uri.substring(0,
|
||||||
|
idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -20,6 +20,12 @@ import org.acegisecurity.ConfigAttribute;
|
|||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.MessageSourceAware;
|
||||||
|
import org.springframework.context.support.MessageSourceAccessor;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -32,28 +38,42 @@ import java.util.List;
|
|||||||
* AccessDecisionVoter}s and the access control behaviour if all voters
|
* AccessDecisionVoter}s and the access control behaviour if all voters
|
||||||
* abstain from voting (defaults to deny access).
|
* abstain from voting (defaults to deny access).
|
||||||
* </p>
|
* </p>
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractAccessDecisionManager
|
public abstract class AbstractAccessDecisionManager
|
||||||
implements AccessDecisionManager, InitializingBean {
|
implements AccessDecisionManager, InitializingBean, MessageSourceAware {
|
||||||
//~ Instance fields ========================================================
|
//~ Instance fields ========================================================
|
||||||
|
|
||||||
private List decisionVoters;
|
private List decisionVoters;
|
||||||
|
protected MessageSourceAccessor messages;
|
||||||
private boolean allowIfAllAbstainDecisions = false;
|
private boolean allowIfAllAbstainDecisions = false;
|
||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setAllowIfAllAbstainDecisions(
|
public void afterPropertiesSet() throws Exception {
|
||||||
boolean allowIfAllAbstainDecisions) {
|
checkIfValidList(this.decisionVoters);
|
||||||
this.allowIfAllAbstainDecisions = allowIfAllAbstainDecisions;
|
Assert.notNull(this.messages, "A message source must be set");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkIfValidList(List listToCheck) {
|
||||||
|
if ((listToCheck == null) || (listToCheck.size() == 0)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"A list of AccessDecisionVoters is required");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List getDecisionVoters() {
|
||||||
|
return this.decisionVoters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAllowIfAllAbstainDecisions() {
|
public boolean isAllowIfAllAbstainDecisions() {
|
||||||
return allowIfAllAbstainDecisions;
|
return allowIfAllAbstainDecisions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAllowIfAllAbstainDecisions(
|
||||||
|
boolean allowIfAllAbstainDecisions) {
|
||||||
|
this.allowIfAllAbstainDecisions = allowIfAllAbstainDecisions;
|
||||||
|
}
|
||||||
|
|
||||||
public void setDecisionVoters(List newList) {
|
public void setDecisionVoters(List newList) {
|
||||||
checkIfValidList(newList);
|
checkIfValidList(newList);
|
||||||
|
|
||||||
@ -76,12 +96,8 @@ public abstract class AbstractAccessDecisionManager
|
|||||||
this.decisionVoters = newList;
|
this.decisionVoters = newList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List getDecisionVoters() {
|
public void setMessageSource(MessageSource messageSource) {
|
||||||
return this.decisionVoters;
|
this.messages = new MessageSourceAccessor(messageSource);
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
|
||||||
checkIfValidList(this.decisionVoters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supports(ConfigAttribute attribute) {
|
public boolean supports(ConfigAttribute attribute) {
|
||||||
@ -124,11 +140,4 @@ public abstract class AbstractAccessDecisionManager
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkIfValidList(List listToCheck) {
|
|
||||||
if ((listToCheck == null) || (listToCheck.size() == 0)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"A list of AccessDecisionVoters is required");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -29,9 +29,6 @@ import java.util.Iterator;
|
|||||||
* Simple concrete implementation of {@link
|
* Simple concrete implementation of {@link
|
||||||
* org.acegisecurity.AccessDecisionManager} that grants access if any
|
* org.acegisecurity.AccessDecisionManager} that grants access if any
|
||||||
* <code>AccessDecisionVoter</code> returns an affirmative response.
|
* <code>AccessDecisionVoter</code> returns an affirmative response.
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class AffirmativeBased extends AbstractAccessDecisionManager {
|
public class AffirmativeBased extends AbstractAccessDecisionManager {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
@ -83,14 +80,18 @@ public class AffirmativeBased extends AbstractAccessDecisionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (deny > 0) {
|
if (deny > 0) {
|
||||||
throw new AccessDeniedException("Access is denied.");
|
throw new AccessDeniedException(messages.getMessage(
|
||||||
|
"AbstractAccessDecisionManager.accessDenied",
|
||||||
|
"Access is denied"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// To get this far, every AccessDecisionVoter abstained
|
// To get this far, every AccessDecisionVoter abstained
|
||||||
if (this.isAllowIfAllAbstainDecisions()) {
|
if (this.isAllowIfAllAbstainDecisions()) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
throw new AccessDeniedException("Access is denied.");
|
throw new AccessDeniedException(messages.getMessage(
|
||||||
|
"AbstractAccessDecisionManager.accessDenied",
|
||||||
|
"Access is denied"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -29,9 +29,6 @@ import java.util.Iterator;
|
|||||||
* Simple concrete implementation of {@link
|
* Simple concrete implementation of {@link
|
||||||
* org.acegisecurity.AccessDecisionManager} that uses a consensus-based
|
* org.acegisecurity.AccessDecisionManager} that uses a consensus-based
|
||||||
* approach.
|
* approach.
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class ConsensusBased extends AbstractAccessDecisionManager {
|
public class ConsensusBased extends AbstractAccessDecisionManager {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
@ -44,15 +41,6 @@ public class ConsensusBased extends AbstractAccessDecisionManager {
|
|||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public void setAllowIfEqualGrantedDeniedDecisions(
|
|
||||||
boolean allowIfEqualGrantedDeniedDecisions) {
|
|
||||||
this.allowIfEqualGrantedDeniedDecisions = allowIfEqualGrantedDeniedDecisions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAllowIfEqualGrantedDeniedDecisions() {
|
|
||||||
return allowIfEqualGrantedDeniedDecisions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This concrete implementation simply polls all configured {@link
|
* This concrete implementation simply polls all configured {@link
|
||||||
* AccessDecisionVoter}s and upon completion determines the consensus of
|
* AccessDecisionVoter}s and upon completion determines the consensus of
|
||||||
@ -111,14 +99,18 @@ public class ConsensusBased extends AbstractAccessDecisionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (deny > grant) {
|
if (deny > grant) {
|
||||||
throw new AccessDeniedException("Access is denied.");
|
throw new AccessDeniedException(messages.getMessage(
|
||||||
|
"AbstractAccessDecisionManager.accessDenied",
|
||||||
|
"Access is denied"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((grant == deny) && (grant != 0)) {
|
if ((grant == deny) && (grant != 0)) {
|
||||||
if (this.allowIfEqualGrantedDeniedDecisions) {
|
if (this.allowIfEqualGrantedDeniedDecisions) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
throw new AccessDeniedException("Access is denied.");
|
throw new AccessDeniedException(messages.getMessage(
|
||||||
|
"AbstractAccessDecisionManager.accessDenied",
|
||||||
|
"Access is denied"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +118,18 @@ public class ConsensusBased extends AbstractAccessDecisionManager {
|
|||||||
if (this.isAllowIfAllAbstainDecisions()) {
|
if (this.isAllowIfAllAbstainDecisions()) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
throw new AccessDeniedException("Access is denied.");
|
throw new AccessDeniedException(messages.getMessage(
|
||||||
|
"AbstractAccessDecisionManager.accessDenied",
|
||||||
|
"Access is denied"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAllowIfEqualGrantedDeniedDecisions() {
|
||||||
|
return allowIfEqualGrantedDeniedDecisions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowIfEqualGrantedDeniedDecisions(
|
||||||
|
boolean allowIfEqualGrantedDeniedDecisions) {
|
||||||
|
this.allowIfEqualGrantedDeniedDecisions = allowIfEqualGrantedDeniedDecisions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -30,9 +30,6 @@ import java.util.Iterator;
|
|||||||
* Simple concrete implementation of {@link
|
* Simple concrete implementation of {@link
|
||||||
* org.acegisecurity.AccessDecisionManager} that requires all voters to
|
* org.acegisecurity.AccessDecisionManager} that requires all voters to
|
||||||
* abstain or grant access.
|
* abstain or grant access.
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class UnanimousBased extends AbstractAccessDecisionManager {
|
public class UnanimousBased extends AbstractAccessDecisionManager {
|
||||||
//~ Static fields/initializers =============================================
|
//~ Static fields/initializers =============================================
|
||||||
@ -105,7 +102,9 @@ public class UnanimousBased extends AbstractAccessDecisionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (deny > 0) {
|
if (deny > 0) {
|
||||||
throw new AccessDeniedException("Access is denied.");
|
throw new AccessDeniedException(messages.getMessage(
|
||||||
|
"AbstractAccessDecisionManager.accessDenied",
|
||||||
|
"Access is denied"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// To get this far, there were no deny votes
|
// To get this far, there were no deny votes
|
||||||
@ -117,7 +116,9 @@ public class UnanimousBased extends AbstractAccessDecisionManager {
|
|||||||
if (this.isAllowIfAllAbstainDecisions()) {
|
if (this.isAllowIfAllAbstainDecisions()) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
throw new AccessDeniedException("Access is denied.");
|
throw new AccessDeniedException(messages.getMessage(
|
||||||
|
"AbstractAccessDecisionManager.accessDenied",
|
||||||
|
"Access is denied"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
|
|||||||
import org.acegisecurity.GrantedAuthorityImpl;
|
import org.acegisecurity.GrantedAuthorityImpl;
|
||||||
|
|
||||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,6 +82,7 @@ public class AuthByAdapterTests extends TestCase {
|
|||||||
public void testAuthByAdapterProviderNonAuthenticationMethods()
|
public void testAuthByAdapterProviderNonAuthenticationMethods()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
AuthByAdapterProvider provider = new AuthByAdapterProvider();
|
AuthByAdapterProvider provider = new AuthByAdapterProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
provider.afterPropertiesSet();
|
provider.afterPropertiesSet();
|
||||||
@ -99,6 +101,7 @@ public class AuthByAdapterTests extends TestCase {
|
|||||||
public void testAuthByAdapterProviderOnlyAcceptsAuthByAdapterImplementations()
|
public void testAuthByAdapterProviderOnlyAcceptsAuthByAdapterImplementations()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
AuthByAdapterProvider provider = new AuthByAdapterProvider();
|
AuthByAdapterProvider provider = new AuthByAdapterProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setKey("my_password");
|
provider.setKey("my_password");
|
||||||
|
|
||||||
// Should fail as UsernamePassword is not interface of AuthByAdapter
|
// Should fail as UsernamePassword is not interface of AuthByAdapter
|
||||||
@ -119,6 +122,7 @@ public class AuthByAdapterTests extends TestCase {
|
|||||||
public void testAuthByAdapterProviderRequiresCorrectKey()
|
public void testAuthByAdapterProviderRequiresCorrectKey()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
AuthByAdapterProvider provider = new AuthByAdapterProvider();
|
AuthByAdapterProvider provider = new AuthByAdapterProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setKey("my_password");
|
provider.setKey("my_password");
|
||||||
|
|
||||||
// Should fail as PrincipalAcegiUserToken has different key
|
// Should fail as PrincipalAcegiUserToken has different key
|
||||||
|
@ -27,6 +27,7 @@ import org.acegisecurity.acl.basic.MockAclObjectIdentity;
|
|||||||
import org.acegisecurity.acl.basic.SimpleAclEntry;
|
import org.acegisecurity.acl.basic.SimpleAclEntry;
|
||||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
import org.acegisecurity.util.SimpleMethodInvocation;
|
import org.acegisecurity.util.SimpleMethodInvocation;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,6 +66,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
|
|||||||
SimpleAclEntry.ADMINISTRATION)});
|
SimpleAclEntry.ADMINISTRATION)});
|
||||||
|
|
||||||
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAclManager(aclManager);
|
provider.setAclManager(aclManager);
|
||||||
provider.afterPropertiesSet();
|
provider.afterPropertiesSet();
|
||||||
|
|
||||||
@ -94,6 +96,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
|
|||||||
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)});
|
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)});
|
||||||
|
|
||||||
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAclManager(aclManager);
|
provider.setAclManager(aclManager);
|
||||||
provider.afterPropertiesSet();
|
provider.afterPropertiesSet();
|
||||||
|
|
||||||
@ -123,6 +126,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
|
|||||||
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)});
|
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE)});
|
||||||
|
|
||||||
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAclManager(aclManager);
|
provider.setAclManager(aclManager);
|
||||||
assertEquals(aclManager, provider.getAclManager());
|
assertEquals(aclManager, provider.getAclManager());
|
||||||
provider.afterPropertiesSet();
|
provider.afterPropertiesSet();
|
||||||
@ -150,6 +154,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
|
|||||||
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()});
|
new MockAclObjectIdentity(), null, SimpleAclEntry.DELETE), new MockAclEntry()});
|
||||||
|
|
||||||
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAclManager(aclManager);
|
provider.setAclManager(aclManager);
|
||||||
provider.afterPropertiesSet();
|
provider.afterPropertiesSet();
|
||||||
|
|
||||||
@ -171,6 +176,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
|
|||||||
new MockAclObjectIdentity(), null, SimpleAclEntry.READ), new MockAclEntry()});
|
new MockAclObjectIdentity(), null, SimpleAclEntry.READ), new MockAclEntry()});
|
||||||
|
|
||||||
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAclManager(aclManager);
|
provider.setAclManager(aclManager);
|
||||||
assertEquals("AFTER_ACL_READ", provider.getProcessConfigAttribute());
|
assertEquals("AFTER_ACL_READ", provider.getProcessConfigAttribute());
|
||||||
provider.setProcessConfigAttribute("AFTER_ACL_ADMIN");
|
provider.setProcessConfigAttribute("AFTER_ACL_ADMIN");
|
||||||
@ -202,6 +208,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
|
|||||||
SimpleAclEntry.ADMINISTRATION), new MockAclEntry()});
|
SimpleAclEntry.ADMINISTRATION), new MockAclEntry()});
|
||||||
|
|
||||||
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAclManager(aclManager);
|
provider.setAclManager(aclManager);
|
||||||
assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]);
|
assertEquals(SimpleAclEntry.READ, provider.getRequirePermission()[0]);
|
||||||
provider.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION});
|
provider.setRequirePermission(new int[] {SimpleAclEntry.ADMINISTRATION});
|
||||||
@ -222,6 +229,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testStartupDetectsMissingAclManager() throws Exception {
|
public void testStartupDetectsMissingAclManager() throws Exception {
|
||||||
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
provider.afterPropertiesSet();
|
provider.afterPropertiesSet();
|
||||||
@ -234,6 +242,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
|
|||||||
public void testStartupDetectsMissingProcessConfigAttribute()
|
public void testStartupDetectsMissingProcessConfigAttribute()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
AclManager aclManager = new MockAclManager("sydney", "marissa",
|
AclManager aclManager = new MockAclManager("sydney", "marissa",
|
||||||
new AclEntry[] {new SimpleAclEntry("marissa",
|
new AclEntry[] {new SimpleAclEntry("marissa",
|
||||||
new MockAclObjectIdentity(), null,
|
new MockAclObjectIdentity(), null,
|
||||||
@ -254,6 +263,7 @@ public class BasicAclEntryAfterInvocationProviderTests extends TestCase {
|
|||||||
public void testStartupDetectsMissingRequirePermission()
|
public void testStartupDetectsMissingRequirePermission()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
BasicAclEntryAfterInvocationProvider provider = new BasicAclEntryAfterInvocationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
AclManager aclManager = new MockAclManager("sydney", "marissa",
|
AclManager aclManager = new MockAclManager("sydney", "marissa",
|
||||||
new AclEntry[] {new SimpleAclEntry("marissa",
|
new AclEntry[] {new SimpleAclEntry("marissa",
|
||||||
new MockAclObjectIdentity(), null,
|
new MockAclObjectIdentity(), null,
|
||||||
|
@ -21,6 +21,7 @@ import org.acegisecurity.Authentication;
|
|||||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
import org.acegisecurity.ui.WebAuthenticationDetails;
|
import org.acegisecurity.ui.WebAuthenticationDetails;
|
||||||
|
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.mock.web.MockHttpSession;
|
import org.springframework.mock.web.MockHttpSession;
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ public class ConcurrentSessionControllerImplTests extends TestCase {
|
|||||||
ConcurrentSessionControllerImpl sc = new ConcurrentSessionControllerImpl();
|
ConcurrentSessionControllerImpl sc = new ConcurrentSessionControllerImpl();
|
||||||
SessionRegistry registry = new SessionRegistryImpl();
|
SessionRegistry registry = new SessionRegistryImpl();
|
||||||
sc.setSessionRegistry(registry);
|
sc.setSessionRegistry(registry);
|
||||||
|
sc.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
// Attempt to authenticate - it should be successful
|
// Attempt to authenticate - it should be successful
|
||||||
Authentication auth = createAuthentication("bob", "1212");
|
Authentication auth = createAuthentication("bob", "1212");
|
||||||
|
@ -41,6 +41,7 @@ import org.acegisecurity.runas.RunAsManagerImpl;
|
|||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
@ -177,6 +178,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
public void testRejectsAccessDecisionManagersThatDoNotSupportMethodInvocation()
|
public void testRejectsAccessDecisionManagersThatDoNotSupportMethodInvocation()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManagerWhichOnlySupportsStrings());
|
si.setAccessDecisionManager(new MockAccessDecisionManagerWhichOnlySupportsStrings());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
|
si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
|
||||||
@ -212,6 +214,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
public void testRejectsCallsWhenObjectDefinitionSourceDoesNotSupportObject()
|
public void testRejectsCallsWhenObjectDefinitionSourceDoesNotSupportObject()
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
|
||||||
|
interceptor.setMessageSource(new StaticMessageSource());
|
||||||
interceptor.setObjectDefinitionSource(new MockObjectDefinitionSourceWhichOnlySupportsStrings());
|
interceptor.setObjectDefinitionSource(new MockObjectDefinitionSourceWhichOnlySupportsStrings());
|
||||||
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
|
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
@ -228,6 +231,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
|
|
||||||
public void testRejectsCallsWhenObjectIsNull() throws Throwable {
|
public void testRejectsCallsWhenObjectIsNull() throws Throwable {
|
||||||
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor interceptor = new MethodSecurityInterceptor();
|
||||||
|
interceptor.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
interceptor.invoke(null);
|
interceptor.invoke(null);
|
||||||
@ -240,6 +244,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
public void testRejectsRunAsManagersThatDoNotSupportMethodInvocation()
|
public void testRejectsRunAsManagersThatDoNotSupportMethodInvocation()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
|
si.setObjectDefinitionSource(new MockMethodDefinitionSource(false, true));
|
||||||
@ -258,6 +263,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
public void testStartupCheckForAccessDecisionManager()
|
public void testStartupCheckForAccessDecisionManager()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setRunAsManager(new MockRunAsManager());
|
si.setRunAsManager(new MockRunAsManager());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
si.setAfterInvocationManager(new MockAfterInvocationManager());
|
si.setAfterInvocationManager(new MockAfterInvocationManager());
|
||||||
@ -276,6 +282,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
public void testStartupCheckForAuthenticationManager()
|
public void testStartupCheckForAuthenticationManager()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
si.setRunAsManager(new MockRunAsManager());
|
si.setRunAsManager(new MockRunAsManager());
|
||||||
si.setAfterInvocationManager(new MockAfterInvocationManager());
|
si.setAfterInvocationManager(new MockAfterInvocationManager());
|
||||||
@ -294,6 +301,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
public void testStartupCheckForMethodDefinitionSource()
|
public void testStartupCheckForMethodDefinitionSource()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
|
|
||||||
@ -308,6 +316,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
|
|
||||||
public void testStartupCheckForRunAsManager() throws Exception {
|
public void testStartupCheckForRunAsManager() throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
si.setRunAsManager(null); // Overriding the default
|
si.setRunAsManager(null); // Overriding the default
|
||||||
@ -325,6 +334,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
public void testStartupCheckForValidAfterInvocationManager()
|
public void testStartupCheckForValidAfterInvocationManager()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setRunAsManager(new MockRunAsManager());
|
si.setRunAsManager(new MockRunAsManager());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
si.setAfterInvocationManager(new MockAfterInvocationManagerWhichOnlySupportsStrings());
|
si.setAfterInvocationManager(new MockAfterInvocationManagerWhichOnlySupportsStrings());
|
||||||
@ -342,6 +352,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
public void testValidationFailsIfInvalidAttributePresented()
|
public void testValidationFailsIfInvalidAttributePresented()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
si.setRunAsManager(new RunAsManagerImpl());
|
si.setRunAsManager(new RunAsManagerImpl());
|
||||||
@ -361,6 +372,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
public void testValidationNotAttemptedIfIsValidateConfigAttributesSetToFalse()
|
public void testValidationNotAttemptedIfIsValidateConfigAttributesSetToFalse()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
|
|
||||||
@ -376,6 +388,7 @@ public class MethodSecurityInterceptorTests extends TestCase {
|
|||||||
public void testValidationNotAttemptedIfMethodDefinitionSourceCannotReturnIterator()
|
public void testValidationNotAttemptedIfMethodDefinitionSourceCannotReturnIterator()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
MethodSecurityInterceptor si = new MethodSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
si.setRunAsManager(new MockRunAsManager());
|
si.setRunAsManager(new MockRunAsManager());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
|
@ -30,6 +30,7 @@ import org.acegisecurity.context.SecurityContextHolder;
|
|||||||
import org.acegisecurity.intercept.method.MethodDefinitionMap;
|
import org.acegisecurity.intercept.method.MethodDefinitionMap;
|
||||||
import org.acegisecurity.intercept.method.MethodDefinitionSourceEditor;
|
import org.acegisecurity.intercept.method.MethodDefinitionSourceEditor;
|
||||||
import org.acegisecurity.providers.TestingAuthenticationToken;
|
import org.acegisecurity.providers.TestingAuthenticationToken;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
@ -64,6 +65,7 @@ public class AspectJSecurityInterceptorTests extends TestCase {
|
|||||||
public void testCallbackIsInvokedWhenPermissionGranted()
|
public void testCallbackIsInvokedWhenPermissionGranted()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
|
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setApplicationEventPublisher(MockApplicationContext.getContext());
|
si.setApplicationEventPublisher(MockApplicationContext.getContext());
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
@ -100,6 +102,7 @@ public class AspectJSecurityInterceptorTests extends TestCase {
|
|||||||
public void testCallbackIsNotInvokedWhenPermissionDenied()
|
public void testCallbackIsNotInvokedWhenPermissionDenied()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
|
AspectJSecurityInterceptor si = new AspectJSecurityInterceptor();
|
||||||
|
si.setMessageSource(new StaticMessageSource());
|
||||||
si.setApplicationEventPublisher(MockApplicationContext.getContext());
|
si.setApplicationEventPublisher(MockApplicationContext.getContext());
|
||||||
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
si.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
si.setAuthenticationManager(new MockAuthenticationManager());
|
si.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
|
@ -34,6 +34,7 @@ import org.acegisecurity.context.SecurityContextHolder;
|
|||||||
import org.acegisecurity.context.SecurityContextImpl;
|
import org.acegisecurity.context.SecurityContextImpl;
|
||||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
|
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.mock.web.MockHttpServletResponse;
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
|
||||||
@ -77,6 +78,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
|
|||||||
public void testEnsuresAccessDecisionManagerSupportsFilterInvocationClass()
|
public void testEnsuresAccessDecisionManagerSupportsFilterInvocationClass()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
|
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
|
||||||
|
interceptor.setMessageSource(new StaticMessageSource());
|
||||||
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
|
interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
|
||||||
interceptor.setRunAsManager(new MockRunAsManager());
|
interceptor.setRunAsManager(new MockRunAsManager());
|
||||||
@ -110,6 +112,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
|
|||||||
public void testEnsuresRunAsManagerSupportsFilterInvocationClass()
|
public void testEnsuresRunAsManagerSupportsFilterInvocationClass()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
|
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
|
||||||
|
interceptor.setMessageSource(new StaticMessageSource());
|
||||||
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
|
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
|
interceptor.setObjectDefinitionSource(new RegExpBasedFilterInvocationDefinitionMap());
|
||||||
@ -144,6 +147,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
|
|||||||
throws Throwable {
|
throws Throwable {
|
||||||
// Setup the FilterSecurityInterceptor
|
// Setup the FilterSecurityInterceptor
|
||||||
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
|
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
|
||||||
|
interceptor.setMessageSource(new StaticMessageSource());
|
||||||
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
|
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
interceptor.setRunAsManager(new MockRunAsManager());
|
interceptor.setRunAsManager(new MockRunAsManager());
|
||||||
@ -183,6 +187,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
|
|||||||
|
|
||||||
public void testNormalStartupAndGetter() throws Exception {
|
public void testNormalStartupAndGetter() throws Exception {
|
||||||
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
|
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
|
||||||
|
interceptor.setMessageSource(new StaticMessageSource());
|
||||||
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
|
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
|
|
||||||
@ -203,6 +208,7 @@ public class FilterSecurityInterceptorTests extends TestCase {
|
|||||||
public void testSuccessfulInvocation() throws Throwable {
|
public void testSuccessfulInvocation() throws Throwable {
|
||||||
// Setup the FilterSecurityInterceptor
|
// Setup the FilterSecurityInterceptor
|
||||||
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
|
FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
|
||||||
|
interceptor.setMessageSource(new StaticMessageSource());
|
||||||
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
|
interceptor.setAccessDecisionManager(new MockAccessDecisionManager());
|
||||||
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
interceptor.setAuthenticationManager(new MockAuthenticationManager());
|
||||||
interceptor.setRunAsManager(new MockRunAsManager());
|
interceptor.setRunAsManager(new MockRunAsManager());
|
||||||
|
@ -29,6 +29,7 @@ import org.acegisecurity.concurrent.NullConcurrentSessionController;
|
|||||||
|
|
||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,7 +183,7 @@ public class ProviderManagerTests extends TestCase {
|
|||||||
|
|
||||||
ProviderManager mgr = new ProviderManager();
|
ProviderManager mgr = new ProviderManager();
|
||||||
mgr.setProviders(providers);
|
mgr.setProviders(providers);
|
||||||
|
mgr.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
mgr.afterPropertiesSet();
|
mgr.afterPropertiesSet();
|
||||||
return mgr;
|
return mgr;
|
||||||
|
@ -22,6 +22,7 @@ import org.acegisecurity.BadCredentialsException;
|
|||||||
import org.acegisecurity.GrantedAuthority;
|
import org.acegisecurity.GrantedAuthority;
|
||||||
import org.acegisecurity.GrantedAuthorityImpl;
|
import org.acegisecurity.GrantedAuthorityImpl;
|
||||||
import org.acegisecurity.providers.TestingAuthenticationToken;
|
import org.acegisecurity.providers.TestingAuthenticationToken;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,6 +54,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testDetectsAnInvalidKey() throws Exception {
|
public void testDetectsAnInvalidKey() throws Exception {
|
||||||
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
||||||
|
aap.setMessageSource(new StaticMessageSource());
|
||||||
aap.setKey("qwerty");
|
aap.setKey("qwerty");
|
||||||
|
|
||||||
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("WRONG_KEY",
|
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("WRONG_KEY",
|
||||||
@ -71,6 +73,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testDetectsMissingKey() throws Exception {
|
public void testDetectsMissingKey() throws Exception {
|
||||||
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
||||||
|
aap.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
aap.afterPropertiesSet();
|
aap.afterPropertiesSet();
|
||||||
@ -82,6 +85,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testGettersSetters() throws Exception {
|
public void testGettersSetters() throws Exception {
|
||||||
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
||||||
|
aap.setMessageSource(new StaticMessageSource());
|
||||||
aap.setKey("qwerty");
|
aap.setKey("qwerty");
|
||||||
aap.afterPropertiesSet();
|
aap.afterPropertiesSet();
|
||||||
assertEquals("qwerty", aap.getKey());
|
assertEquals("qwerty", aap.getKey());
|
||||||
@ -89,6 +93,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testIgnoresClassesItDoesNotSupport() throws Exception {
|
public void testIgnoresClassesItDoesNotSupport() throws Exception {
|
||||||
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
||||||
|
aap.setMessageSource(new StaticMessageSource());
|
||||||
aap.setKey("qwerty");
|
aap.setKey("qwerty");
|
||||||
|
|
||||||
TestingAuthenticationToken token = new TestingAuthenticationToken("user",
|
TestingAuthenticationToken token = new TestingAuthenticationToken("user",
|
||||||
@ -102,6 +107,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testNormalOperation() throws Exception {
|
public void testNormalOperation() throws Exception {
|
||||||
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
||||||
|
aap.setMessageSource(new StaticMessageSource());
|
||||||
aap.setKey("qwerty");
|
aap.setKey("qwerty");
|
||||||
|
|
||||||
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("qwerty",
|
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken("qwerty",
|
||||||
@ -116,6 +122,7 @@ public class AnonymousAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testSupports() {
|
public void testSupports() {
|
||||||
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
AnonymousAuthenticationProvider aap = new AnonymousAuthenticationProvider();
|
||||||
|
aap.setMessageSource(new StaticMessageSource());
|
||||||
assertTrue(aap.supports(AnonymousAuthenticationToken.class));
|
assertTrue(aap.supports(AnonymousAuthenticationToken.class));
|
||||||
assertFalse(aap.supports(TestingAuthenticationToken.class));
|
assertFalse(aap.supports(TestingAuthenticationToken.class));
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
|||||||
import org.acegisecurity.providers.cas.ticketvalidator.AbstractTicketValidator;
|
import org.acegisecurity.providers.cas.ticketvalidator.AbstractTicketValidator;
|
||||||
import org.acegisecurity.providers.dao.User;
|
import org.acegisecurity.providers.dao.User;
|
||||||
import org.acegisecurity.ui.cas.CasProcessingFilter;
|
import org.acegisecurity.ui.cas.CasProcessingFilter;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -64,6 +65,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testAuthenticateStateful() throws Exception {
|
public void testAuthenticateStateful() throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||||
cap.setCasProxyDecider(new MockProxyDecider(true));
|
cap.setCasProxyDecider(new MockProxyDecider(true));
|
||||||
cap.setKey("qwerty");
|
cap.setKey("qwerty");
|
||||||
@ -108,6 +110,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testAuthenticateStateless() throws Exception {
|
public void testAuthenticateStateless() throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||||
cap.setCasProxyDecider(new MockProxyDecider(true));
|
cap.setCasProxyDecider(new MockProxyDecider(true));
|
||||||
cap.setKey("qwerty");
|
cap.setKey("qwerty");
|
||||||
@ -144,6 +147,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testDetectsAMissingTicketId() throws Exception {
|
public void testDetectsAMissingTicketId() throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||||
cap.setCasProxyDecider(new MockProxyDecider(true));
|
cap.setCasProxyDecider(new MockProxyDecider(true));
|
||||||
cap.setKey("qwerty");
|
cap.setKey("qwerty");
|
||||||
@ -167,6 +171,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testDetectsAnInvalidKey() throws Exception {
|
public void testDetectsAnInvalidKey() throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||||
cap.setCasProxyDecider(new MockProxyDecider(true));
|
cap.setCasProxyDecider(new MockProxyDecider(true));
|
||||||
cap.setKey("qwerty");
|
cap.setKey("qwerty");
|
||||||
@ -193,6 +198,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
public void testDetectsMissingAuthoritiesPopulator()
|
public void testDetectsMissingAuthoritiesPopulator()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasProxyDecider(new MockProxyDecider());
|
cap.setCasProxyDecider(new MockProxyDecider());
|
||||||
cap.setKey("qwerty");
|
cap.setKey("qwerty");
|
||||||
cap.setStatelessTicketCache(new MockStatelessTicketCache());
|
cap.setStatelessTicketCache(new MockStatelessTicketCache());
|
||||||
@ -209,6 +215,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testDetectsMissingKey() throws Exception {
|
public void testDetectsMissingKey() throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||||
cap.setCasProxyDecider(new MockProxyDecider());
|
cap.setCasProxyDecider(new MockProxyDecider());
|
||||||
cap.setStatelessTicketCache(new MockStatelessTicketCache());
|
cap.setStatelessTicketCache(new MockStatelessTicketCache());
|
||||||
@ -225,6 +232,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testDetectsMissingProxyDecider() throws Exception {
|
public void testDetectsMissingProxyDecider() throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||||
cap.setKey("qwerty");
|
cap.setKey("qwerty");
|
||||||
cap.setStatelessTicketCache(new MockStatelessTicketCache());
|
cap.setStatelessTicketCache(new MockStatelessTicketCache());
|
||||||
@ -241,6 +249,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
public void testDetectsMissingStatelessTicketCache()
|
public void testDetectsMissingStatelessTicketCache()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||||
cap.setCasProxyDecider(new MockProxyDecider());
|
cap.setCasProxyDecider(new MockProxyDecider());
|
||||||
cap.setKey("qwerty");
|
cap.setKey("qwerty");
|
||||||
@ -257,6 +266,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testDetectsMissingTicketValidator() throws Exception {
|
public void testDetectsMissingTicketValidator() throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||||
cap.setCasProxyDecider(new MockProxyDecider(true));
|
cap.setCasProxyDecider(new MockProxyDecider(true));
|
||||||
cap.setKey("qwerty");
|
cap.setKey("qwerty");
|
||||||
@ -272,6 +282,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testGettersSetters() throws Exception {
|
public void testGettersSetters() throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||||
cap.setCasProxyDecider(new MockProxyDecider());
|
cap.setCasProxyDecider(new MockProxyDecider());
|
||||||
cap.setKey("qwerty");
|
cap.setKey("qwerty");
|
||||||
@ -288,6 +299,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testIgnoresClassesItDoesNotSupport() throws Exception {
|
public void testIgnoresClassesItDoesNotSupport() throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||||
cap.setCasProxyDecider(new MockProxyDecider());
|
cap.setCasProxyDecider(new MockProxyDecider());
|
||||||
cap.setKey("qwerty");
|
cap.setKey("qwerty");
|
||||||
@ -307,6 +319,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
public void testIgnoresUsernamePasswordAuthenticationTokensWithoutCasIdentifiersAsPrincipal()
|
public void testIgnoresUsernamePasswordAuthenticationTokensWithoutCasIdentifiersAsPrincipal()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
cap.setCasAuthoritiesPopulator(new MockAuthoritiesPopulator());
|
||||||
cap.setCasProxyDecider(new MockProxyDecider());
|
cap.setCasProxyDecider(new MockProxyDecider());
|
||||||
cap.setKey("qwerty");
|
cap.setKey("qwerty");
|
||||||
@ -322,6 +335,7 @@ public class CasAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testSupports() {
|
public void testSupports() {
|
||||||
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
CasAuthenticationProvider cap = new CasAuthenticationProvider();
|
||||||
|
cap.setMessageSource(new StaticMessageSource());
|
||||||
assertTrue(cap.supports(UsernamePasswordAuthenticationToken.class));
|
assertTrue(cap.supports(UsernamePasswordAuthenticationToken.class));
|
||||||
assertTrue(cap.supports(CasAuthenticationToken.class));
|
assertTrue(cap.supports(CasAuthenticationToken.class));
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -19,15 +19,14 @@ import junit.framework.TestCase;
|
|||||||
|
|
||||||
import org.acegisecurity.providers.cas.ProxyUntrustedException;
|
import org.acegisecurity.providers.cas.ProxyUntrustedException;
|
||||||
|
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link NamedCasProxyDecider}.
|
* Tests {@link NamedCasProxyDecider}.
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class NamedCasProxyDeciderTests extends TestCase {
|
public class NamedCasProxyDeciderTests extends TestCase {
|
||||||
//~ Constructors ===========================================================
|
//~ Constructors ===========================================================
|
||||||
@ -42,17 +41,18 @@ public class NamedCasProxyDeciderTests extends TestCase {
|
|||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public final void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
junit.textui.TestRunner.run(NamedCasProxyDeciderTests.class);
|
junit.textui.TestRunner.run(NamedCasProxyDeciderTests.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
}
|
||||||
|
|
||||||
public void testAcceptsIfNearestProxyIsAuthorized()
|
public void testAcceptsIfNearestProxyIsAuthorized()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
||||||
|
proxyDecider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
// Build the ticket returned from CAS
|
// Build the ticket returned from CAS
|
||||||
List proxyList = new Vector();
|
List proxyList = new Vector();
|
||||||
@ -72,6 +72,8 @@ public class NamedCasProxyDeciderTests extends TestCase {
|
|||||||
|
|
||||||
public void testAcceptsIfNoProxiesInTicket() {
|
public void testAcceptsIfNoProxiesInTicket() {
|
||||||
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
||||||
|
proxyDecider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
List proxyList = new Vector(); // no proxies in list
|
List proxyList = new Vector(); // no proxies in list
|
||||||
|
|
||||||
proxyDecider.confirmProxyListTrusted(proxyList);
|
proxyDecider.confirmProxyListTrusted(proxyList);
|
||||||
@ -80,6 +82,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
|
|||||||
|
|
||||||
public void testDetectsMissingValidProxiesList() throws Exception {
|
public void testDetectsMissingValidProxiesList() throws Exception {
|
||||||
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
||||||
|
proxyDecider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
proxyDecider.afterPropertiesSet();
|
proxyDecider.afterPropertiesSet();
|
||||||
@ -92,6 +95,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
|
|||||||
|
|
||||||
public void testDoesNotAcceptNull() {
|
public void testDoesNotAcceptNull() {
|
||||||
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
||||||
|
proxyDecider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
proxyDecider.confirmProxyListTrusted(null);
|
proxyDecider.confirmProxyListTrusted(null);
|
||||||
@ -103,6 +107,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
|
|||||||
|
|
||||||
public void testGettersSetters() {
|
public void testGettersSetters() {
|
||||||
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
||||||
|
proxyDecider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
// Build the list of valid nearest proxies
|
// Build the list of valid nearest proxies
|
||||||
List validProxies = new Vector();
|
List validProxies = new Vector();
|
||||||
@ -117,6 +122,7 @@ public class NamedCasProxyDeciderTests extends TestCase {
|
|||||||
public void testRejectsIfNearestProxyIsNotAuthorized()
|
public void testRejectsIfNearestProxyIsNotAuthorized()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
NamedCasProxyDecider proxyDecider = new NamedCasProxyDecider();
|
||||||
|
proxyDecider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
// Build the ticket returned from CAS
|
// Build the ticket returned from CAS
|
||||||
List proxyList = new Vector();
|
List proxyList = new Vector();
|
||||||
|
@ -18,6 +18,7 @@ package org.acegisecurity.providers.cas.proxy;
|
|||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.acegisecurity.providers.cas.ProxyUntrustedException;
|
import org.acegisecurity.providers.cas.ProxyUntrustedException;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
@ -71,6 +72,7 @@ public class RejectProxyTicketsTests extends TestCase {
|
|||||||
|
|
||||||
public void testRejectsIfAnyProxyInList() {
|
public void testRejectsIfAnyProxyInList() {
|
||||||
RejectProxyTickets proxyDecider = new RejectProxyTickets();
|
RejectProxyTickets proxyDecider = new RejectProxyTickets();
|
||||||
|
proxyDecider.setMessageSource(new StaticMessageSource());
|
||||||
List proxyList = new Vector();
|
List proxyList = new Vector();
|
||||||
proxyList.add("https://localhost/webApp/j_acegi_cas_security_check");
|
proxyList.add("https://localhost/webApp/j_acegi_cas_security_check");
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ import org.acegisecurity.providers.dao.cache.NullUserCache;
|
|||||||
import org.acegisecurity.providers.dao.salt.SystemWideSaltSource;
|
import org.acegisecurity.providers.dao.salt.SystemWideSaltSource;
|
||||||
import org.acegisecurity.providers.encoding.ShaPasswordEncoder;
|
import org.acegisecurity.providers.encoding.ShaPasswordEncoder;
|
||||||
|
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.dao.DataRetrievalFailureException;
|
import org.springframework.dao.DataRetrievalFailureException;
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"KOala");
|
"KOala");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
|
|
||||||
@ -79,6 +81,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"opal");
|
"opal");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterAccountExpired());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterAccountExpired());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
|
|
||||||
@ -95,6 +98,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"opal");
|
"opal");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterAccountLocked());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterAccountLocked());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
|
|
||||||
@ -111,6 +115,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"opal");
|
"opal");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterCredentialsExpired());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeterCredentialsExpired());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
|
|
||||||
@ -138,6 +143,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"opal");
|
"opal");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeter());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserPeter());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
|
|
||||||
@ -154,6 +160,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"koala");
|
"koala");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoSimulateBackendError());
|
provider.setAuthenticationDao(new MockAuthenticationDaoSimulateBackendError());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
|
|
||||||
@ -170,6 +177,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"koala");
|
"koala");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
|
|
||||||
@ -186,6 +194,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"INVALID_PASSWORD");
|
"INVALID_PASSWORD");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
|
|
||||||
@ -202,6 +211,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"koala");
|
"koala");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setHideUserNotFoundExceptions(false); // we want UsernameNotFoundExceptions
|
provider.setHideUserNotFoundExceptions(false); // we want UsernameNotFoundExceptions
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
@ -219,6 +229,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"koala");
|
"koala");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
assertTrue(provider.isHideUserNotFoundExceptions());
|
assertTrue(provider.isHideUserNotFoundExceptions());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
@ -236,6 +247,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"koala");
|
"koala");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
|
|
||||||
@ -253,6 +265,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
token.setDetails("192.168.0.1");
|
token.setDetails("192.168.0.1");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
|
|
||||||
@ -276,6 +289,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"koala");
|
"koala");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
|
|
||||||
@ -305,6 +319,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
salt.setSystemWideSalt("SYSTEM_SALT_VALUE");
|
salt.setSystemWideSalt("SYSTEM_SALT_VALUE");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissaWithSalt());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissaWithSalt());
|
||||||
provider.setSaltSource(salt);
|
provider.setSaltSource(salt);
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
@ -330,6 +345,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"koala");
|
"koala");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
provider.setForcePrincipalAsString(true);
|
provider.setForcePrincipalAsString(true);
|
||||||
@ -351,6 +367,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
"koala");
|
"koala");
|
||||||
|
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoReturnsNull());
|
provider.setAuthenticationDao(new MockAuthenticationDaoReturnsNull());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -364,6 +381,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testGettersSetters() {
|
public void testGettersSetters() {
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setPasswordEncoder(new ShaPasswordEncoder());
|
provider.setPasswordEncoder(new ShaPasswordEncoder());
|
||||||
assertEquals(ShaPasswordEncoder.class,
|
assertEquals(ShaPasswordEncoder.class,
|
||||||
provider.getPasswordEncoder().getClass());
|
provider.getPasswordEncoder().getClass());
|
||||||
@ -388,6 +406,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
MockAuthenticationDaoUserMarissa authenticationDao = new MockAuthenticationDaoUserMarissa();
|
MockAuthenticationDaoUserMarissa authenticationDao = new MockAuthenticationDaoUserMarissa();
|
||||||
MockUserCache cache = new MockUserCache();
|
MockUserCache cache = new MockUserCache();
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(authenticationDao);
|
provider.setAuthenticationDao(authenticationDao);
|
||||||
provider.setUserCache(cache);
|
provider.setUserCache(cache);
|
||||||
|
|
||||||
@ -414,6 +433,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
public void testStartupFailsIfNoAuthenticationDao()
|
public void testStartupFailsIfNoAuthenticationDao()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
provider.afterPropertiesSet();
|
provider.afterPropertiesSet();
|
||||||
@ -425,6 +445,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testStartupFailsIfNoUserCacheSet() throws Exception {
|
public void testStartupFailsIfNoUserCacheSet() throws Exception {
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
provider.setAuthenticationDao(new MockAuthenticationDaoUserMarissa());
|
||||||
assertEquals(NullUserCache.class, provider.getUserCache().getClass());
|
assertEquals(NullUserCache.class, provider.getUserCache().getClass());
|
||||||
provider.setUserCache(null);
|
provider.setUserCache(null);
|
||||||
@ -439,6 +460,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testStartupSuccess() throws Exception {
|
public void testStartupSuccess() throws Exception {
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
AuthenticationDao dao = new MockAuthenticationDaoUserMarissa();
|
AuthenticationDao dao = new MockAuthenticationDaoUserMarissa();
|
||||||
provider.setAuthenticationDao(dao);
|
provider.setAuthenticationDao(dao);
|
||||||
provider.setUserCache(new MockUserCache());
|
provider.setUserCache(new MockUserCache());
|
||||||
@ -449,6 +471,7 @@ public class DaoAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testSupports() {
|
public void testSupports() {
|
||||||
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
assertTrue(provider.supports(UsernamePasswordAuthenticationToken.class));
|
assertTrue(provider.supports(UsernamePasswordAuthenticationToken.class));
|
||||||
assertTrue(!provider.supports(TestingAuthenticationToken.class));
|
assertTrue(!provider.supports(TestingAuthenticationToken.class));
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import org.acegisecurity.BadCredentialsException;
|
|||||||
import org.acegisecurity.GrantedAuthority;
|
import org.acegisecurity.GrantedAuthority;
|
||||||
import org.acegisecurity.GrantedAuthorityImpl;
|
import org.acegisecurity.GrantedAuthorityImpl;
|
||||||
import org.acegisecurity.providers.TestingAuthenticationToken;
|
import org.acegisecurity.providers.TestingAuthenticationToken;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,6 +54,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testDetectsAnInvalidKey() throws Exception {
|
public void testDetectsAnInvalidKey() throws Exception {
|
||||||
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
|
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
|
||||||
|
aap.setMessageSource(new StaticMessageSource());
|
||||||
aap.setKey("qwerty");
|
aap.setKey("qwerty");
|
||||||
|
|
||||||
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("WRONG_KEY",
|
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("WRONG_KEY",
|
||||||
@ -71,6 +73,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testDetectsMissingKey() throws Exception {
|
public void testDetectsMissingKey() throws Exception {
|
||||||
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
|
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
|
||||||
|
aap.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
aap.afterPropertiesSet();
|
aap.afterPropertiesSet();
|
||||||
@ -82,6 +85,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testGettersSetters() throws Exception {
|
public void testGettersSetters() throws Exception {
|
||||||
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
|
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
|
||||||
|
aap.setMessageSource(new StaticMessageSource());
|
||||||
aap.setKey("qwerty");
|
aap.setKey("qwerty");
|
||||||
aap.afterPropertiesSet();
|
aap.afterPropertiesSet();
|
||||||
assertEquals("qwerty", aap.getKey());
|
assertEquals("qwerty", aap.getKey());
|
||||||
@ -102,6 +106,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testNormalOperation() throws Exception {
|
public void testNormalOperation() throws Exception {
|
||||||
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
|
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
|
||||||
|
aap.setMessageSource(new StaticMessageSource());
|
||||||
aap.setKey("qwerty");
|
aap.setKey("qwerty");
|
||||||
|
|
||||||
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("qwerty",
|
RememberMeAuthenticationToken token = new RememberMeAuthenticationToken("qwerty",
|
||||||
@ -116,6 +121,7 @@ public class RememberMeAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testSupports() {
|
public void testSupports() {
|
||||||
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
|
RememberMeAuthenticationProvider aap = new RememberMeAuthenticationProvider();
|
||||||
|
aap.setMessageSource(new StaticMessageSource());
|
||||||
assertTrue(aap.supports(RememberMeAuthenticationToken.class));
|
assertTrue(aap.supports(RememberMeAuthenticationToken.class));
|
||||||
assertFalse(aap.supports(TestingAuthenticationToken.class));
|
assertFalse(aap.supports(TestingAuthenticationToken.class));
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import junit.framework.TestCase;
|
|||||||
import org.acegisecurity.*;
|
import org.acegisecurity.*;
|
||||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
import org.acegisecurity.providers.dao.User;
|
import org.acegisecurity.providers.dao.User;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
@ -49,6 +50,7 @@ public class X509AuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testAuthenticationIsNullWithUnsupportedToken() {
|
public void testAuthenticationIsNullWithUnsupportedToken() {
|
||||||
X509AuthenticationProvider provider = new X509AuthenticationProvider();
|
X509AuthenticationProvider provider = new X509AuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
Authentication request = new UsernamePasswordAuthenticationToken("dummy",
|
Authentication request = new UsernamePasswordAuthenticationToken("dummy",
|
||||||
"dummy");
|
"dummy");
|
||||||
Authentication result = provider.authenticate(request);
|
Authentication result = provider.authenticate(request);
|
||||||
@ -57,6 +59,7 @@ public class X509AuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testFailsWithNullCertificate() {
|
public void testFailsWithNullCertificate() {
|
||||||
X509AuthenticationProvider provider = new X509AuthenticationProvider();
|
X509AuthenticationProvider provider = new X509AuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(false));
|
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(false));
|
||||||
|
|
||||||
@ -70,6 +73,7 @@ public class X509AuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testNormalOperation() throws Exception {
|
public void testNormalOperation() throws Exception {
|
||||||
X509AuthenticationProvider provider = new X509AuthenticationProvider();
|
X509AuthenticationProvider provider = new X509AuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(false));
|
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(false));
|
||||||
provider.afterPropertiesSet();
|
provider.afterPropertiesSet();
|
||||||
@ -82,6 +86,7 @@ public class X509AuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testPopulatorRejectionCausesFailure() throws Exception {
|
public void testPopulatorRejectionCausesFailure() throws Exception {
|
||||||
X509AuthenticationProvider provider = new X509AuthenticationProvider();
|
X509AuthenticationProvider provider = new X509AuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(true));
|
provider.setX509AuthoritiesPopulator(new MockAuthoritiesPopulator(true));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -94,6 +99,7 @@ public class X509AuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
public void testRequiresPopulator() throws Exception {
|
public void testRequiresPopulator() throws Exception {
|
||||||
X509AuthenticationProvider provider = new X509AuthenticationProvider();
|
X509AuthenticationProvider provider = new X509AuthenticationProvider();
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
provider.afterPropertiesSet();
|
provider.afterPropertiesSet();
|
||||||
|
@ -26,6 +26,7 @@ import org.acegisecurity.providers.dao.User;
|
|||||||
import org.acegisecurity.providers.dao.UsernameNotFoundException;
|
import org.acegisecurity.providers.dao.UsernameNotFoundException;
|
||||||
import org.acegisecurity.providers.x509.X509TestUtils;
|
import org.acegisecurity.providers.x509.X509TestUtils;
|
||||||
|
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
@ -56,6 +57,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
|
|||||||
public void testDefaultCNPatternMatch() throws Exception {
|
public void testDefaultCNPatternMatch() throws Exception {
|
||||||
X509Certificate cert = X509TestUtils.buildTestCertificate();
|
X509Certificate cert = X509TestUtils.buildTestCertificate();
|
||||||
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
||||||
|
populator.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
|
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
|
||||||
populator.afterPropertiesSet();
|
populator.afterPropertiesSet();
|
||||||
@ -65,6 +67,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
|
|||||||
public void testEmailPatternMatch() throws Exception {
|
public void testEmailPatternMatch() throws Exception {
|
||||||
X509Certificate cert = X509TestUtils.buildTestCertificate();
|
X509Certificate cert = X509TestUtils.buildTestCertificate();
|
||||||
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
||||||
|
populator.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
|
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
|
||||||
populator.setSubjectDNRegex("emailAddress=(.*?),");
|
populator.setSubjectDNRegex("emailAddress=(.*?),");
|
||||||
@ -74,6 +77,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
|
|||||||
|
|
||||||
public void testInvalidRegexFails() throws Exception {
|
public void testInvalidRegexFails() throws Exception {
|
||||||
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
||||||
|
populator.setMessageSource(new StaticMessageSource());
|
||||||
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
|
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
|
||||||
populator.setSubjectDNRegex("CN=(.*?,"); // missing closing bracket on group
|
populator.setSubjectDNRegex("CN=(.*?,"); // missing closing bracket on group
|
||||||
|
|
||||||
@ -88,6 +92,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
|
|||||||
public void testMatchOnShoeSizeFieldInDNFails() throws Exception {
|
public void testMatchOnShoeSizeFieldInDNFails() throws Exception {
|
||||||
X509Certificate cert = X509TestUtils.buildTestCertificate();
|
X509Certificate cert = X509TestUtils.buildTestCertificate();
|
||||||
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
||||||
|
populator.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
|
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
|
||||||
populator.setSubjectDNRegex("shoeSize=(.*?),");
|
populator.setSubjectDNRegex("shoeSize=(.*?),");
|
||||||
@ -104,6 +109,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
|
|||||||
public void testPatternWithNoGroupFails() throws Exception {
|
public void testPatternWithNoGroupFails() throws Exception {
|
||||||
X509Certificate cert = X509TestUtils.buildTestCertificate();
|
X509Certificate cert = X509TestUtils.buildTestCertificate();
|
||||||
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
||||||
|
populator.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
|
populator.setAuthenticationDao(new MockAuthenticationDaoMatchesNameOrEmail());
|
||||||
populator.setSubjectDNRegex("CN=.*?,");
|
populator.setSubjectDNRegex("CN=.*?,");
|
||||||
@ -120,6 +126,7 @@ public class DaoX509AuthoritiesPopulatorTests extends TestCase {
|
|||||||
|
|
||||||
public void testRequiresDao() throws Exception {
|
public void testRequiresDao() throws Exception {
|
||||||
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
DaoX509AuthoritiesPopulator populator = new DaoX509AuthoritiesPopulator();
|
||||||
|
populator.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
populator.afterPropertiesSet();
|
populator.afterPropertiesSet();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright 2004 Acegi Technology Pty Limited
|
/* Copyright 2004, 2005 Acegi Technology Pty Limited
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -21,15 +21,15 @@ import org.acegisecurity.Authentication;
|
|||||||
import org.acegisecurity.BadCredentialsException;
|
import org.acegisecurity.BadCredentialsException;
|
||||||
import org.acegisecurity.GrantedAuthority;
|
import org.acegisecurity.GrantedAuthority;
|
||||||
import org.acegisecurity.GrantedAuthorityImpl;
|
import org.acegisecurity.GrantedAuthorityImpl;
|
||||||
|
|
||||||
import org.acegisecurity.providers.TestingAuthenticationToken;
|
import org.acegisecurity.providers.TestingAuthenticationToken;
|
||||||
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
|
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link RunAsImplAuthenticationProvider}.
|
* Tests {@link RunAsImplAuthenticationProvider}.
|
||||||
*
|
|
||||||
* @author Ben Alex
|
|
||||||
* @version $Id$
|
|
||||||
*/
|
*/
|
||||||
public class RunAsImplAuthenticationProviderTests extends TestCase {
|
public class RunAsImplAuthenticationProviderTests extends TestCase {
|
||||||
//~ Constructors ===========================================================
|
//~ Constructors ===========================================================
|
||||||
@ -44,14 +44,14 @@ public class RunAsImplAuthenticationProviderTests extends TestCase {
|
|||||||
|
|
||||||
//~ Methods ================================================================
|
//~ Methods ================================================================
|
||||||
|
|
||||||
public final void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
junit.textui.TestRunner.run(RunAsImplAuthenticationProviderTests.class);
|
junit.textui.TestRunner.run(RunAsImplAuthenticationProviderTests.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
}
|
||||||
|
|
||||||
public void testAuthenticationFailDueToWrongKey() {
|
public void testAuthenticationFailDueToWrongKey() {
|
||||||
RunAsUserToken token = new RunAsUserToken("WRONG_PASSWORD", "Test",
|
RunAsUserToken token = new RunAsUserToken("WRONG_PASSWORD", "Test",
|
||||||
"Password",
|
"Password",
|
||||||
@ -59,6 +59,7 @@ public class RunAsImplAuthenticationProviderTests extends TestCase {
|
|||||||
"ROLE_TWO")}, UsernamePasswordAuthenticationToken.class);
|
"ROLE_TWO")}, UsernamePasswordAuthenticationToken.class);
|
||||||
RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider();
|
RunAsImplAuthenticationProvider provider = new RunAsImplAuthenticationProvider();
|
||||||
provider.setKey("hello_world");
|
provider.setKey("hello_world");
|
||||||
|
provider.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
provider.authenticate(token);
|
provider.authenticate(token);
|
||||||
|
@ -31,6 +31,7 @@ import org.acegisecurity.providers.dao.User;
|
|||||||
import org.acegisecurity.providers.dao.UsernameNotFoundException;
|
import org.acegisecurity.providers.dao.UsernameNotFoundException;
|
||||||
import org.acegisecurity.util.MockFilterChain;
|
import org.acegisecurity.util.MockFilterChain;
|
||||||
|
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.mock.web.MockHttpServletResponse;
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
@ -74,6 +75,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
"user-that-doesnt-exist");
|
"user-that-doesnt-exist");
|
||||||
|
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -97,6 +99,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
"mcgarrett");
|
"mcgarrett");
|
||||||
|
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -122,6 +125,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
"wofat");
|
"wofat");
|
||||||
|
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -147,6 +151,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
"steve");
|
"steve");
|
||||||
|
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -169,6 +174,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
"jacklord");
|
"jacklord");
|
||||||
|
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
||||||
|
|
||||||
Authentication result = filter.attemptSwitchUser(request);
|
Authentication result = filter.attemptSwitchUser(request);
|
||||||
@ -177,6 +183,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
|
|
||||||
public void testBadConfigMissingAuthenticationDao() {
|
public void testBadConfigMissingAuthenticationDao() {
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setSwitchUserUrl("/j_acegi_switch_user");
|
filter.setSwitchUserUrl("/j_acegi_switch_user");
|
||||||
filter.setExitUserUrl("/j_acegi_exit_user");
|
filter.setExitUserUrl("/j_acegi_exit_user");
|
||||||
filter.setTargetUrl("/main.jsp");
|
filter.setTargetUrl("/main.jsp");
|
||||||
@ -191,6 +198,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
|
|
||||||
public void testBadConfigMissingTargetUrl() {
|
public void testBadConfigMissingTargetUrl() {
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
||||||
filter.setSwitchUserUrl("/j_acegi_switch_user");
|
filter.setSwitchUserUrl("/j_acegi_switch_user");
|
||||||
filter.setExitUserUrl("/j_acegi_exit_user");
|
filter.setExitUserUrl("/j_acegi_exit_user");
|
||||||
@ -206,6 +214,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
public void testDefaultProcessesFilterUrlWithPathParameter() {
|
public void testDefaultProcessesFilterUrlWithPathParameter() {
|
||||||
MockHttpServletRequest request = createMockSwitchRequest();
|
MockHttpServletRequest request = createMockSwitchRequest();
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setSwitchUserUrl("/j_acegi_switch_user");
|
filter.setSwitchUserUrl("/j_acegi_switch_user");
|
||||||
|
|
||||||
request.setRequestURI(
|
request.setRequestURI(
|
||||||
@ -238,6 +247,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
|
|
||||||
// setup filter
|
// setup filter
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
||||||
filter.setExitUserUrl("/j_acegi_exit_user");
|
filter.setExitUserUrl("/j_acegi_exit_user");
|
||||||
|
|
||||||
@ -266,6 +276,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
|
|
||||||
// setup filter
|
// setup filter
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
||||||
filter.setExitUserUrl("/j_acegi_exit_user");
|
filter.setExitUserUrl("/j_acegi_exit_user");
|
||||||
|
|
||||||
@ -294,6 +305,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
MockFilterChain chain = new MockFilterChain(true);
|
MockFilterChain chain = new MockFilterChain(true);
|
||||||
|
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setSwitchUserUrl("/j_acegi_switch_user");
|
filter.setSwitchUserUrl("/j_acegi_switch_user");
|
||||||
filter.setTargetUrl("/webapp/someOtherUrl");
|
filter.setTargetUrl("/webapp/someOtherUrl");
|
||||||
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
||||||
@ -343,6 +355,7 @@ public class SwitchUserProcessingFilterTests extends TestCase {
|
|||||||
|
|
||||||
// setup filter
|
// setup filter
|
||||||
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
SwitchUserProcessingFilter filter = new SwitchUserProcessingFilter();
|
||||||
|
filter.setMessageSource(new StaticMessageSource());
|
||||||
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
filter.setAuthenticationDao(new MockAuthenticationDaoUserJackLord());
|
||||||
filter.setSwitchUserUrl("/j_acegi_switch_user");
|
filter.setSwitchUserUrl("/j_acegi_switch_user");
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
|
|||||||
import org.acegisecurity.GrantedAuthorityImpl;
|
import org.acegisecurity.GrantedAuthorityImpl;
|
||||||
import org.acegisecurity.SecurityConfig;
|
import org.acegisecurity.SecurityConfig;
|
||||||
import org.acegisecurity.providers.TestingAuthenticationToken;
|
import org.acegisecurity.providers.TestingAuthenticationToken;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
@ -143,6 +144,7 @@ public class AffirmativeBasedTests extends TestCase {
|
|||||||
|
|
||||||
private AffirmativeBased makeDecisionManager() {
|
private AffirmativeBased makeDecisionManager() {
|
||||||
AffirmativeBased decisionManager = new AffirmativeBased();
|
AffirmativeBased decisionManager = new AffirmativeBased();
|
||||||
|
decisionManager.setMessageSource(new StaticMessageSource());
|
||||||
RoleVoter roleVoter = new RoleVoter();
|
RoleVoter roleVoter = new RoleVoter();
|
||||||
DenyVoter denyForSureVoter = new DenyVoter();
|
DenyVoter denyForSureVoter = new DenyVoter();
|
||||||
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
|
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
|
||||||
|
@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
|
|||||||
import org.acegisecurity.GrantedAuthorityImpl;
|
import org.acegisecurity.GrantedAuthorityImpl;
|
||||||
import org.acegisecurity.SecurityConfig;
|
import org.acegisecurity.SecurityConfig;
|
||||||
import org.acegisecurity.providers.TestingAuthenticationToken;
|
import org.acegisecurity.providers.TestingAuthenticationToken;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
@ -164,6 +165,7 @@ public class ConsensusBasedTests extends TestCase {
|
|||||||
|
|
||||||
private ConsensusBased makeDecisionManager() {
|
private ConsensusBased makeDecisionManager() {
|
||||||
ConsensusBased decisionManager = new ConsensusBased();
|
ConsensusBased decisionManager = new ConsensusBased();
|
||||||
|
decisionManager.setMessageSource(new StaticMessageSource());
|
||||||
RoleVoter roleVoter = new RoleVoter();
|
RoleVoter roleVoter = new RoleVoter();
|
||||||
DenyVoter denyForSureVoter = new DenyVoter();
|
DenyVoter denyForSureVoter = new DenyVoter();
|
||||||
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
|
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
|
||||||
|
@ -23,6 +23,7 @@ import org.acegisecurity.GrantedAuthority;
|
|||||||
import org.acegisecurity.GrantedAuthorityImpl;
|
import org.acegisecurity.GrantedAuthorityImpl;
|
||||||
import org.acegisecurity.SecurityConfig;
|
import org.acegisecurity.SecurityConfig;
|
||||||
import org.acegisecurity.providers.TestingAuthenticationToken;
|
import org.acegisecurity.providers.TestingAuthenticationToken;
|
||||||
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
@ -59,6 +60,7 @@ public class UnanimousBasedTests extends TestCase {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
TestingAuthenticationToken auth = makeTestToken();
|
TestingAuthenticationToken auth = makeTestToken();
|
||||||
UnanimousBased mgr = makeDecisionManager();
|
UnanimousBased mgr = makeDecisionManager();
|
||||||
|
mgr.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
||||||
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
|
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
|
||||||
@ -76,6 +78,7 @@ public class UnanimousBasedTests extends TestCase {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
TestingAuthenticationToken auth = makeTestToken();
|
TestingAuthenticationToken auth = makeTestToken();
|
||||||
UnanimousBased mgr = makeDecisionManager();
|
UnanimousBased mgr = makeDecisionManager();
|
||||||
|
mgr.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
||||||
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
|
config.addConfigAttribute(new SecurityConfig("ROLE_2")); // grant
|
||||||
@ -88,6 +91,7 @@ public class UnanimousBasedTests extends TestCase {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
TestingAuthenticationToken auth = makeTestToken();
|
TestingAuthenticationToken auth = makeTestToken();
|
||||||
UnanimousBased mgr = makeDecisionManager();
|
UnanimousBased mgr = makeDecisionManager();
|
||||||
|
mgr.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
||||||
config.addConfigAttribute(new SecurityConfig("ROLE_WE_DO_NOT_HAVE")); // deny
|
config.addConfigAttribute(new SecurityConfig("ROLE_WE_DO_NOT_HAVE")); // deny
|
||||||
@ -103,6 +107,7 @@ public class UnanimousBasedTests extends TestCase {
|
|||||||
public void testRoleVoterPrefixObserved() throws Exception {
|
public void testRoleVoterPrefixObserved() throws Exception {
|
||||||
TestingAuthenticationToken auth = makeTestTokenWithFooBarPrefix();
|
TestingAuthenticationToken auth = makeTestTokenWithFooBarPrefix();
|
||||||
UnanimousBased mgr = makeDecisionManagerWithFooBarPrefix();
|
UnanimousBased mgr = makeDecisionManagerWithFooBarPrefix();
|
||||||
|
mgr.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
||||||
config.addConfigAttribute(new SecurityConfig("FOOBAR_1")); // grant
|
config.addConfigAttribute(new SecurityConfig("FOOBAR_1")); // grant
|
||||||
@ -116,6 +121,7 @@ public class UnanimousBasedTests extends TestCase {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
TestingAuthenticationToken auth = makeTestToken();
|
TestingAuthenticationToken auth = makeTestToken();
|
||||||
UnanimousBased mgr = makeDecisionManager();
|
UnanimousBased mgr = makeDecisionManager();
|
||||||
|
mgr.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
assertTrue(!mgr.isAllowIfAllAbstainDecisions()); // check default
|
assertTrue(!mgr.isAllowIfAllAbstainDecisions()); // check default
|
||||||
|
|
||||||
@ -135,6 +141,7 @@ public class UnanimousBasedTests extends TestCase {
|
|||||||
TestingAuthenticationToken auth = makeTestToken();
|
TestingAuthenticationToken auth = makeTestToken();
|
||||||
UnanimousBased mgr = makeDecisionManager();
|
UnanimousBased mgr = makeDecisionManager();
|
||||||
mgr.setAllowIfAllAbstainDecisions(true);
|
mgr.setAllowIfAllAbstainDecisions(true);
|
||||||
|
mgr.setMessageSource(new StaticMessageSource());
|
||||||
assertTrue(mgr.isAllowIfAllAbstainDecisions()); // check changed
|
assertTrue(mgr.isAllowIfAllAbstainDecisions()); // check changed
|
||||||
|
|
||||||
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
||||||
@ -148,6 +155,7 @@ public class UnanimousBasedTests extends TestCase {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
TestingAuthenticationToken auth = makeTestToken();
|
TestingAuthenticationToken auth = makeTestToken();
|
||||||
UnanimousBased mgr = makeDecisionManager();
|
UnanimousBased mgr = makeDecisionManager();
|
||||||
|
mgr.setMessageSource(new StaticMessageSource());
|
||||||
|
|
||||||
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
ConfigAttributeDefinition config = new ConfigAttributeDefinition();
|
||||||
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
|
config.addConfigAttribute(new SecurityConfig("ROLE_1")); // grant
|
||||||
@ -159,6 +167,7 @@ public class UnanimousBasedTests extends TestCase {
|
|||||||
|
|
||||||
private UnanimousBased makeDecisionManager() {
|
private UnanimousBased makeDecisionManager() {
|
||||||
UnanimousBased decisionManager = new UnanimousBased();
|
UnanimousBased decisionManager = new UnanimousBased();
|
||||||
|
decisionManager.setMessageSource(new StaticMessageSource());
|
||||||
RoleVoter roleVoter = new RoleVoter();
|
RoleVoter roleVoter = new RoleVoter();
|
||||||
DenyVoter denyForSureVoter = new DenyVoter();
|
DenyVoter denyForSureVoter = new DenyVoter();
|
||||||
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
|
DenyAgainVoter denyAgainForSureVoter = new DenyAgainVoter();
|
||||||
@ -173,6 +182,7 @@ public class UnanimousBasedTests extends TestCase {
|
|||||||
|
|
||||||
private UnanimousBased makeDecisionManagerWithFooBarPrefix() {
|
private UnanimousBased makeDecisionManagerWithFooBarPrefix() {
|
||||||
UnanimousBased decisionManager = new UnanimousBased();
|
UnanimousBased decisionManager = new UnanimousBased();
|
||||||
|
decisionManager.setMessageSource(new StaticMessageSource());
|
||||||
RoleVoter roleVoter = new RoleVoter();
|
RoleVoter roleVoter = new RoleVoter();
|
||||||
roleVoter.setRolePrefix("FOOBAR_");
|
roleVoter.setRolePrefix("FOOBAR_");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user