1
0
mirror of synced 2026-07-08 20:30:04 +00:00

Compare commits

..

37 Commits

Author SHA1 Message Date
Luke Taylor d6d9bc9d6b [maven-release-plugin] copy for tag spring-security-parent-2.0.3 2008-06-23 14:08:17 +00:00
Luke Taylor 2fa991c44f Some reorganization of itest module 2008-06-22 21:42:25 +00:00
Luke Taylor 3ee8733261 SEC-879: Added required BeanPostProcessor to set SessionRegistry is set on namespace registered AbstractProcessingFilter and SessionFixationProtectionFilter when using custom ConcurrentSessionController
http://jira.springframework.org/browse/SEC-879.
2008-06-20 22:08:05 +00:00
Luke Taylor d5ee89bb7c Correct typo in error message. 2008-06-19 15:21:03 +00:00
Luke Taylor ff5bfccdba SEC-892: Linked use of create-session='never' in namespace to corresponding properties in ExceptionTranslationFilter and AbstractProcessingFilter 2008-06-19 13:46:45 +00:00
Scott Battaglia 5b089aea16 SEC-852
provided mechanism to do get a proxy ticket
2008-06-18 17:34:14 +00:00
Scott Battaglia d7f194df78 SEC-886
upgraded to the most recent CAS Client for Java (3.1.3)
2008-06-18 17:22:20 +00:00
Luke Taylor c56d524bd9 SEC-887: Added setter method for account status checker. 2008-06-18 12:00:45 +00:00
Luke Taylor af5f193ec1 SEC-890: Corrected use of dataSource property name in RememberMeBDP. 2008-06-18 10:35:30 +00:00
Luke Taylor 7d79ae5424 SEC-880: Fix incorrect index value. 2008-06-13 10:58:01 +00:00
Luke Taylor 3e5b65bd85 Updated version names etc in petclinic tutorial 2008-06-12 12:23:25 +00:00
Luke Taylor 64b5fa0131 Added OWASP and Spring Framework links to site template 2008-06-11 17:46:43 +00:00
Luke Taylor fe929bf9b9 Added reference to OWASP site to preface of ref manual 2008-06-11 17:35:27 +00:00
Luke Taylor 8a2581c939 Experimental integration test module 2008-06-10 22:17:44 +00:00
Luke Taylor 55caab3bbc Added spring-jdbc dep back in core-tiger (since it's optional in core) hence not transient) 2008-06-10 22:00:27 +00:00
Luke Taylor 269865ca65 Removed spring deps from core-tiger pom as they are transiently available anyway 2008-06-10 21:41:20 +00:00
Luke Taylor 32b8009bee SEC-875: Removed duplicated parameters from SavedRequestWrapper.getParameterValues() 2008-06-09 23:33:36 +00:00
Luke Taylor 3b775d29d3 SEC-870: Polish messages file contribution 2008-06-08 22:09:47 +00:00
Luke Taylor 0401dddda8 SEC-868: Added example siteminder config 2008-06-08 18:53:22 +00:00
Ben Alex 358f284f42 SEC-760: Correct bug where more than one concurrent JaasAuthenticationProvider used. 2008-06-06 06:13:14 +00:00
Ben Alex b403216494 SEC-838: Make fields in AbstractAclProvider protected to facilitate subclass reuse. 2008-06-06 03:01:51 +00:00
Ben Alex 371769740a SEC-831: Improve support for Postges, which requires "AS" for table aliasing, together with stored procedures for sequence allocation. 2008-06-06 02:55:53 +00:00
Ben Alex e38d5dfd87 SEC-813: Allow custom Permission classes to be used. 2008-06-06 02:37:19 +00:00
Ben Alex ff5666ae83 SEC-819: Properly support integer (and other numeric) identifiers. 2008-06-06 01:05:46 +00:00
Ben Alex de897ad1ac SEC-867: Remove superfluous <property /> entry. 2008-06-05 22:51:47 +00:00
Luke Taylor ff785a829f [maven-release-plugin] prepare for next development iteration 2008-06-03 16:07:20 +00:00
Luke Taylor db1d8604a6 [maven-release-plugin] prepare release spring-security-parent-2.0.2 2008-06-03 16:05:40 +00:00
Luke Taylor f762920239 Typo 2008-06-03 15:49:21 +00:00
Luke Taylor 70826f1202 Shorten faq question 2008-06-03 15:48:30 +00:00
Luke Taylor ea25299bd0 Removed sandbox from build because of site generation problems 2008-06-03 15:37:41 +00:00
Luke Taylor d784d854cd Corrected log file name. 2008-06-03 14:57:40 +00:00
Luke Taylor 9308284bd4 SEC-864: Removed duplicate OpenID provider. 2008-06-03 14:53:43 +00:00
Luke Taylor c34eb497c8 Correct captcha module dependency 2008-06-03 14:11:30 +00:00
Luke Taylor de250d2073 Add sandbox code to build for 2.0.2 release 2008-06-03 13:41:38 +00:00
Luke Taylor 8df56c8ac5 Test log4j properties file for core-tiger module 2008-06-03 13:21:23 +00:00
Luke Taylor 192aa25b60 Addtional sample app files 2008-06-03 13:04:50 +00:00
Luke Taylor d95a5597c8 Bug-testing changes to heavyduty sample 2008-06-03 12:58:13 +00:00
91 changed files with 1739 additions and 370 deletions
+2 -2
View File
@@ -3,13 +3,13 @@
<parent>
<artifactId>spring-security-parent</artifactId>
<groupId>org.springframework.security</groupId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-acl</artifactId>
<name>Spring Security - ACL module</name>
<version>2.0.2</version>
<version>2.0.3</version>
<packaging>bundle</packaging>
<dependencies>
@@ -0,0 +1,59 @@
package org.springframework.security.acls.domain;
import org.springframework.security.acls.AclFormattingUtils;
import org.springframework.security.acls.Permission;
/**
* Provides an abstract superclass for {@link Permission} implementations.
*
* @author Ben Alex
* @since 2.0.3
* @see AbstractRegisteredPermission
*
*/
public abstract class AbstractPermission implements Permission {
//~ Instance fields ================================================================================================
protected char code;
protected int mask;
//~ Constructors ===================================================================================================
protected AbstractPermission(int mask, char code) {
this.mask = mask;
this.code = code;
}
//~ Methods ========================================================================================================
public final boolean equals(Object arg0) {
if (arg0 == null) {
return false;
}
if (!(arg0 instanceof Permission)) {
return false;
}
Permission rhs = (Permission) arg0;
return (this.mask == rhs.getMask());
}
public final int getMask() {
return mask;
}
public String getPattern() {
return AclFormattingUtils.printBinary(mask, code);
}
public final String toString() {
return this.getClass().getSimpleName() + "[" + getPattern() + "=" + mask + "]";
}
public final int hashCode() {
return this.mask;
}
}
@@ -0,0 +1,39 @@
package org.springframework.security.acls.domain;
import org.springframework.security.acls.Permission;
/**
* Provides an abstract base for standard {@link Permission} instances that wish to offer static convenience
* methods to callers via delegation to {@link DefaultPermissionFactory}.
*
* @author Ben Alex
* @since 2.0.3
*
*/
public abstract class AbstractRegisteredPermission extends AbstractPermission {
protected static DefaultPermissionFactory defaultPermissionFactory = new DefaultPermissionFactory();
protected AbstractRegisteredPermission(int mask, char code) {
super(mask, code);
}
protected final static void registerPermissionsFor(Class subClass) {
defaultPermissionFactory.registerPublicPermissions(subClass);
}
public final static Permission buildFromMask(int mask) {
return defaultPermissionFactory.buildFromMask(mask);
}
public final static Permission[] buildFromMask(int[] masks) {
return defaultPermissionFactory.buildFromMask(masks);
}
public final static Permission buildFromName(String name) {
return defaultPermissionFactory.buildFromName(name);
}
public final static Permission[] buildFromName(String[] names) {
return defaultPermissionFactory.buildFromName(names);
}
}
@@ -14,157 +14,36 @@
*/
package org.springframework.security.acls.domain;
import org.springframework.security.acls.AclFormattingUtils;
import org.springframework.security.acls.Permission;
import org.springframework.util.Assert;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* A set of standard permissions.
*
*
* <p>
* You may subclass this class to add additional permissions, or use this class as a guide
* for creating your own permission classes.
* </p>
*
* @author Ben Alex
* @version $Id$
*/
public final class BasePermission implements Permission {
//~ Static fields/initializers =====================================================================================
public class BasePermission extends AbstractRegisteredPermission {
public static final Permission READ = new BasePermission(1 << 0, 'R'); // 1
public static final Permission WRITE = new BasePermission(1 << 1, 'W'); // 2
public static final Permission CREATE = new BasePermission(1 << 2, 'C'); // 4
public static final Permission DELETE = new BasePermission(1 << 3, 'D'); // 8
public static final Permission ADMINISTRATION = new BasePermission(1 << 4, 'A'); // 16
private static Map locallyDeclaredPermissionsByInteger = new HashMap();
private static Map locallyDeclaredPermissionsByName = new HashMap();
static {
Field[] fields = BasePermission.class.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
try {
Object fieldValue = fields[i].get(null);
if (BasePermission.class.isAssignableFrom(fieldValue.getClass())) {
// Found a BasePermission static field
BasePermission perm = (BasePermission) fieldValue;
locallyDeclaredPermissionsByInteger.put(new Integer(perm.getMask()), perm);
locallyDeclaredPermissionsByName.put(fields[i].getName(), perm);
}
} catch (Exception ignore) {}
}
}
//~ Instance fields ================================================================================================
private char code;
private int mask;
//~ Constructors ===================================================================================================
private BasePermission(int mask, char code) {
this.mask = mask;
this.code = code;
}
//~ Methods ========================================================================================================
/**
* Dynamically creates a <code>CumulativePermission</code> or <code>BasePermission</code> representing the
* active bits in the passed mask.
*
* @param mask to build
*
* @return a Permission representing the requested object
* Registers the public static permissions defined on this class. This is mandatory so
* that the static methods will operate correctly.
*/
public static Permission buildFromMask(int mask) {
if (locallyDeclaredPermissionsByInteger.containsKey(new Integer(mask))) {
// The requested mask has an exactly match against a statically-defined BasePermission, so return it
return (Permission) locallyDeclaredPermissionsByInteger.get(new Integer(mask));
}
// To get this far, we have to use a CumulativePermission
CumulativePermission permission = new CumulativePermission();
for (int i = 0; i < 32; i++) {
int permissionToCheck = 1 << i;
if ((mask & permissionToCheck) == permissionToCheck) {
Permission p = (Permission) locallyDeclaredPermissionsByInteger.get(new Integer(permissionToCheck));
Assert.state(p != null,
"Mask " + permissionToCheck + " does not have a corresponding static BasePermission");
permission.set(p);
}
}
return permission;
static {
registerPermissionsFor(BasePermission.class);
}
public static Permission[] buildFromMask(int[] masks) {
if ((masks == null) || (masks.length == 0)) {
return new Permission[0];
}
Permission[] permissions = new Permission[masks.length];
for (int i = 0; i < masks.length; i++) {
permissions[i] = buildFromMask(masks[i]);
}
return permissions;
protected BasePermission(int mask, char code) {
super(mask, code);
}
public static Permission buildFromName(String name) {
Assert.isTrue(locallyDeclaredPermissionsByName.containsKey(name), "Unknown permission '" + name + "'");
return (Permission) locallyDeclaredPermissionsByName.get(name);
}
public static Permission[] buildFromName(String[] names) {
if ((names == null) || (names.length == 0)) {
return new Permission[0];
}
Permission[] permissions = new Permission[names.length];
for (int i = 0; i < names.length; i++) {
permissions[i] = buildFromName(names[i]);
}
return permissions;
}
public boolean equals(Object arg0) {
if (arg0 == null) {
return false;
}
if (!(arg0 instanceof Permission)) {
return false;
}
Permission rhs = (Permission) arg0;
return (this.mask == rhs.getMask());
}
public int getMask() {
return mask;
}
public String getPattern() {
return AclFormattingUtils.printBinary(mask, code);
}
public String toString() {
return "BasePermission[" + getPattern() + "=" + mask + "]";
}
public int hashCode() {
return this.mask;
}
}
@@ -19,20 +19,21 @@ import org.springframework.security.acls.Permission;
/**
* Represents a <code>Permission</code> that is constructed at runtime from other permissions.<p>Methods return
* <code>this</code>, in order to facilitate method chaining.</p>
* Represents a <code>Permission</code> that is constructed at runtime from other permissions.
*
* <p>Methods return <code>this</code>, in order to facilitate method chaining.</p>
*
* @author Ben Alex
* @version $Id$
*/
public class CumulativePermission implements Permission {
//~ Instance fields ================================================================================================
public class CumulativePermission extends AbstractPermission {
private String pattern = THIRTY_TWO_RESERVED_OFF;
private int mask = 0;
//~ Methods ========================================================================================================
public CumulativePermission() {
super(0, ' ');
}
public CumulativePermission clear(Permission permission) {
this.mask &= ~permission.getMask();
this.pattern = AclFormattingUtils.demergePatterns(this.pattern, permission.getPattern());
@@ -46,43 +47,16 @@ public class CumulativePermission implements Permission {
return this;
}
public boolean equals(Object arg0) {
if (arg0 == null)
{
return false;
}
if (!(arg0 instanceof Permission)) {
return false;
}
Permission rhs = (Permission) arg0;
return (this.mask == rhs.getMask());
}
public int hashCode() {
return this.mask;
}
public int getMask() {
return this.mask;
}
public String getPattern() {
return this.pattern;
}
public CumulativePermission set(Permission permission) {
this.mask |= permission.getMask();
this.pattern = AclFormattingUtils.mergePatterns(this.pattern, permission.getPattern());
return this;
}
public String toString() {
return "CumulativePermission[" + pattern + "=" + this.mask + "]";
public String getPattern() {
return this.pattern;
}
}
@@ -0,0 +1,127 @@
package org.springframework.security.acls.domain;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import org.springframework.security.acls.Permission;
import org.springframework.security.acls.jdbc.LookupStrategy;
import org.springframework.util.Assert;
/**
* Default implementation of {@link PermissionFactory}.
*
* <p>
* Generally this class will be used by a {@link Permission} instance, as opposed to being dependency
* injected into a {@link LookupStrategy} or similar. Nevertheless, the latter mode of operation is
* fully supported (in which case your {@link Permission} implementations probably should extend
* {@link AbstractPermission} instead of {@link AbstractRegisteredPermission}).
* </p>
*
* @author Ben Alex
* @since 2.0.3
*
*/
public class DefaultPermissionFactory implements PermissionFactory {
private Map registeredPermissionsByInteger = new HashMap();
private Map registeredPermissionsByName = new HashMap();
/**
* Permit registration of a {@link DefaultPermissionFactory} class. The class must provide
* public static fields of type {@link Permission} to represent the possible permissions.
*
* @param clazz a {@link Permission} class with public static fields to register
*/
public void registerPublicPermissions(Class clazz) {
Assert.notNull(clazz, "Class required");
Assert.isAssignable(Permission.class, clazz);
Field[] fields = clazz.getFields();
for (int i = 0; i < fields.length; i++) {
try {
Object fieldValue = fields[i].get(null);
if (Permission.class.isAssignableFrom(fieldValue.getClass())) {
// Found a Permission static field
Permission perm = (Permission) fieldValue;
String permissionName = fields[i].getName();
registerPermission(perm, permissionName);
}
} catch (Exception ignore) {}
}
}
public void registerPermission(Permission perm, String permissionName) {
Assert.notNull(perm, "Permission required");
Assert.hasText(permissionName, "Permission name required");
Integer mask = new Integer(perm.getMask());
// Ensure no existing Permission uses this integer or code
Assert.isTrue(!registeredPermissionsByInteger.containsKey(mask), "An existing Permission already provides mask " + mask);
Assert.isTrue(!registeredPermissionsByName.containsKey(permissionName), "An existing Permission already provides name '" + permissionName + "'");
// Register the new Permission
registeredPermissionsByInteger.put(mask, perm);
registeredPermissionsByName.put(permissionName, perm);
}
public Permission buildFromMask(int mask) {
if (registeredPermissionsByInteger.containsKey(new Integer(mask))) {
// The requested mask has an exactly match against a statically-defined Permission, so return it
return (Permission) registeredPermissionsByInteger.get(new Integer(mask));
}
// To get this far, we have to use a CumulativePermission
CumulativePermission permission = new CumulativePermission();
for (int i = 0; i < 32; i++) {
int permissionToCheck = 1 << i;
if ((mask & permissionToCheck) == permissionToCheck) {
Permission p = (Permission) registeredPermissionsByInteger.get(new Integer(permissionToCheck));
Assert.state(p != null, "Mask " + permissionToCheck + " does not have a corresponding static Permission");
permission.set(p);
}
}
return permission;
}
public Permission[] buildFromMask(int[] masks) {
if ((masks == null) || (masks.length == 0)) {
return new Permission[0];
}
Permission[] permissions = new Permission[masks.length];
for (int i = 0; i < masks.length; i++) {
permissions[i] = buildFromMask(masks[i]);
}
return permissions;
}
public Permission buildFromName(String name) {
Assert.isTrue(registeredPermissionsByName.containsKey(name), "Unknown permission '" + name + "'");
return (Permission) registeredPermissionsByName.get(name);
}
public Permission[] buildFromName(String[] names) {
if ((names == null) || (names.length == 0)) {
return new Permission[0];
}
Permission[] permissions = new Permission[names.length];
for (int i = 0; i < names.length; i++) {
permissions[i] = buildFromName(names[i]);
}
return permissions;
}
}
@@ -0,0 +1,24 @@
package org.springframework.security.acls.domain;
import org.springframework.security.acls.Permission;
/**
* Provides a simple mechanism to retrieve {@link Permission} instances from integer masks.
*
* @author Ben Alex
* @since 2.0.3
*
*/
public interface PermissionFactory {
/**
* Dynamically creates a <code>CumulativePermission</code> or <code>BasePermission</code> representing the
* active bits in the passed mask.
*
* @param mask to build
*
* @return a Permission representing the requested object
*/
public abstract Permission buildFromMask(int mask);
}
@@ -49,6 +49,7 @@ import org.springframework.security.acls.sid.PrincipalSid;
import org.springframework.security.acls.sid.Sid;
import org.springframework.security.util.FieldUtils;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -239,7 +240,8 @@ public final class BasicLookupStrategy implements LookupStrategy {
recipient = new GrantedAuthoritySid(rs.getString("ace_sid"));
}
Permission permission = BasePermission.buildFromMask(rs.getInt("mask"));
int mask = rs.getInt("mask");
Permission permission = convertMaskIntoPermission(mask);
boolean granting = rs.getBoolean("granting");
boolean auditSuccess = rs.getBoolean("audit_success");
boolean auditFailure = rs.getBoolean("audit_failure");
@@ -264,6 +266,10 @@ public final class BasicLookupStrategy implements LookupStrategy {
}
}
protected Permission convertMaskIntoPermission(int mask) {
return BasePermission.buildFromMask(mask);
}
/**
* Looks up a batch of <code>ObjectIdentity</code>s directly from the database.<p>The caller is responsible
* for optimization issues, such as selecting the identities to lookup, ensuring the cache doesn't contain them
@@ -293,10 +299,10 @@ public final class BasicLookupStrategy implements LookupStrategy {
for (int i = 0; i < objectIdentities.length; i++) {
// Determine prepared statement values for this iteration
String javaType = objectIdentities[i].getJavaType().getName();
Assert.isInstanceOf(Long.class, objectIdentities[i].getIdentifier(),
"This class requires ObjectIdentity.getIdentifier() to be a Long");
long id = ((Long) objectIdentities[i].getIdentifier()).longValue();
// No need to check for nulls, as guaranteed non-null by ObjectIdentity.getIdentifier() interface contract
String identifier = objectIdentities[i].getIdentifier().toString();
long id = (Long.valueOf(identifier)).longValue();
// Inject values
ps.setLong((2 * i) + 1, id);
@@ -53,7 +53,7 @@ public class JdbcAclService implements AclService {
//~ Static fields/initializers =====================================================================================
protected static final Log log = LogFactory.getLog(JdbcAclService.class);
private static final String selectAclObjectWithParent = "select obj.object_id_identity obj_id, class.class class "
private static final String selectAclObjectWithParent = "select obj.object_id_identity as obj_id, class.class as class "
+ "from acl_object_identity obj, acl_object_identity parent, acl_class class "
+ "where obj.parent_object = parent.id and obj.object_id_class = class.id "
+ "and parent.object_id_identity = ? and parent.object_id_class = ("
@@ -64,7 +64,8 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
private AclCache aclCache;
private String deleteEntryByObjectIdentityForeignKey = "delete from acl_entry where acl_object_identity=?";
private String deleteObjectIdentityByPrimaryKey = "delete from acl_object_identity where id=?";
private String identityQuery = "call identity()";
private String classIdentityQuery = "call identity()"; // should be overridden for postgres : select currval('acl_class_seq')
private String sidIdentityQuery = "call identity()"; // should be overridden for postgres : select currval('acl_siq_seq')
private String insertClass = "insert into acl_class (class) values (?)";
private String insertEntry = "insert into acl_entry "
+ "(acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure)"
@@ -176,7 +177,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
jdbcTemplate.update(insertClass, new Object[] {clazz.getName()});
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(),
"Transaction must be running");
classId = new Long(jdbcTemplate.queryForLong(identityQuery));
classId = new Long(jdbcTemplate.queryForLong(classIdentityQuery));
}
} else {
classId = (Long) classIds.iterator().next();
@@ -221,7 +222,7 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
jdbcTemplate.update(insertSid, new Object[] {new Boolean(principal), sidName});
Assert.isTrue(TransactionSynchronizationManager.isSynchronizationActive(),
"Transaction must be running");
sidId = new Long(jdbcTemplate.queryForLong(identityQuery));
sidId = new Long(jdbcTemplate.queryForLong(sidIdentityQuery));
}
} else {
sidId = (Long) sidIds.iterator().next();
@@ -380,11 +381,15 @@ public class JdbcMutableAclService extends JdbcAclService implements MutableAclS
}
}
public void setIdentityQuery(String identityQuery) {
public void setClassIdentityQuery(String identityQuery) {
Assert.hasText(identityQuery, "New identity query is required");
this.identityQuery = identityQuery;
this.classIdentityQuery = identityQuery;
}
public void setSidIdentityQuery(String identityQuery) {
Assert.hasText(identityQuery, "New identity query is required");
this.sidIdentityQuery = identityQuery;
}
/**
* @param foreignKeysInDatabase if false this class will perform additional FK constrain checking, which may
* cause deadlocks (the default is true, so deadlocks are avoided but the database is expected to enforce FKs)
@@ -15,6 +15,7 @@
package org.springframework.security.acls.objectidentity;
import org.springframework.security.acls.IdentityUnavailableException;
import org.springframework.security.acls.jdbc.LookupStrategy;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -97,6 +98,12 @@ public class ObjectIdentityImpl implements ObjectIdentity {
/**
* Important so caching operates properly.<P>Considers an object of the same class equal if it has the same
* <code>classname</code> and <code>id</code> properties.</p>
*
* <p>
* Note that this class uses string equality for the identifier field, which ensures it better supports
* differences between {@link LookupStrategy} requirements and the domain object represented by this
* <code>ObjectIdentityImpl</code>.
* </p>
*
* @param arg0 object to compare
*
@@ -113,7 +120,7 @@ public class ObjectIdentityImpl implements ObjectIdentity {
ObjectIdentityImpl other = (ObjectIdentityImpl) arg0;
if (this.getIdentifier().equals(other.getIdentifier()) && this.getJavaType().equals(other.getJavaType())) {
if (this.getIdentifier().toString().equals(other.getIdentifier().toString()) && this.getJavaType().equals(other.getJavaType())) {
return true;
}
@@ -34,20 +34,20 @@ import org.springframework.util.Assert;
/**
* DOCUMENT ME!
* Abstract {@link AfterInvocationProvider} which provides commonly-used ACL-related services.
*
* @author $author$
* @version $Revision$
* @author Ben Alex
* @version $Id$
*/
public abstract class AbstractAclProvider implements AfterInvocationProvider {
//~ Instance fields ================================================================================================
private AclService aclService;
private Class processDomainObjectClass = Object.class;
private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
private String processConfigAttribute;
private Permission[] requirePermission = {BasePermission.READ};
protected AclService aclService;
protected Class processDomainObjectClass = Object.class;
protected ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl();
protected SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl();
protected String processConfigAttribute;
protected Permission[] requirePermission = {BasePermission.READ};
//~ Constructors ===================================================================================================
@@ -22,7 +22,7 @@ import org.springframework.security.acls.Permission;
/**
* Tests BasePermission and CumulativePermission.
* Tests classes associated with Permission.
*
* @author Ben Alex
* @version $Id${date}
@@ -63,9 +63,9 @@ public class PermissionTests {
assertEquals("CumulativePermission[...............................R=1]",
new CumulativePermission().set(BasePermission.READ).toString());
System.out.println("A = " + new CumulativePermission().set(BasePermission.ADMINISTRATION).toString());
assertEquals("CumulativePermission[...........................A....=16]",
new CumulativePermission().set(BasePermission.ADMINISTRATION).toString());
System.out.println("A = " + new CumulativePermission().set(SpecialPermission.ENTER).set(BasePermission.ADMINISTRATION).toString());
assertEquals("CumulativePermission[..........................EA....=48]",
new CumulativePermission().set(SpecialPermission.ENTER).set(BasePermission.ADMINISTRATION).toString());
System.out.println("RA = "
+ new CumulativePermission().set(BasePermission.ADMINISTRATION).set(BasePermission.READ).toString());
@@ -0,0 +1,40 @@
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.acls.domain;
import org.springframework.security.acls.Permission;
/**
* A test permission.
*
* @author Ben Alex
* @version $Id$
*/
public class SpecialPermission extends BasePermission {
public static final Permission ENTER = new SpecialPermission(1 << 5, 'E'); // 32
/**
* Registers the public static permissions defined on this class. This is mandatory so
* that the static methods will operate correctly.
*/
static {
registerPermissionsFor(SpecialPermission.class);
}
protected SpecialPermission(int mask, char code) {
super(mask, code);
}
}
@@ -120,7 +120,8 @@ public class BasicLookupStrategyTests {
public void testAclsRetrievalWithDefaultBatchSize() throws Exception {
ObjectIdentity topParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100));
ObjectIdentity middleParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(101));
ObjectIdentity childOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(102));
// Deliberately use an integer for the child, to reproduce bug report in SEC-819
ObjectIdentity childOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Integer(102));
Map map = this.strategy.readAclsById(new ObjectIdentity[] { topParentOid, middleParentOid, childOid }, null);
checkEntries(topParentOid, middleParentOid, childOid, map);
@@ -128,7 +129,7 @@ public class BasicLookupStrategyTests {
@Test
public void testAclsRetrievalFromCacheOnly() throws Exception {
ObjectIdentity topParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100));
ObjectIdentity topParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Integer(100));
ObjectIdentity middleParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(101));
ObjectIdentity childOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(102));
@@ -145,7 +146,7 @@ public class BasicLookupStrategyTests {
@Test
public void testAclsRetrievalWithCustomBatchSize() throws Exception {
ObjectIdentity topParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100));
ObjectIdentity middleParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(101));
ObjectIdentity middleParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Integer(101));
ObjectIdentity childOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(102));
// Set a batch size to allow multiple database queries in order to retrieve all acls
@@ -227,7 +228,7 @@ public class BasicLookupStrategyTests {
jdbcTemplate.execute(query);
ObjectIdentity topParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100));
ObjectIdentity middleParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(101));
ObjectIdentity middleParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Integer(101));
ObjectIdentity childOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(102));
ObjectIdentity middleParent2Oid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(103));
@@ -260,8 +261,8 @@ public class BasicLookupStrategyTests {
ObjectIdentity grandParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(104));
ObjectIdentity parent1Oid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(105));
ObjectIdentity parent2Oid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(106));
ObjectIdentity childOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(107));
ObjectIdentity parent2Oid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Integer(106));
ObjectIdentity childOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Integer(107));
// First lookup only child, thus populating the cache with grandParent, parent1 and child
Permission[] checkPermission = new Permission[] { BasePermission.READ };
@@ -290,21 +291,4 @@ public class BasicLookupStrategyTests {
Assert.assertTrue(foundParent2Acl.isGranted(checkPermission, sids, false));
}
@Test
public void testAclsWithDifferentSerializableTypesAsObjectIdentities() throws Exception {
String query = "INSERT INTO acl_object_identity(ID,OBJECT_ID_CLASS,OBJECT_ID_IDENTITY,PARENT_OBJECT,OWNER_SID,ENTRIES_INHERITING) VALUES (4,2,104,null,1,1);"
+ "INSERT INTO acl_entry(ID,ACL_OBJECT_IDENTITY,ACE_ORDER,SID,MASK,GRANTING,AUDIT_SUCCESS,AUDIT_FAILURE) VALUES (5,4,0,1,1,1,0,0)";
jdbcTemplate.execute(query);
ObjectIdentity oid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Integer(104));
Sid[] sids = new Sid[] { new PrincipalSid("ben") };
ObjectIdentity[] childOids = new ObjectIdentity[] { oid };
try {
Map foundAcls = strategy.readAclsById(childOids, sids);
Assert.fail("It should have thrown IllegalArgumentException");
} catch(IllegalArgumentException expected) {
Assert.assertTrue(true);
}
}
}
@@ -97,7 +97,7 @@ public class JdbcAclServiceTests extends AbstractTransactionalDataSourceSpringCo
ObjectIdentity topParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100));
ObjectIdentity middleParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(101));
ObjectIdentity childOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(102));
ObjectIdentity childOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Integer(102));
MutableAcl topParent = jdbcMutableAclService.createAcl(topParentOid);
MutableAcl middleParent = jdbcMutableAclService.createAcl(middleParentOid);
@@ -337,7 +337,7 @@ public class JdbcAclServiceTests extends AbstractTransactionalDataSourceSpringCo
ObjectIdentity topParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100));
ObjectIdentity middleParentOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(101));
ObjectIdentity childOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(102));
ObjectIdentity childOid = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Integer(102));
// Remove the child and check all related database rows were removed accordingly
jdbcMutableAclService.deleteAcl(childOid, false);
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-adapters</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<artifactId>spring-security-catalina</artifactId>
<name>Spring Security - Catalina adapter</name>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-adapters</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<artifactId>spring-security-jboss</artifactId>
<name>Spring Security - JBoss adapter</name>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-adapters</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<artifactId>spring-security-jetty</artifactId>
<name>Spring Security - Jetty adapter</name>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<artifactId>spring-security-adapters</artifactId>
<name>Spring Security - Adapters</name>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-adapters</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<artifactId>spring-security-resin</artifactId>
<name>Spring Security - Resin adapter</name>
+3 -3
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<artifactId>spring-security-cas-client</artifactId>
<name>Spring Security - CAS support</name>
@@ -31,7 +31,7 @@
<dependency>
<groupId>org.jasig.cas</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.1.1</version>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
@@ -54,7 +54,7 @@
javax.servlet.*;version="[2.4.0, 3.0.0)";resolution:=optional,
net.sf.ehcache.*;version="[1.4.1, 2.0.0)";resolution:=optional,
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
org.jasig.cas.client.*;version="[3.1.1, 4.0.0)"
org.jasig.cas.client.*;version="[3.1.3, 4.0.0)"
</spring.osgi.import>
<spring.osgi.private.pkg>
@@ -15,6 +15,11 @@
package org.springframework.security.ui.cas;
import java.io.IOException;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.validation.TicketValidator;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
@@ -24,6 +29,7 @@ import org.springframework.security.ui.AbstractProcessingFilter;
import org.springframework.security.ui.FilterChainOrder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
@@ -38,7 +44,11 @@ import javax.servlet.http.HttpServletRequest;
* <p>The configured <code>AuthenticationManager</code> is expected to provide a provider that can recognise
* <code>UsernamePasswordAuthenticationToken</code>s containing this special <code>principal</code> name, and process
* them accordingly by validation with the CAS server.</p>
* <p><b>Do not use this class directly.</b> Instead configure <code>web.xml</code> to use the {@link
* <p>By configuring a shared {@link ProxyGrantingTicketStorage} between the {@link TicketValidator} and the CasProcessingFilter
* one can have the CasProcessingFilter handle the proxying requirements for CAS. In addition, the URI endpoint for the proxying
* would also need to be configured (i.e. the part after protocol, hostname, and port).
*
* <p><b>Do not use this class directly.</b> Instead configure <code>web.xml</code> to use the {@link
* org.springframework.security.util.FilterToBeanProxy}.</p>
*
* @author Ben Alex
@@ -57,8 +67,17 @@ public class CasProcessingFilter extends AbstractProcessingFilter {
*/
public static final String CAS_STATELESS_IDENTIFIER = "_cas_stateless_";
//~ Methods ========================================================================================================
/**
* The last portion of the receptor url, i.e. /proxy/receptor
*/
private String proxyReceptorUrl;
/**
* The backing storage to store ProxyGrantingTicket requests.
*/
private ProxyGrantingTicketStorage proxyGrantingTicketStorage;
//~ Methods ========================================================================================================
public Authentication attemptAuthentication(final HttpServletRequest request)
throws AuthenticationException {
final String username = CAS_STATEFUL_IDENTIFIER;
@@ -87,4 +106,35 @@ public class CasProcessingFilter extends AbstractProcessingFilter {
public int getOrder() {
return FilterChainOrder.CAS_PROCESSING_FILTER;
}
/**
* Overridden to provide proxying capabilities.
*/
protected boolean requiresAuthentication(final HttpServletRequest request,
final HttpServletResponse response) {
final String requestUri = request.getRequestURI();
if (CommonUtils.isEmpty(this.proxyReceptorUrl) || !requestUri.endsWith(this.proxyReceptorUrl) || this.proxyGrantingTicketStorage == null) {
return super.requiresAuthentication(request, response);
}
try {
CommonUtils.readAndRespondToProxyReceptorRequest(request, response, this.proxyGrantingTicketStorage);
return false;
} catch (final IOException e) {
return super.requiresAuthentication(request, response);
}
}
public final void setProxyReceptorUrl(final String proxyReceptorUrl) {
this.proxyReceptorUrl = proxyReceptorUrl;
}
public final void setProxyGrantingTicketStorage(
final ProxyGrantingTicketStorage proxyGrantingTicketStorage) {
this.proxyGrantingTicketStorage = proxyGrantingTicketStorage;
}
}
+1 -15
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<packaging>bundle</packaging>
<artifactId>spring-security-core-tiger</artifactId>
@@ -32,20 +32,6 @@
<artifactId>aspectjweaver</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-support</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<packaging>bundle</packaging>
<artifactId>spring-security-core</artifactId>
@@ -158,4 +158,8 @@ public class ConcurrentSessionControllerImpl implements ConcurrentSessionControl
public void setSessionRegistry(SessionRegistry sessionRegistry) {
this.sessionRegistry = sessionRegistry;
}
public SessionRegistry getSessionRegistry() {
return sessionRegistry;
}
}
@@ -1,5 +1,6 @@
package org.springframework.security.config;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -36,10 +37,15 @@ public class AuthenticationManagerBeanDefinitionParser implements BeanDefinition
BeanIds.CONCURRENT_SESSION_CONTROLLER, element);
authManager.getPropertyValues().addPropertyValue("sessionController",
new RuntimeBeanReference(sessionControllerRef));
RootBeanDefinition sessionRegistryInjector = new RootBeanDefinition(SessionRegistryInjectionBeanPostProcessor.class);
sessionRegistryInjector.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
sessionRegistryInjector.getConstructorArgumentValues().addGenericArgumentValue(sessionControllerRef);
parserContext.getRegistry().registerBeanDefinition(BeanIds.SESSION_REGISTRY_INJECTION_POST_PROCESSOR, sessionRegistryInjector);
}
parserContext.getRegistry().registerAlias(BeanIds.AUTHENTICATION_MANAGER, alias);
return null;
}
}
}
@@ -18,6 +18,7 @@ public abstract class BeanIds {
static final String CONTEXT_SOURCE_SETTING_POST_PROCESSOR = "_contextSettingPostProcessor";
static final String ENTRY_POINT_INJECTION_POST_PROCESSOR = "_entryPointInjectionBeanPostProcessor";
static final String USER_DETAILS_SERVICE_INJECTION_POST_PROCESSOR = "_userServiceInjectionPostProcessor";
static final String SESSION_REGISTRY_INJECTION_POST_PROCESSOR = "_sessionRegistryInjectionPostProcessor";
static final String FILTER_CHAIN_POST_PROCESSOR = "_filterChainProxyPostProcessor";
static final String FILTER_LIST = "_filterChainList";
@@ -66,7 +66,7 @@ public class FilterChainProxyPostProcessor implements BeanPostProcessor, BeanFac
unwrapFilter(previous) + "' have the same 'order' value. When using custom filters, " +
"please make sure the positions do not conflict with default filters. " +
"Alternatively you can disable the default filters by removing the corresponding " +
"child elements from <http> and not avoiding the use of <http auto-config='true'>.");
"child elements from <http> and avoiding the use of <http auto-config='true'>.");
}
}
}
@@ -116,7 +116,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
parseInterceptUrlsForChannelSecurityAndFilterChain(interceptUrlElts, filterChainMap, channelRequestMap,
convertPathsToLowerCase, parserContext);
registerHttpSessionIntegrationFilter(element, parserContext);
boolean allowSessionCreation = registerHttpSessionIntegrationFilter(element, parserContext);
registerServletApiFilter(element, parserContext);
@@ -133,7 +133,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
DomUtils.getChildElementByTagName(element, Elements.PORT_MAPPINGS), parserContext);
registry.registerBeanDefinition(BeanIds.PORT_MAPPER, portMapper);
registerExceptionTranslationFilter(element, parserContext);
registerExceptionTranslationFilter(element, parserContext, allowSessionCreation);
if (channelRequestMap.size() > 0) {
@@ -174,7 +174,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
new LogoutBeanDefinitionParser().parse(logoutElt, parserContext);
}
parseBasicFormLoginAndOpenID(element, parserContext, autoConfig);
parseBasicFormLoginAndOpenID(element, parserContext, autoConfig, allowSessionCreation);
Element x509Elt = DomUtils.getChildElementByTagName(element, Elements.X509);
if (x509Elt != null) {
@@ -205,8 +205,9 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
pc.getRegistry().registerAlias(BeanIds.FILTER_CHAIN_PROXY, BeanIds.SPRING_SECURITY_FILTER_CHAIN);
}
private void registerHttpSessionIntegrationFilter(Element element, ParserContext pc) {
private boolean registerHttpSessionIntegrationFilter(Element element, ParserContext pc) {
RootBeanDefinition httpScif = new RootBeanDefinition(HttpSessionContextIntegrationFilter.class);
boolean sessionCreationAllowed = true;
String createSession = element.getAttribute(ATT_CREATE_SESSION);
if (OPT_CREATE_SESSION_ALWAYS.equals(createSession)) {
@@ -215,6 +216,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
} else if (OPT_CREATE_SESSION_NEVER.equals(createSession)) {
httpScif.getPropertyValues().addPropertyValue("allowSessionCreation", Boolean.FALSE);
httpScif.getPropertyValues().addPropertyValue("forceEagerSessionCreation", Boolean.FALSE);
sessionCreationAllowed = false;
} else {
createSession = DEF_CREATE_SESSION_IF_REQUIRED;
httpScif.getPropertyValues().addPropertyValue("allowSessionCreation", Boolean.TRUE);
@@ -223,6 +225,8 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
pc.getRegistry().registerBeanDefinition(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER, httpScif);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER));
return sessionCreationAllowed;
}
// Adds the servlet-api integration filter if required
@@ -252,12 +256,13 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
return true;
}
private void registerExceptionTranslationFilter(Element element, ParserContext pc) {
private void registerExceptionTranslationFilter(Element element, ParserContext pc, boolean allowSessionCreation) {
String accessDeniedPage = element.getAttribute(ATT_ACCESS_DENIED_PAGE);
ConfigUtils.validateHttpRedirect(accessDeniedPage, pc, pc.extractSource(element));
BeanDefinitionBuilder exceptionTranslationFilterBuilder
= BeanDefinitionBuilder.rootBeanDefinition(ExceptionTranslationFilter.class);
exceptionTranslationFilterBuilder.addPropertyValue("createSessionAllowed", new Boolean(allowSessionCreation));
if (StringUtils.hasText(accessDeniedPage)) {
AccessDeniedHandlerImpl accessDeniedHandler = new AccessDeniedHandlerImpl();
accessDeniedHandler.setErrorPage(accessDeniedPage);
@@ -338,7 +343,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
}
}
private void parseBasicFormLoginAndOpenID(Element element, ParserContext pc, boolean autoConfig) {
private void parseBasicFormLoginAndOpenID(Element element, ParserContext pc, boolean autoConfig, boolean allowSessionCreation) {
RootBeanDefinition formLoginFilter = null;
RootBeanDefinition formLoginEntryPoint = null;
String formLoginPage = null;
@@ -397,6 +402,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
if (formLoginFilter != null) {
needLoginPage = true;
formLoginFilter.getPropertyValues().addPropertyValue("allowSessionCreation", new Boolean(allowSessionCreation));
pc.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_FILTER, formLoginFilter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.FORM_LOGIN_FILTER));
pc.getRegistry().registerBeanDefinition(BeanIds.FORM_LOGIN_ENTRY_POINT, formLoginEntryPoint);
@@ -404,6 +410,7 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser {
if (openIDFilter != null) {
needLoginPage = true;
openIDFilter.getPropertyValues().addPropertyValue("allowSessionCreation", new Boolean(allowSessionCreation));
pc.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_FILTER, openIDFilter);
ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.OPEN_ID_FILTER));
pc.getRegistry().registerBeanDefinition(BeanIds.OPEN_ID_ENTRY_POINT, openIDEntryPoint);
@@ -84,7 +84,7 @@ public class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
tokenRepo = new RuntimeBeanReference(tokenRepository);
} else {
tokenRepo = new RootBeanDefinition(JdbcTokenRepositoryImpl.class);
((BeanDefinition)tokenRepo).getPropertyValues().addPropertyValue(ATT_DATA_SOURCE,
((BeanDefinition)tokenRepo).getPropertyValues().addPropertyValue("dataSource",
new RuntimeBeanReference(dataSource));
}
services.getPropertyValues().addPropertyValue("tokenRepository", tokenRepo);
@@ -0,0 +1,94 @@
package org.springframework.security.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.security.concurrent.ConcurrentSessionController;
import org.springframework.security.concurrent.ConcurrentSessionControllerImpl;
import org.springframework.security.concurrent.SessionRegistry;
import org.springframework.security.ui.AbstractProcessingFilter;
import org.springframework.security.ui.SessionFixationProtectionFilter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Registered by the <tt>AuthenticationManagerBeanDefinitionParser</tt> if an external
* ConcurrentSessionController is set (and hence an external SessionRegistry).
* Its responsibility is to set the SessionRegistry on namespace-registered beans which require access
* to it.
* <p>
* It will attempt to read the registry directly from the registered controller. If that fails, it will look in
* the application context for a registered SessionRegistry bean.
*
* See SEC-879.
*
* @author Luke Taylor
* @since 2.0.3
*/
class SessionRegistryInjectionBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware {
private final Log logger = LogFactory.getLog(getClass());
private ListableBeanFactory beanFactory;
private SessionRegistry sessionRegistry;
private final String controllerBeanName;
SessionRegistryInjectionBeanPostProcessor(String controllerBeanName) {
this.controllerBeanName = controllerBeanName;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (BeanIds.FORM_LOGIN_FILTER.equals(beanName) ||
BeanIds.OPEN_ID_FILTER.equals(beanName)) {
((AbstractProcessingFilter) bean).setSessionRegistry(getSessionRegistry());
} else if (BeanIds.SESSION_FIXATION_PROTECTION_FILTER.equals(beanName)) {
((SessionFixationProtectionFilter)bean).setSessionRegistry(getSessionRegistry());
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
private SessionRegistry getSessionRegistry() {
if (sessionRegistry != null) {
return sessionRegistry;
}
logger.info("Attempting to read SessionRegistry from registered ConcurrentSessionController bean");
ConcurrentSessionController controller = (ConcurrentSessionController) beanFactory.getBean(controllerBeanName);
if (controller instanceof ConcurrentSessionControllerImpl) {
sessionRegistry = ((ConcurrentSessionControllerImpl)controller).getSessionRegistry();
return sessionRegistry;
}
logger.info("ConcurrentSessionController is not a standard implementation. SessionRegistry could not be read from it. Looking for it in the context.");
List sessionRegs = new ArrayList(beanFactory.getBeansOfType(SessionRegistry.class).values());
if (sessionRegs.size() == 0) {
throw new SecurityConfigurationException("concurrent-session-controller-ref was set but no SessionRegistry could be obtained from the application context.");
}
if (sessionRegs.size() > 1) {
logger.warn("More than one SessionRegistry instance in application context. Possible configuration errors may result.");
}
sessionRegistry = (SessionRegistry) sessionRegs.get(0);
return sessionRegistry;
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = (ListableBeanFactory) beanFactory;
}
}
@@ -158,7 +158,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, Appli
Assert.hasLength(loginContextName, "loginContextName must be set on " + getClass());
configureJaas(loginConfig);
Assert.notNull(Configuration.getConfiguration(),
"As per http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/login/Configuration.html "
+ "\"If a Configuration object was set via the Configuration.setConfiguration method, then that object is "
@@ -246,6 +246,9 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, Appli
*/
protected void configureJaas(Resource loginConfig) throws IOException {
configureJaasUsingLoop();
// Overcome issue in SEC-760
Configuration.getConfiguration().refresh();
}
/**
@@ -375,7 +378,9 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, Appli
* @param token The {@link UsernamePasswordAuthenticationToken} being processed
*/
protected void publishSuccessEvent(UsernamePasswordAuthenticationToken token) {
applicationEventPublisher.publishEvent(new JaasAuthenticationSuccessEvent(token));
if (applicationEventPublisher != null) {
applicationEventPublisher.publishEvent(new JaasAuthenticationSuccessEvent(token));
}
}
/**
@@ -88,7 +88,6 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
result.setDetails(authentication.getDetails());
return result;
}
/**
@@ -123,4 +122,14 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
public void setThrowExceptionWhenTokenRejected(boolean throwExceptionWhenTokenRejected) {
this.throwExceptionWhenTokenRejected = throwExceptionWhenTokenRejected;
}
/**
* Sets the strategy which will be used to validate the loaded <tt>UserDetails</tt> object
* for the user. Defaults to an {@link AccountStatusUserDetailsChecker}.
* @param userDetailsChecker
*/
public void setUserDetailsChecker(UserDetailsChecker userDetailsChecker) {
Assert.notNull(userDetailsChecker, "userDetailsChacker cannot be null");
this.userDetailsChecker = userDetailsChecker;
}
}
@@ -58,7 +58,7 @@ public class AuthenticationDetailsSourceImpl implements AuthenticationDetailsSou
Constructor constructor = null;
for (int i = 0; i < constructors.length; i++) {
Class[] parameterTypes = constructors[i].getParameterTypes();
if (parameterTypes.length == 1 && (object == null || parameterTypes[i].isInstance(object))) {
if (parameterTypes.length == 1 && (object == null || parameterTypes[0].isInstance(object))) {
constructor = constructors[i];
break;
}
@@ -31,10 +31,12 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.Map.Entry;
@@ -274,58 +276,62 @@ public class SavedRequestAwareWrapper extends SecurityContextHolderAwareRequestW
}
public Map getParameterMap() {
Map parameters = super.getParameterMap();
if (savedRequest == null) {
return parameters;
return super.getParameterMap();
}
// We have a saved request so merge the values, with the wrapped request taking precedence (see getParameter())
Map newParameters = new HashMap(savedRequest.getParameterMap().size() + parameters.size());
newParameters.putAll(parameters);
Set names = getCombinedParameterNames();
Iterator nameIter = names.iterator();
Map parameterMap = new HashMap(names.size());
Iterator savedParams = savedRequest.getParameterMap().entrySet().iterator();
while (savedParams.hasNext()) {
Map.Entry entry = (Entry) savedParams.next();
String name = (String) entry.getKey();
String[] savedParamValues = (String[]) entry.getValue();
if (newParameters.containsKey(name)) {
// merge values
String[] existingValues = (String[]) newParameters.get(name);
String[] mergedValues = new String[savedParamValues.length + existingValues.length];
System.arraycopy(existingValues, 0, mergedValues, 0, existingValues.length);
System.arraycopy(savedParamValues, 0, mergedValues, existingValues.length, savedParamValues.length);
newParameters.put(name, mergedValues);
} else {
newParameters.put(name, savedParamValues);
}
while (nameIter.hasNext()) {
String name = (String) nameIter.next();
parameterMap.put(name, getParameterValues(name));
}
return newParameters;
return parameterMap;
}
private Set getCombinedParameterNames() {
Set names = new HashSet();
names.addAll(super.getParameterMap().keySet());
if (savedRequest != null) {
names.addAll(savedRequest.getParameterMap().keySet());
}
return names;
}
public Enumeration getParameterNames() {
return new Enumerator(getParameterMap().keySet());
return new Enumerator(getCombinedParameterNames());
}
public String[] getParameterValues(String name) {
String[] savedRequestParams = savedRequest == null ? null : savedRequest.getParameterValues(name);
if (savedRequest == null) {
return super.getParameterValues(name);
}
String[] savedRequestParams = savedRequest.getParameterValues(name);
String[] wrappedRequestParams = super.getParameterValues(name);
if (savedRequestParams == null && wrappedRequestParams == null) {
return null;
if (savedRequestParams == null) {
return wrappedRequestParams;
}
if (wrappedRequestParams == null) {
return savedRequestParams;
}
List combinedParams = new ArrayList();
// We have params in both saved and wrapped requests so have to merge them
List wrappedParamsList = Arrays.asList(wrappedRequestParams);
List combinedParams = new ArrayList(wrappedParamsList);
if (wrappedRequestParams != null) {
combinedParams.addAll(Arrays.asList(wrappedRequestParams));
}
if (savedRequestParams != null) {
combinedParams.addAll(Arrays.asList(savedRequestParams));
// We want to add all parameters of the saved request *apart from* duplicates of those already added
for (int i = 0; i < savedRequestParams.length; i++) {
if (!wrappedParamsList.contains(savedRequestParams[i])) {
combinedParams.add(savedRequestParams[i]);
}
}
return (String[]) combinedParams.toArray(new String[combinedParams.size()]);
@@ -0,0 +1,53 @@
AuthByAdapterProvider.incorrectKey=Podana implementacja AuthByAdapter nie zawiera oczekiwanego klucza
BasicAclEntryAfterInvocationProvider.noPermission=U\u017cytkownik {0} nie posiada \u017bADNYCH uprawnie\u0144 do obiektu {1}
BasicAclEntryAfterInvocationProvider.insufficientPermission=U\u017cytkownik {0} nie posiada wymaganych uprawnie\u0144 do obiektu {1}
ConcurrentSessionControllerImpl.exceededAllowed=Maksymalna liczba sesji ({0}) dla tego u\u017cytkownika zosta\u0142a przekroczona
ProviderManager.providerNotFound=AuthenticationProvider dla {0} nie zosta\u0142 znaleziony
AnonymousAuthenticationProvider.incorrectKey=Podany AnonymousAuthenticationToken nie zawiera oczekiwanego klucza
CasAuthenticationProvider.incorrectKey=Podany CasAuthenticationToken nie zawiera oczekiwanego klucza
CasAuthenticationProvider.noServiceTicket=Dostarczenie biletu serwisu CAS do walidacji nie powiod\u0142o si\u0119
NamedCasProxyDecider.untrusted=Najbli\u017cszy serwer po\u015brednicz\u0105cy {0} jest niezaufany
RejectProxyTickets.reject=Bilety serwera po\u015brednicz\u0105cego zosta\u0142y odrzucone
AbstractSecurityInterceptor.authenticationNotFound=Obiekt Authentication nie zosta\u0142 odnaleziony w SecurityContext
AbstractUserDetailsAuthenticationProvider.onlySupports=Tylko UsernamePasswordAuthenticationToken jest obs\u0142ugiwany
AbstractUserDetailsAuthenticationProvider.locked=Konto u\u017cytkownika jest zablokowane
AbstractUserDetailsAuthenticationProvider.disabled=Konto u\u017cytkownika jest wy\u0142\u0105czone
AbstractUserDetailsAuthenticationProvider.expired=Wa\u017cno\u015b\u0107 konta u\u017cytkownika wygas\u0142a
AbstractUserDetailsAuthenticationProvider.credentialsExpired=Wa\u017cno\u015b\u0107 danych uwierzytelniaj\u0105cych wygas\u0142a
AbstractUserDetailsAuthenticationProvider.badCredentials=Niepoprawne dane uwierzytelniaj\u0105ce
X509AuthenticationProvider.certificateNull=Certyfikat jest pusty
DaoX509AuthoritiesPopulator.noMatching=Nie odnaleziono pasuj\u0105cego wzorca w subjectDN: {0}
RememberMeAuthenticationProvider.incorrectKey=Podany RememberMeAuthenticationToken nie zawiera oczekiwanego klucza
RunAsImplAuthenticationProvider.incorrectKey=Podany RunAsUserToken nie zawiera oczekiwanego klucza
DigestProcessingFilter.missingMandatory=Brakuje wymaganej warto\u015bci skr\u00f3tu; otrzymany nag\u0142\u00f3wek {0}
DigestProcessingFilter.missingAuth=Brakuje wymaganej warto\u015bci skr\u00f3tu dla 'auth' QOP; otrzymany nag\u0142\u00f3wek {0}
DigestProcessingFilter.incorrectRealm=Nazwa domeny {0} w odpowiedzi nie jest zgodna z nazw\u0105 domeny {1} w systemie
DigestProcessingFilter.nonceExpired=Wa\u017cno\u015b\u0107 kodu jednorazowego (nonce) wygas\u0142a
DigestProcessingFilter.nonceEncoding=Kod jednorazowy (nonce) nie jest zakodowany w Base64; otrzymany kod {0}
DigestProcessingFilter.nonceNotTwoTokens=Kod jednorazowy (nonce) powinien zawiera\u0107 dwie warto\u015bci {0}
DigestProcessingFilter.nonceNotNumeric=Pierwsza warto\u015b\u0107 kodu jednorazowego (nonce) nie jest warto\u015bci\u0105 numeryczn\u0105: {0}
DigestProcessingFilter.nonceCompromised=Niepoprawny kod jednorazowy (nonce) {0}
DigestProcessingFilter.usernameNotFound=Nazwa u\u017cytkownika {0} nie zosta\u0142a odnaleziona
DigestProcessingFilter.incorrectResponse=Niepoprawna odpowied\u017a
JdbcDaoImpl.notFound=Nazwa u\u017cytkownika {0} nie zosta\u0142a odnaleziona
JdbcDaoImpl.noAuthority=U\u017cytkownik {0} nie posiada \u017cadnych uprawnie\u0144 (GrantedAuthority)
SwitchUserProcessingFilter.noCurrentUser=\u017baden aktualny u\u017cytkownik nie jest powi\u0105zany z tym zapytaniem
SwitchUserProcessingFilter.noOriginalAuthentication=Nie mo\u017cna by\u0142o odnale\u017a\u0107 oryginalnego obiektu Authentication
SwitchUserProcessingFilter.usernameNotFound=Nazwa u\u017cytkownika {0} nie zosta\u0142a odnaleziona
SwitchUserProcessingFilter.locked=Konto u\u017cytkownika jest zablokowane
SwitchUserProcessingFilter.disabled=Konto u\u017cytkownika jest wy\u0142\u0105czone
SwitchUserProcessingFilter.expired=Wa\u017cno\u015b\u0107 konta u\u017cytkownika wygas\u0142a
SwitchUserProcessingFilter.credentialsExpired=Wa\u017cno\u015b\u0107 danych uwierzytelniaj\u0105cych wygas\u0142a
AbstractAccessDecisionManager.accessDenied=Dost\u0119p zabroniony
LdapAuthenticationProvider.emptyUsername=Pusta nazwa u\u017cytkownika jest niedozwolona
LdapAuthenticationProvider.emptyPassword=Niepoprawne dane uwierzytelniaj\u0105ce
DefaultIntitalDirContextFactory.communicationFailure=Po\u0142\u0105czenie z serwerem LDAP nie powiod\u0142o si\u0119
DefaultIntitalDirContextFactory.badCredentials=Niepoprawne dane uwierzytelniaj\u0105ce
DefaultIntitalDirContextFactory.unexpectedException=Nie mo\u017cna by\u0142o uzyska\u0107 InitialDirContext z powodu nieoczekiwanego wyj\u0105tku
PasswordComparisonAuthenticator.badCredentials=Niepoprawne dane uwierzytelniaj\u0105ce
BindAuthenticator.badCredentials=Niepoprawne dane uwierzytelniaj\u0105ce
BindAuthenticator.failedToLoadAttributes=Niepoprawne dane uwierzytelniaj\u0105ce
UserDetailsService.locked=Konto u\u017cytkownika jest zablokowane
UserDetailsService.disabled=Konto u\u017cytkownika jest wy\u0142\u0105czone
UserDetailsService.expired=Wa\u017cno\u015b\u0107 konta u\u017cytkownika wygas\u0142a
UserDetailsService.credentialsExpired=Wa\u017cno\u015b\u0107 danych uwierzytelniaj\u0105cych wygas\u0142a
@@ -349,6 +349,21 @@ public class HttpSecurityBeanDefinitionParserTests {
assertTrue(rememberMeServices instanceof PersistentTokenBasedRememberMeServices);
}
@Test
public void rememberMeServiceWorksWithDataSourceRef() {
setContext(
"<http auto-config='true'>" +
" <remember-me data-source-ref='ds'/>" +
"</http>" +
"<b:bean id='ds' class='org.springframework.security.TestDataSource'> " +
" <b:constructor-arg value='tokendb'/>" +
"</b:bean>" + AUTH_PROVIDER_XML);
Object rememberMeServices = appContext.getBean(BeanIds.REMEMBER_ME_SERVICES);
assertTrue(rememberMeServices instanceof PersistentTokenBasedRememberMeServices);
}
@Test
public void rememberMeServiceWorksWithExternalServicesImpl() throws Exception {
setContext(
@@ -586,6 +601,22 @@ public class HttpSecurityBeanDefinitionParserTests {
" </http>" + AUTH_PROVIDER_XML);
}
@Test
public void settingCreateSessionToAlwaysSetsFilterPropertiesCorrectly() throws Exception {
// Protected, no anonymous filter configured.
setContext("<http auto-config='true' create-session='always'/>" + AUTH_PROVIDER_XML);
assertEquals(Boolean.TRUE, FieldUtils.getFieldValue(appContext.getBean(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER), "forceEagerSessionCreation"));
assertEquals(Boolean.TRUE, FieldUtils.getFieldValue(appContext.getBean(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER), "allowSessionCreation"));
}
@Test
public void settingCreateSessionToNeverSetsFilterPropertiesCorrectly() throws Exception {
// Protected, no anonymous filter configured.
setContext("<http auto-config='true' create-session='never'/>" + AUTH_PROVIDER_XML);
assertEquals(Boolean.FALSE, FieldUtils.getFieldValue(appContext.getBean(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER), "forceEagerSessionCreation"));
assertEquals(Boolean.FALSE, FieldUtils.getFieldValue(appContext.getBean(BeanIds.HTTP_SESSION_CONTEXT_INTEGRATION_FILTER), "allowSessionCreation"));
}
private void setContext(String context) {
appContext = new InMemoryXmlApplicationContext(context);
}
@@ -0,0 +1,66 @@
package org.springframework.security.config;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Test;
import org.springframework.context.support.AbstractXmlApplicationContext;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.concurrent.ConcurrentSessionController;
import org.springframework.security.util.FieldUtils;
import org.springframework.security.util.InMemoryXmlApplicationContext;
/**
*
* @author Luke Taylor
*/
public class SessionRegistryInjectionBeanPostProcessorTests {
private AbstractXmlApplicationContext appContext;
@After
public void closeAppContext() {
if (appContext != null) {
appContext.close();
appContext = null;
}
}
private void setContext(String context) {
appContext = new InMemoryXmlApplicationContext(context);
}
@Test
public void sessionRegistryIsSetOnFiltersWhenUsingCustomControllerWithInternalRegistryBean() throws Exception {
setContext(
"<http auto-config='true'/>" +
"<b:bean id='sc' class='org.springframework.security.concurrent.ConcurrentSessionControllerImpl'>" +
" <b:property name='sessionRegistry'>" +
" <b:bean class='org.springframework.security.concurrent.SessionRegistryImpl'/>" +
" </b:property>" +
"</b:bean>" +
"<authentication-manager alias='authManager' session-controller-ref='sc'/>" +
HttpSecurityBeanDefinitionParserTests.AUTH_PROVIDER_XML);
assertNotNull(FieldUtils.getFieldValue(appContext.getBean(BeanIds.SESSION_FIXATION_PROTECTION_FILTER), "sessionRegistry"));
assertNotNull(FieldUtils.getFieldValue(appContext.getBean(BeanIds.FORM_LOGIN_FILTER), "sessionRegistry"));
}
@Test
public void sessionRegistryIsSetOnFiltersWhenUsingCustomControllerWithNonStandardController() throws Exception {
setContext(
"<http auto-config='true'/>" +
"<b:bean id='sc' class='org.springframework.security.config.SessionRegistryInjectionBeanPostProcessorTests$MockConcurrentSessionController'/>" +
"<b:bean id='sessionRegistry' class='org.springframework.security.concurrent.SessionRegistryImpl'/>" +
"<authentication-manager alias='authManager' session-controller-ref='sc'/>" +
HttpSecurityBeanDefinitionParserTests.AUTH_PROVIDER_XML);
assertNotNull(FieldUtils.getFieldValue(appContext.getBean(BeanIds.SESSION_FIXATION_PROTECTION_FILTER), "sessionRegistry"));
assertNotNull(FieldUtils.getFieldValue(appContext.getBean(BeanIds.FORM_LOGIN_FILTER), "sessionRegistry"));
}
public static class MockConcurrentSessionController implements ConcurrentSessionController {
public void checkAuthenticationAllowed(Authentication request) throws AuthenticationException {
}
public void registerSuccessfulAuthentication(Authentication authentication) {
}
}
}
@@ -0,0 +1,64 @@
package org.springframework.security.providers.jaas;
import java.net.URL;
import java.security.Security;
import javax.security.auth.login.LoginContext;
import junit.framework.Assert;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
/**
* Tests bug reported in SEC-760.
*
* @author Ben Alex
*
*/
public class Sec760Tests {
public String resolveConfigFile(String filename) {
String resName = "/" + getClass().getPackage().getName().replace('.', '/') + filename;
return resName;
}
private void testConfigureJaasCase(JaasAuthenticationProvider p1, JaasAuthenticationProvider p2) throws Exception {
p1.setLoginConfig(new ClassPathResource(resolveConfigFile("/test1.conf")));
p1.setLoginContextName("test1");
p1.setCallbackHandlers(new JaasAuthenticationCallbackHandler[] {new TestCallbackHandler(), new JaasNameCallbackHandler(), new JaasPasswordCallbackHandler()});
p1.setAuthorityGranters(new AuthorityGranter[] {new TestAuthorityGranter()});
p1.afterPropertiesSet();
testAuthenticate(p1);
p2.setLoginConfig(new ClassPathResource(resolveConfigFile("/test2.conf")));
p2.setLoginContextName("test2");
p2.setCallbackHandlers(new JaasAuthenticationCallbackHandler[] {new TestCallbackHandler(), new JaasNameCallbackHandler(), new JaasPasswordCallbackHandler()});
p2.setAuthorityGranters(new AuthorityGranter[] {new TestAuthorityGranter()});
p2.afterPropertiesSet();
testAuthenticate(p2);
}
private void testAuthenticate(JaasAuthenticationProvider p1) {
GrantedAuthorityImpl role1 = new GrantedAuthorityImpl("ROLE_1");
GrantedAuthorityImpl role2 = new GrantedAuthorityImpl("ROLE_2");
GrantedAuthority[] defaultAuths = new GrantedAuthority[] {role1, role2,};
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password",
defaultAuths);
Authentication auth = p1.authenticate(token);
Assert.assertNotNull(auth);
}
@Test
public void testConfigureJaas() throws Exception {
testConfigureJaasCase(new JaasAuthenticationProvider(), new JaasAuthenticationProvider());
}
}
@@ -11,7 +11,10 @@ import org.springframework.security.util.PortResolverImpl;
public class SavedRequestAwareWrapperTests {
@Test
/* SEC-830 */
/* SEC-830. Assume we have a request to /someUrl?action=foo (the saved request)
* and then RequestDispatcher.forward() it to /someUrl?action=bar.
* What should action parameter be before and during the forward?
**/
public void wrappedRequestParameterTakesPrecedenceOverSavedRequest() {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setParameter("action", "foo");
@@ -20,8 +23,26 @@ public class SavedRequestAwareWrapperTests {
request2.getSession().setAttribute(AbstractProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY, savedRequest);
SavedRequestAwareWrapper wrapper = new SavedRequestAwareWrapper(request2, new PortResolverImpl(), "ROLE_");
assertEquals("foo", wrapper.getParameter("action"));
// The request after forward
request2.setParameter("action", "bar");
assertEquals("bar", wrapper.getParameter("action"));
// Both values should be set, but "bar" should be first
assertEquals(2, wrapper.getParameterValues("action").length);
assertEquals("bar", wrapper.getParameterValues("action")[0]);
}
@Test
public void savedRequestDoesntCreateDuplicateParams() {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setParameter("action", "foo");
SavedRequest savedRequest = new SavedRequest(request, new PortResolverImpl());
MockHttpServletRequest request2 = new MockHttpServletRequest();
request2.getSession().setAttribute(AbstractProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY, savedRequest);
request2.setParameter("action", "foo");
SavedRequestAwareWrapper wrapper = new SavedRequestAwareWrapper(request2, new PortResolverImpl(), "ROLE_");
assertEquals(1, wrapper.getParameterValues("action").length);
assertEquals(1, wrapper.getParameterMap().size());
assertEquals(1, ((String[])wrapper.getParameterMap().get("action")).length);
}
@Test
@@ -0,0 +1,3 @@
test1 {
org.springframework.security.providers.jaas.TestLoginModule required;
};
@@ -0,0 +1,3 @@
test2 {
org.springframework.security.providers.jaas.TestLoginModule required;
};
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<packaging>jar</packaging>
<artifactId>spring-security-ntlm</artifactId>
+2 -2
View File
@@ -3,12 +3,12 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<artifactId>spring-security-openid</artifactId>
<name>Spring Security - OpenID support</name>
<description>Spring Security - Support for OpenID</description>
<version>2.0.2</version>
<version>2.0.3</version>
<packaging>bundle</packaging>
<dependencies>
+5 -5
View File
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
<name>Spring Security</name>
<packaging>pom</packaging>
@@ -38,9 +38,9 @@
<!-- Note when doing releases: tagBase is set in release plugin configuration below -->
<scm>
<connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/spring-security/tags/spring-security-parent-2.0.2</connection>
<developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/spring-security/tags/spring-security-parent-2.0.2</developerConnection>
<url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/spring-security/tags/spring-security-parent-2.0.2</url>
<connection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/spring-security/tags/spring-security-parent-2.0.3</connection>
<developerConnection>scm:svn:https://acegisecurity.svn.sourceforge.net/svnroot/acegisecurity/spring-security/tags/spring-security-parent-2.0.3</developerConnection>
<url>http://acegisecurity.svn.sourceforge.net/viewcvs.cgi/acegisecurity/spring-security/tags/spring-security-parent-2.0.3</url>
</scm>
<issueManagement>
@@ -732,7 +732,7 @@
</dependencies>
</dependencyManagement>
<properties>
<pom.version.osgi>2.0.2.SNAPSHOT</pom.version.osgi>
<pom.version.osgi>2.0.3.RELEASE</pom.version.osgi>
<spring.version>2.0.8</spring.version>
<spring.version.osgi>[2.0.8, 3.0.0)</spring.version.osgi>
<jstl.version>1.1.2</jstl.version>
+3 -3
View File
@@ -3,18 +3,18 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<artifactId>spring-security-portlet</artifactId>
<name>Spring Security - Portlet support</name>
<description>Spring Security - Support for JSR 168 Portlets</description>
<version>2.0.2</version>
<version>2.0.3</version>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
+4 -4
View File
@@ -18,15 +18,15 @@ BUILDING
-------------------------------------------------------------------------------
Spring Security is built using Maven. Please read the "Building from Source" page
at http://static.springframework.org/spring-security/site/.
This page is also included in the /docs directory of official release ZIPs.
at http://static.springframework.org/spring-security/site/.
-------------------------------------------------------------------------------
DOCUMENTATION
-------------------------------------------------------------------------------
Be sure to read the Reference Guide, which is available from the web site.
Every class also has thorough JavaDocs, which are also available on the web site.
Be sure to read the Reference Guide (docs/reference/html/springsecurity.html).
Extensive JavaDoc for the Spring Security code is also available (in docs/apidocs).
Both can also be found on the website.
-------------------------------------------------------------------------------
QUICK START
+3 -3
View File
@@ -10,11 +10,11 @@ client - this contains the actual sample web application which uses the cas serv
Running the CAS Server
-----------------------
You first need to download the CAS server 3.2 distribution from
You first need to download the CAS server 3.2.1 distribution from
http://www.ja-sig.org/products/cas/downloads/index.html
You only need the modules/cas-server-webapp-3.2.war web application file from the distribution. Copy this to the
You only need the modules/cas-server-webapp-3.2.1.war web application file from the distribution. Copy this to the
"server" directory inside the one that contains this readme file (i.e. copy it to samples/cas/server).
You can then run the CAS server (from the same) by executing the maven command
@@ -34,7 +34,7 @@ Running the Client Application
Leave the server running and start up a separate command window to run the sample application. Change to the directory
samples/cas/client and execute the command
mvn:jetty-run
mvn jetty:run
This should start the sample application on
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples-cas</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples-cas-client</artifactId>
@@ -11,14 +11,15 @@
<sec:logout />
</sec:http>
<sec:authentication-manager alias="authenticationManager"/>
<bean id="casProcessingFilter" class="org.springframework.security.ui.cas.CasProcessingFilter">
<sec:custom-filter after="CAS_PROCESSING_FILTER"/>
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationFailureUrl" value="/casfailed.jsp"/>
<property name="defaultTargetUrl" value="/"/>
<property name="defaultTargetUrl" value="/"/>
<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
<property name="proxyReceptorUrl" value="/secure/receptor" />
</bean>
<bean id="casProcessingFilterEntryPoint" class="org.springframework.security.ui.cas.CasProcessingFilterEntryPoint">
@@ -32,11 +33,15 @@
<property name="serviceProperties" ref="serviceProperties" />
<property name="ticketValidator">
<bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
<constructor-arg index="0" value="https://localhost:9443/cas" />
<constructor-arg index="0" value="https://localhost:9443/cas" />
<property name="proxyGrantingTicketStorage" ref="proxyGrantingTicketStorage" />
<property name="proxyCallbackUrl" value="https://localhost:8443/cas-sample/secure/receptor" />
</bean>
</property>
<property name="key" value="an_id_for_this_auth_provider_only"/>
</bean>
<property name="key" value="an_id_for_this_auth_provider_only"/>
</bean>
<bean id="proxyGrantingTicketStorage" class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl" />
<bean id="serviceProperties" class="org.springframework.security.ui.cas.ServiceProperties">
<property name="service" value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/>
@@ -48,5 +53,4 @@
<sec:user name="dianne" password="dianne" authorities="ROLE_USER" />
<sec:user name="scott" password="scott" authorities="ROLE_USER" />
</sec:user-service>
</beans>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples-cas</artifactId>
+13 -3
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples-cas</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples-cas-server</artifactId>
@@ -17,7 +17,7 @@
<version>6.1.7</version>
<configuration>
<contextPath>/cas</contextPath>
<webApp>${basedir}/cas-server-webapp-3.2.war</webApp>
<webApp>${basedir}/cas-server-webapp-3.2.1.war</webApp>
<connectors>
<connector implementation="org.mortbay.jetty.security.SslSocketConnector">
<port>9443</port>
@@ -30,8 +30,18 @@
<needClientAuth>false</needClientAuth>
</connector>
</connectors>
<systemProperties>
<systemProperty>
<name>javax.net.ssl.trustStore</name>
<value>../../certificates/server.jks</value>
</systemProperty>
<systemProperty>
<name>javax.net.ssl.trustStorePassword</name>
<value>password</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
</project>
</project>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<artifactId>spring-security-samples-contacts</artifactId>
<name>Spring Security - Contacts sample</name>
@@ -36,7 +36,6 @@
<bean name="/ContactManager-hessian" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="contactManager"/>
<property name="serviceInterface" value="sample.contact.ContactManager"/>
</property>
</bean>
<!-- Burlap exporter for the ContactManager -->
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<artifactId>spring-security-samples-dms</artifactId>
<name>Spring Security - DMS sample</name>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples-ldap</artifactId>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples-openid</artifactId>
@@ -15,8 +15,8 @@
<http>
<intercept-url pattern="/**" access="ROLE_USER"/>
<intercept-url pattern="/openidlogin.jsp*" filters="none"/>
<logout/>
<openid-login login-page="/openidlogin.jsp" />
<logout/>
<openid-login login-page="/openidlogin.jsp" authentication-failure-url="/openidlogin.jsp?login_error=true" />
</http>
<authentication-manager alias="authenticationManager"/>
@@ -44,4 +44,4 @@
<user name="http://spring.security.test.myopenid.com/" password="password" authorities="ROLE_SUPERVISOR,ROLE_USER" />
</user-service>
</b:beans>
</b:beans>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples</artifactId>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples-portlet</artifactId>
+1 -2
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples-preauth</artifactId>
@@ -42,7 +42,6 @@
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.1</version>
<optional>true</optional>
</dependency>
</dependencies>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-samples-tutorial</artifactId>
+2 -1
View File
@@ -3,12 +3,13 @@
<parent>
<artifactId>spring-security-parent</artifactId>
<groupId>org.springframework.security</groupId>
<version>2.0.2</version>
<version>2.0.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-captcha</artifactId>
<name>Spring Security - Captcha module</name>
<version>2.0.2-SNAPSHOT</version>
<dependencies>
<dependency>
+2 -2
View File
@@ -4,7 +4,7 @@
<artifactId>spring-security-heavyduty</artifactId>
<name>Spring Security - Heavy Duty Sample</name>
<packaging>war</packaging>
<version>2.0.2</version>
<version>2.0.3-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
@@ -166,7 +166,7 @@
</build>
<properties>
<spring.version>2.5.4</spring.version>
<spring.security.version>2.0.2</spring.security.version>
<spring.security.version>2.0.3-SNAPSHOT</spring.security.version>
</properties>
</project>
@@ -1,6 +1,7 @@
package heavyduty.web;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -23,10 +24,15 @@ public class TestMultiActionController extends MultiActionController {
}
public void step1(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/testMulti.htm?action=step1xtra").forward(request, response);
String[] x = request.getParameterValues("x");
logger.info("x= " + (x == null ? "null" : Arrays.asList(x)));
String[] y = request.getParameterValues("y");
logger.info("y = " + (y == null ? "null" : Arrays.asList(y)));
request.getRequestDispatcher("/testMulti.htm?action=step1xtra&x=5&x=5").forward(request, response);
}
public ModelAndView step1xtra(HttpServletRequest request, HttpServletResponse response) throws ServletRequestBindingException {
logger.info("x = " + Arrays.asList(request.getParameterValues("x")));
return createView("step2");
}
@@ -6,7 +6,9 @@
<body>
<form action="testMulti.htm">
<input name="action" value="${nextAction}" type="text"/>
<input name="action" value="${nextAction}" type="text"/> <br/>
<input name="x" value="5" type="text"/> <br/>
<input name="y" value="5" type="text"/> <br/>
<input type='submit' value='submit' />
</form>
</body>
+240
View File
@@ -0,0 +1,240 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0.3-SNAPSHOT</version>
</parent>
-->
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-itest</artifactId>
<name>Spring Security - Integration Tests</name>
<packaging>pom</packaging>
<version>2.0.3-SNAPSHOT</version>
<modules>
<module>web</module>
<!-- module>webflow</module-->
<!--module>context</module-->
</modules>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.8</version>
<scope>test</scope>
<classifier>jdk15</classifier>
</dependency>
<!--
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.4</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-support</artifactId>
</exclusion>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core-tiger</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.4.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-core</artifactId>
<version>1.0.2</version>
<scope>runtime</scope>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-server-jndi</artifactId>
<version>1.0.2</version>
<scope>runtime</scope>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>jwebunit</groupId>
<artifactId>jwebunit</artifactId>
<version>1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-naming</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-plus</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jsp-2.1</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jsp-api-2.1</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap</artifactId>
<version>1.2.1</version>
<scope>runtime</scope>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.4.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl104-over-slf4j</artifactId>
<version>1.4.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<includes>
<include>**/*Tests.class</include>
</includes>
<excludes>
<exclude>**/Abstract*</exclude>
</excludes>
<forkMode>once</forkMode>
<systemProperties>
<!-- The working directory for the embedded apache Ldap test server -->
<property>
<name>apacheDSWorkDir</name>
<value>
${basedir}/target/apacheds-work
</value>
</property>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jetty.version>6.1.11</jetty.version>
</properties>
</project>
+50
View File
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-itest</artifactId>
<version>2.0.3-SNAPSHOT</version>
</parent>
<artifactId>spring-security-itest-web</artifactId>
<name>Spring Security - Web Integration Tests</name>
<packaging>war</packaging>
<!--
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<scope>runtime</scope>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<scope>runtime</scope>
<version>1.1.2</version>
</dependency>
</dependencies>
-->
<!--
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-jspc-plugin</artifactId>
<version>6.1.11</version>
<executions>
<execution>
<id>jspc</id>
<goals>
<goal>jspc</goal>
</goals>
<configuration>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
-->
</project>
@@ -0,0 +1,9 @@
log4j.rootCategory=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p %c - %m%n
log4j.category.org.apache.jasper=DEBUG
log4j.category.org.mortbay.log=DEBUG
log4j.category.org.springframework.security=DEBUG
@@ -0,0 +1,106 @@
# Users
dn: ou=people,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: people
dn: ou=musicians,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: people
dn: uid=ben,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Ben Alex
sn: Alex
uid: ben
userPassword: {SHA}nFCebWjxfaLbHHG1Qk5UU4trbvQ=
dn: uid=bob,ou=people,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Bob Hamilton
sn: Hamilton
uid: bob
userPassword: bobspassword
dn: uid=miles,ou=musicians,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Miles Davis
sn: Davis
uid: miles
userPassword: milespassword
dn: uid=johnc,ou=musicians,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: John Coltrane
sn: Coltrane
uid: johnc
userPassword: johncspassword
dn: uid=jimi,ou=musicians,dc=springframework,dc=org
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
cn: Jimi Hendrix
sn: Hendrix
uid: jimi
userPassword: {SSHA}S6jnyvykw4K5eF35OXvAkQsf3y2fPrRQ
# Groups
dn: ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: groups
dn: cn=developers,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfUniqueNames
cn: developers
ou: developer
uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
uniqueMember: uid=bob,ou=people,dc=springframework,dc=org
dn: cn=managers,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfUniqueNames
cn: managers
ou: manager
uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
dn: ou=genres,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: organizationalUnit
ou: genres
dn: cn=rock,ou=genres,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfUniqueNames
cn: rock
ou: rock
uniqueMember: uid=jimi,ou=musicians,dc=springframework,dc=org
dn: cn=jazz,ou=genres,ou=groups,dc=springframework,dc=org
objectclass: top
objectclass: groupOfUniqueNames
cn: jazz
ou: jazz
uniqueMember: uid=miles,ou=musicians,dc=springframework,dc=org
@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Class-Path:
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd">
<!--
Http App Context to test form login, remember-me and concurrent session control.
Needs to be supplemented with authentication provider(s)
-->
<http>
<intercept-url pattern="/login.jsp*" filters="none" />
<intercept-url pattern="/secure/**" access="ROLE_DEVELOPER,ROLE_USER" />
<intercept-url pattern="/**" access="ROLE_DEVELOPER,ROLE_USER" />
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=true"/>
<http-basic/>
<!-- Default logout configuration -->
<logout logout-url="/logout"/>
<concurrent-session-control max-sessions="1" />
<remember-me key="doesntmatter" token-repository-ref="tokenRepo"/>
</http>
<beans:bean name="tokenRepo" class="org.springframework.security.ui.rememberme.InMemoryTokenRepositoryImpl"/>
<!-- bean name="rememberMeServices" class="org.springframework.security.ui.rememberme.NullRememberMeServices"/ -->
</beans:beans>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd">
<authentication-provider>
<user-service>
<user name="miles" password="milespassword" authorities="ROLE_USER,ROLE_JAZZ,ROLE_TRUMPETER"/>
<user name="johnc" password="johncspassword" authorities="ROLE_USER,ROLE_JAZZ,ROLE_SAXOPHONIST"/>
<user name="jimi" password="jimispassword" authorities="ROLE_USER,ROLE_ROCK,ROLE_GUITARIST"/>
</user-service>
</authentication-provider>
</beans:beans>
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- LDAP Provider configuration snippet
-
-->
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.2.xsd">
<ldap-server ldif="classpath*:test-server.ldif"/>
<ldap-authentication-provider user-search-filter="(uid={0})" group-role-attribute="ou" />
<ldap-user-service user-search-filter="(uid={0})" group-role-attribute="ou"/>
</beans:beans>
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>Integration Tests Webapp</display-name>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Don't add a context loader listener or config location. These are set programmatically -->
</web-app>
@@ -0,0 +1,35 @@
<!-- %@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" % -->
<!-- Not used unless you declare a <form-login login-page="/login.jsp"/> element -->
<html>
<head>
<title>Custom Spring Security Login</title>
</head>
<body>
<h1>Custom Spring Security Login</h1>
<%
if (request.getParameter("login_error") != null) {
%>
<font color="red">
Your login attempt was not successful, try again.<br/><br/>
</font>
<%
}
%>
<form action="j_spring_security_check" method="POST">
<table>
<tr><td>User:</td><td><input type='text' name='j_username' value=''/></td></tr>
<tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
<tr><td><input type="checkbox" name="_spring_security_remember_me"></td><td>Don't ask for my password for two weeks</td></tr>
<tr><td colspan='2'><input name="submit" type="submit"></td></tr>
<tr><td colspan='2'><input name="reset" type="reset"></td></tr>
</table>
</form>
</body>
</html>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>A secure page</title>
</head>
<body>
A Secure Page.
</body>
</html>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>A secure page</title>
</head>
<body>
<jsp:include page="secure1body.jsp?x=1&y=2"/>
</body>
</html>
@@ -0,0 +1,2 @@
Params: x=<%= request.getParameter("x") %>, y=<%= request.getParameter("y") %>
xcount=<%= request.getParameterValues("x").length %>
@@ -0,0 +1,129 @@
package org.springframework.security.integration;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.util.StringUtils;
import net.sourceforge.jwebunit.WebTester;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.webapp.WebAppContext;
import javax.servlet.ServletContext;
import org.testng.annotations.*;
import com.meterware.httpunit.WebConversation;
/**
* @author Luke Taylor
* @version $Id$
*/
public abstract class AbstractWebServerIntegrationTests {
private Server server;
private final Object SERVER_LOCK = new Object();
protected final WebTester tester = new WebTester();
/**
* Override to set the application context files that should be loaded or return null
* to use web.xml.
*/
protected abstract String getContextConfigLocations();
protected String getContextPath() {
return "/testapp";
}
@BeforeClass
public void startServer() throws Exception {
synchronized(SERVER_LOCK) {
if (server == null) {
//System.setProperty("DEBUG", "true");
//System.setProperty("VERBOSE", "true");
//System.setProperty("IGNORED", "true");
server = new Server(0);
server.addHandler(createWebContext());
server.start();
tester.getTestContext().setBaseUrl(getBaseUrl());
}
}
}
protected WebAppContext createWebContext() {
WebAppContext webCtx = new WebAppContext("src/main/webapp", getContextPath());
if (StringUtils.hasText(getContextConfigLocations())) {
webCtx.addEventListener(new ContextLoaderListener());
webCtx.getInitParams().put("contextConfigLocation", getContextConfigLocations());
}
return webCtx;
}
@AfterClass
public void stopServer() throws Exception {
synchronized(SERVER_LOCK) {
if (server != null) {
server.stop();
}
server = null;
}
}
@AfterMethod
public void resetWebConversation() {
tester.getTestContext().setWebClient(new WebConversation());
}
private final String getBaseUrl() {
int port = server.getConnectors()[0].getLocalPort();
return "http://localhost:" + port + getContextPath() + "/";
}
protected final Object getBean(String beanName) {
return getAppContext().getBean(beanName);
}
private WebApplicationContext getAppContext() {
ServletContext servletCtx = ((WebAppContext)server.getHandler()).getServletContext();
WebApplicationContext appCtx =
WebApplicationContextUtils.getRequiredWebApplicationContext(servletCtx);
return appCtx;
}
// protected final HttpUnitDialog getDialog() {
// return tester.getDialog();
// }
protected final void submit() {
tester.submit();
}
protected final void beginAt(String url) {
tester.beginAt(url);
}
protected final void setFormElement(String name, String value) {
tester.setFormElement(name, value);
}
protected final void assertFormPresent() {
tester.assertFormPresent();
}
protected final void assertTextPresent(String text) {
tester.assertTextPresent(text);
}
// Security-specific utility methods
protected void login(String username, String password) {
assertFormPresent();
setFormElement("j_username", username);
setFormElement("j_password", password);
submit();
}
}
@@ -0,0 +1,42 @@
package org.springframework.security.integration;
import org.testng.annotations.*;
/**
* @author Luke Taylor
* @version $Id$
*/
public class InMemoryProviderWebAppTests extends AbstractWebServerIntegrationTests {
protected String getContextConfigLocations() {
return "/WEB-INF/http-security.xml /WEB-INF/in-memory-provider.xml";
}
@Test
public void loginFailsWithinvalidPassword() {
beginAt("secure/index.html");
login("jimi", "wrongPassword");
assertTextPresent("Your login attempt was not successful");
}
@Test
public void loginSucceedsWithCorrectPassword() {
beginAt("secure/index.html");
login("jimi", "jimispassword");
assertTextPresent("A Secure Page");
tester.gotoPage("/logout");
}
/*
* Checks use of <jsp:include> with parameters in the secured page.
*/
@Test
public void savedRequestWithJspIncludeSeesCorrectParams() {
beginAt("secure/secure1.jsp?x=0");
login("jimi", "jimispassword");
// Included JSP has params ?x=1&y=2
assertTextPresent("Params: x=1, y=2");
assertTextPresent("xcount=2");
}
}
@@ -0,0 +1,20 @@
package org.springframework.security.integration;
import org.testng.annotations.*;
/**
* @author Luke Taylor
* @version $Id$
*/
public class LdapWebAppTests extends AbstractWebServerIntegrationTests {
protected String getContextConfigLocations() {
return "/WEB-INF/http-security.xml /WEB-INF/ldap-provider.xml";
}
@Test
public void doSomething() {
}
}
+1 -1
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-sandbox</artifactId>
<version>2.0.2</version>
<version>2.0.2-SNAPSHOT</version>
</parent>
<artifactId>spring-security-sandbox-other</artifactId>
<name>Spring Security - Other Sandbox Code</name>
+1 -1
View File
@@ -4,7 +4,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-parent</artifactId>
<version>2.0.2</version>
<version>2.0.2-SNAPSHOT</version>
</parent>
<artifactId>spring-security-sandbox</artifactId>
<name>Spring Security - Sandbox</name>
+1 -1
View File
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-sandbox</artifactId>
<version>2.0.2</version>
<version>2.0.2-SNAPSHOT</version>
</parent>
<artifactId>spring-security-webwork</artifactId>
<name>Spring Security - Webwork support</name>
+33
View File
@@ -146,6 +146,39 @@
detected then they could potentially choose any userame they wished.
</para>
</tip>
<section>
<title>Siteminder Example Configuration</title>
<para>
A typical configuration using this filter would look like this:
<programlisting><![CDATA[
<bean id="siteminderFilter"
class="org.springframework.security.ui.preauth.header.RequestHeaderPreAuthenticatedProcessingFilter">
<security:custom-filter position="PRE_AUTH_FILTER" />
<property name="principalRequestHeader" value="SM_USER"/>
<property name="authenticationManager" ref="authenticationManager" />
</bean>
<bean id="preauthAuthProvider"
class="org.springframework.security.providers.preauth.PreAuthenticatedAuthenticationProvider">
<security:custom-authentication-provider />
<property name="preAuthenticatedUserDetailsService">
<bean id="userDetailsServiceWrapper"
class="org.springframework.security.userdetails.UserDetailsByNameServiceWrapper">
<property name="userDetailsService" ref="userDetailsService"/>
</bean>
</property>
</bean>
<security:authentication-manager alias="authenticationManager" />
]]>
</programlisting>
We've assumed here that the security namespace is being used for configuration (hence the user of the <literal>custom-filter</literal>,
<literal>authentication-manager</literal> and <literal>custom-authentication-provider</literal> elements (you can read more about them
in the <link xlink:href="ns-config">namespace chapter</link>). You would leave these out of a traditional bean configuration.
It's also assumed that you have added a <interfacename>UserDetailsService</interfacename> (called <quote>userDetailsService</quote>)
to your configuration to load the user's roles.
</para>
</section>
</section>
<section>
+15 -4
View File
@@ -49,7 +49,8 @@
hopefully be configured to minimize the permissions granted to different
Java types, and then your application will add its own problem
domain-specific security configuration. Spring Security makes this latter
area - application security - much easier.</para>
area - application security - much easier.
</para>
<para>Of course, you will need to properly address all security layers
mentioned above, together with managerial factors that encompass every
@@ -65,7 +66,8 @@
banking application has different needs from an ecommerce application. An
ecommerce application has different needs from a corporate sales force
automation tool. These custom requirements make application security
interesting, challenging and rewarding.</para>
interesting, challenging and rewarding.
</para>
<para>Please read <xref linkend="getting-started"/>, in
its entirety to begin with. This will introduce you to the framework and the namespace-based
@@ -73,10 +75,19 @@
of an in-depth understaning of how Spring Security works, and some of the classes you might
need to use, you should then read <xref linkend="overall-architecture"/>.
The remaining parts of this guide are structured in a more traditional reference style,
designed to be read on an as-required basis.</para>
designed to be read on an as-required basis. We'd also recommend that you read up as much as
possible on application security issues in general. Spring Security is not a panacea which will
solve all security issues. It is important that the application is designed with security in
mind from the start. Attempting to retrofit it is not a good idea.
In particular, if you are building a web application, you should be aware of the many potential
vulnerabilities such as cross-site scripting, request-forgery and session-hijacking which you should
be taking into account from the start. The OWASP web site (http://www.owasp.org/) maintains a
top ten list of web application vulnerabilities as well as a lot of useful reference information.
</para>
<para>We hope that you find this reference guide useful, and we welcome
your feedback and <link xlink:href="#jira">suggestions</link>.</para>
your feedback and <link xlink:href="#jira">suggestions</link>.
</para>
<para>Finally, welcome to the Spring Security <link xlink:href="#community" >community</link>.
</para>
+10 -10
View File
@@ -19,15 +19,15 @@ Tutorial: Adding Security to Spring Petclinic
You will also need to download:
* {{{http://www.springframework.org/download}Spring 2.5.2 with dependencies ZIP file}}
* {{{http://www.springframework.org/download}Spring 2.5.4 with dependencies ZIP file}}
* {{{http://www.springframework.org/download}Spring Security 2.0}}
* {{{http://www.springframework.org/download}Spring Security 2.0.2}}
Unzip both files. After unzipping Spring Security, you'll need to unzip the
spring-security-sample-tutorial-2.0.war file, because we need some files that are
spring-security-sample-tutorial-2.0.2.war file, because we need some files that are
included within it. After unzipping the war file, you will see a folder called
spring-security-samples-tutorial-2.0.0.
spring-security-samples-tutorial-2.0.2.
In the code below, we'll refer to the respective unzipped
locations as %spring% and %spring-sec-tutorial% (with the later variable
@@ -82,10 +82,10 @@ copy dist\petclinic.war %TOMCAT_HOME%\webapps
+------------------------------------------------------
copy %spring-sec-tutorial%\WEB-INF\applicationContext-security-ns.xml %spring%\samples\petclinic\war\WEB-INF
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-core-2.0.0-RC1.jar %spring%\samples\petclinic\war\WEB-INF\lib
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-core-tiger-2.0.0-RC1.jar %spring%\samples\petclinic\war\WEB-INF\lib
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-acl-2.0.0-RC1.jar %spring%\samples\petclinic\war\WEB-INF\lib
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-taglibs-2.0.0-RC1.jar %spring%\samples\petclinic\war\WEB-INF\lib
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-core-2.0.2.jar %spring%\samples\petclinic\war\WEB-INF\lib
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-core-tiger-2.0.2.jar %spring%\samples\petclinic\war\WEB-INF\lib
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-acl-2.0.2.jar %spring%\samples\petclinic\war\WEB-INF\lib
copy %spring-sec-tutorial%\WEB-INF\lib\spring-security-taglibs-2.0.2.jar %spring%\samples\petclinic\war\WEB-INF\lib
copy %spring-sec-tutorial%\WEB-INF\lib\commons-codec-1.3.jar %spring%\samples\petclinic\war\WEB-INF\lib
+------------------------------------------------------
@@ -95,7 +95,7 @@ copy %spring-sec-tutorial%\WEB-INF\lib\commons-codec-1.3.jar %spring%\samples\pe
Edit %spring%\samples\petclinic\war\WEB-INF\web.xml. The "contextConfigLocation" specifies Spring configuration files that should be used
by the petclinic application. Locate the "contextConfigLocation" parameter and add a new line into
the existing param-value. Now that we are using Spring Security, It should also declare
applicationContext-security-ns.xml (Spring config file for Spring Security).
applicationContext-security.xml (Spring config file for Spring Security).
The resulting block will look like this:
+------------------------------------------------------
@@ -104,7 +104,7 @@ copy %spring-sec-tutorial%\WEB-INF\lib\commons-codec-1.3.jar %spring%\samples\pe
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext-jdbc.xml
/WEB-INF/applicationContext-security-ns.xml
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
+2 -3
View File
@@ -16,11 +16,10 @@
</href>
</bannerLeft>
<body>
<!--
<links>
<item name="Spring Security on Sourceforge" href="http://sourceforge.net/projects/acegisecurity" />
<item name="Spring Framework" href="http://www.springframework.org/"/>
<item name="OWASP" href="http://www.owasp.org/"/>
</links>
-->
<menu name="Overview">
<item name="Home" href="index.html"/>
<item name="Building from Source" href="building.html"/>
+2 -2
View File
@@ -3,13 +3,13 @@
<parent>
<artifactId>spring-security-parent</artifactId>
<groupId>org.springframework.security</groupId>
<version>2.0.2</version>
<version>2.0.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<name>Spring Security - JSP taglibs</name>
<version>2.0.2</version>
<version>2.0.3</version>
<packaging>jar</packaging>
<dependencies>