Browse Source

SEC-999: Introduced custom SecurityExpressionEvaluationContext which is responsible for lazy initialization of parameter values in the context. Also some further conversion of code using GrantedAuthority arrays.

3.0.x
Luke Taylor 18 years ago
parent
commit
514bca669f
  1. 15
      acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategyImpl.java
  2. 459
      acl/src/test/java/org/springframework/security/acls/domain/AclImplementationSecurityCheckTests.java
  3. 6
      core/src/main/java/org/springframework/security/expression/ExpressionUtils.java
  4. 48
      core/src/main/java/org/springframework/security/expression/SecurityEvaluationContext.java
  5. 11
      core/src/main/java/org/springframework/security/expression/annotation/PreFilter.java
  6. 10
      core/src/main/java/org/springframework/security/expression/support/AbstractExpressionBasedMethodConfigAttribute.java
  7. 4
      core/src/main/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSource.java
  8. 10
      core/src/main/java/org/springframework/security/expression/support/MethodExpressionAfterInvocationProvider.java
  9. 69
      core/src/main/java/org/springframework/security/expression/support/MethodExpressionVoter.java
  10. 4
      core/src/main/java/org/springframework/security/expression/support/PostInvocationExpressionAttribute.java
  11. 4
      core/src/main/java/org/springframework/security/expression/support/PreInvocationExpressionAttribute.java
  12. 27
      core/src/main/java/org/springframework/security/expression/support/WebExpressionConfigAttribute.java
  13. 26
      core/src/main/java/org/springframework/security/expression/support/WebExpressionVoter.java
  14. 6
      core/src/main/java/org/springframework/security/util/SimpleMethodInvocation.java
  15. 14
      core/src/test/java/org/springframework/security/context/rmi/ContextPropagatingRemoteInvocationTests.java
  16. 30
      core/src/test/java/org/springframework/security/expression/SecurityExpressionTests.java
  17. 28
      core/src/test/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSourceTests.java
  18. 100
      core/src/test/java/org/springframework/security/expression/support/MethodExpressionVoterTests.java
  19. 3
      core/src/test/java/org/springframework/security/intercept/method/aspectj/AspectJSecurityInterceptorTests.java
  20. 3
      core/src/test/java/org/springframework/security/providers/anonymous/AnonymousAuthenticationTokenTests.java
  21. 3
      core/src/test/java/org/springframework/security/providers/jaas/JaasAuthenticationProviderTests.java
  22. 128
      core/src/test/java/org/springframework/security/providers/preauth/PreAuthenticatedAuthenticationProviderTests.java
  23. 6
      core/src/test/java/org/springframework/security/wrapper/SecurityContextHolderAwareRequestWrapperTests.java
  24. 34
      taglibs/src/test/java/org/springframework/security/taglibs/authz/AclTagTests.java
  25. 4
      taglibs/src/test/java/org/springframework/security/taglibs/authz/AuthenticationTagTests.java
  26. 4
      taglibs/src/test/java/org/springframework/security/taglibs/velocity/AuthzImplTests.java

15
acl/src/main/java/org/springframework/security/acls/domain/AclAuthorizationStrategyImpl.java

@ -34,10 +34,12 @@ import org.springframework.util.Assert;
/** /**
* Default implementation of {@link AclAuthorizationStrategy}.<p>Permission will be granted provided the current * Default implementation of {@link AclAuthorizationStrategy}.
* principal is either the owner (as defined by the ACL), has {@link BasePermission#ADMINISTRATION} (as defined by the * <p>
* ACL and via a {@link Sid} retrieved for the current principal via {@link #sidRetrievalStrategy}), or if the current * Permission will be granted provided the current principal is either the owner (as defined by the ACL), has
* principal holds the relevant system-wide {@link GrantedAuthority} and injected into the constructor.</p> * {@link BasePermission#ADMINISTRATION} (as defined by the ACL and via a {@link Sid} retrieved for the current
* principal via {@link #sidRetrievalStrategy}), or if the current principal holds the relevant system-wide
* {@link GrantedAuthority} and injected into the constructor.
* *
* @author Ben Alex * @author Ben Alex
* @version $Id$ * @version $Id$
@ -52,7 +54,7 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
/** /**
* Constructor. The only mandatory parameter relates to the system-wide {@link GrantedAuthority} instances that * Constructor. The only mandatory parameter relates to the system-wide {@link GrantedAuthority} instances that
* can be held to always permit ACL changes. * can be held to always permit ACL changes.
* *
@ -62,8 +64,7 @@ public class AclAuthorizationStrategyImpl implements AclAuthorizationStrategy {
* index 2 is the authority needed to change other ACL and ACE details) (required) * index 2 is the authority needed to change other ACL and ACE details) (required)
*/ */
public AclAuthorizationStrategyImpl(GrantedAuthority[] auths) { public AclAuthorizationStrategyImpl(GrantedAuthority[] auths) {
Assert.notEmpty(auths, "GrantedAuthority[] with three elements required"); Assert.isTrue(auths != null && auths.length == 3, "GrantedAuthority[] with three elements required");
Assert.isTrue(auths.length == 3, "GrantedAuthority[] with three elements required");
this.gaTakeOwnership = auths[0]; this.gaTakeOwnership = auths[0];
this.gaModifyAuditing = auths[1]; this.gaModifyAuditing = auths[1];
this.gaGeneralChanges = auths[2]; this.gaGeneralChanges = auths[2];

459
acl/src/test/java/org/springframework/security/acls/domain/AclImplementationSecurityCheckTests.java

@ -19,278 +19,243 @@ import org.springframework.security.providers.TestingAuthenticationToken;
/** /**
* Test class for {@link AclAuthorizationStrategyImpl} and {@link AclImpl} * Test class for {@link AclAuthorizationStrategyImpl} and {@link AclImpl}
* security checks. * security checks.
* *
* @author Andrei Stefan * @author Andrei Stefan
*/ */
public class AclImplementationSecurityCheckTests extends TestCase { public class AclImplementationSecurityCheckTests extends TestCase {
//~ Methods ========================================================================================================
protected void setUp() throws Exception { //~ Methods ========================================================================================================
SecurityContextHolder.clearContext();
}
protected void tearDown() throws Exception { protected void setUp() throws Exception {
SecurityContextHolder.clearContext(); SecurityContextHolder.clearContext();
} }
public void testSecurityCheckNoACEs() throws Exception { protected void tearDown() throws Exception {
Authentication auth = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] { SecurityContextHolder.clearContext();
new GrantedAuthorityImpl("ROLE_GENERAL"), new GrantedAuthorityImpl("ROLE_AUDITING"), }
new GrantedAuthorityImpl("ROLE_OWNERSHIP") });
auth.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(auth);
ObjectIdentity identity = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100)); public void testSecurityCheckNoACEs() throws Exception {
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] { Authentication auth = new TestingAuthenticationToken("user", "password","ROLE_GENERAL","ROLE_AUDITING","ROLE_OWNERSHIP");
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"), auth.setAuthenticated(true);
new GrantedAuthorityImpl("ROLE_GENERAL") }); SecurityContextHolder.getContext().setAuthentication(auth);
Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger()); ObjectIdentity identity = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100));
try { AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL); new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
Assert.assertTrue(true); new GrantedAuthorityImpl("ROLE_GENERAL") });
}
catch (AccessDeniedException notExpected) {
Assert.fail("It shouldn't have thrown AccessDeniedException");
}
try {
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING);
Assert.assertTrue(true);
}
catch (AccessDeniedException notExpected) {
Assert.fail("It shouldn't have thrown AccessDeniedException");
}
try {
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
Assert.assertTrue(true);
}
catch (AccessDeniedException notExpected) {
Assert.fail("It shouldn't have thrown AccessDeniedException");
}
// Create another authorization strategy Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
AclAuthorizationStrategy aclAuthorizationStrategy2 = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"),
new GrantedAuthorityImpl("ROLE_THREE") });
Acl acl2 = new AclImpl(identity, new Long(1), aclAuthorizationStrategy2, new ConsoleAuditLogger());
// Check access in case the principal has no authorization rights
try {
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_GENERAL);
Assert.fail("It should have thrown NotFoundException");
}
catch (NotFoundException expected) {
Assert.assertTrue(true);
}
try {
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_AUDITING);
Assert.fail("It should have thrown NotFoundException");
}
catch (NotFoundException expected) {
Assert.assertTrue(true);
}
try {
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
Assert.fail("It should have thrown NotFoundException");
}
catch (NotFoundException expected) {
Assert.assertTrue(true);
}
}
public void testSecurityCheckWithMultipleACEs() throws Exception { aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
// Create a simple authentication with ROLE_GENERAL aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING);
Authentication auth = new TestingAuthenticationToken("user", "password", aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_GENERAL") });
auth.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(auth);
ObjectIdentity identity = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100)); // Create another authorization strategy
// Authorization strategy will require a different role for each access AclAuthorizationStrategy aclAuthorizationStrategy2 = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"),
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"), new GrantedAuthorityImpl("ROLE_THREE") });
new GrantedAuthorityImpl("ROLE_GENERAL") }); Acl acl2 = new AclImpl(identity, new Long(1), aclAuthorizationStrategy2, new ConsoleAuditLogger());
// Check access in case the principal has no authorization rights
try {
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_GENERAL);
Assert.fail("It should have thrown NotFoundException");
}
catch (NotFoundException expected) {
}
try {
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_AUDITING);
Assert.fail("It should have thrown NotFoundException");
}
catch (NotFoundException expected) {
}
try {
aclAuthorizationStrategy2.securityCheck(acl2, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
Assert.fail("It should have thrown NotFoundException");
}
catch (NotFoundException expected) {
}
}
// Let's give the principal the ADMINISTRATION permission, without public void testSecurityCheckWithMultipleACEs() throws Exception {
// granting access // Create a simple authentication with ROLE_GENERAL
MutableAcl aclFirstDeny = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger()); Authentication auth = new TestingAuthenticationToken("user", "password",
aclFirstDeny.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false); new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_GENERAL") });
auth.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(auth);
// The CHANGE_GENERAL test should pass as the principal has ROLE_GENERAL ObjectIdentity identity = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100));
try { // Authorization strategy will require a different role for each access
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_GENERAL); AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
Assert.assertTrue(true); new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
} new GrantedAuthorityImpl("ROLE_GENERAL") });
catch (AccessDeniedException notExpected) {
Assert.fail("It shouldn't have thrown AccessDeniedException");
}
// The CHANGE_AUDITING and CHANGE_OWNERSHIP should fail since the
// principal doesn't have these authorities,
// nor granting access
try {
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_AUDITING);
Assert.fail("It should have thrown AccessDeniedException");
}
catch (AccessDeniedException expected) {
Assert.assertTrue(true);
}
try {
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
Assert.fail("It should have thrown AccessDeniedException");
}
catch (AccessDeniedException expected) {
Assert.assertTrue(true);
}
// Add granting access to this principal // Let's give the principal the ADMINISTRATION permission, without
aclFirstDeny.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true); // granting access
// and try again for CHANGE_AUDITING - the first ACE's granting flag MutableAcl aclFirstDeny = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
// (false) will deny this access aclFirstDeny.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false);
try {
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_AUDITING);
Assert.fail("It should have thrown AccessDeniedException");
}
catch (AccessDeniedException expected) {
Assert.assertTrue(true);
}
// Create another ACL and give the principal the ADMINISTRATION // The CHANGE_GENERAL test should pass as the principal has ROLE_GENERAL
// permission, with granting access aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_GENERAL);
MutableAcl aclFirstAllow = new AclImpl(identity, new Long(1), aclAuthorizationStrategy,
new ConsoleAuditLogger());
aclFirstAllow.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
// The CHANGE_AUDITING test should pass as there is one ACE with // The CHANGE_AUDITING and CHANGE_OWNERSHIP should fail since the
// granting access // principal doesn't have these authorities,
try { // nor granting access
aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING); try {
Assert.assertTrue(true); aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_AUDITING);
} Assert.fail("It should have thrown AccessDeniedException");
catch (AccessDeniedException notExpected) { }
Assert.fail("It shouldn't have thrown AccessDeniedException"); catch (AccessDeniedException expected) {
} }
try {
aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
Assert.fail("It should have thrown AccessDeniedException");
}
catch (AccessDeniedException expected) {
}
// Add a deny ACE and test again for CHANGE_AUDITING // Add granting access to this principal
aclFirstAllow.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false); aclFirstDeny.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
try { // and try again for CHANGE_AUDITING - the first ACE's granting flag
aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING); // (false) will deny this access
Assert.assertTrue(true); try {
} aclAuthorizationStrategy.securityCheck(aclFirstDeny, AclAuthorizationStrategy.CHANGE_AUDITING);
catch (AccessDeniedException notExpected) { Assert.fail("It should have thrown AccessDeniedException");
Assert.fail("It shouldn't have thrown AccessDeniedException"); }
} catch (AccessDeniedException expected) {
}
// Create an ACL with no ACE // Create another ACL and give the principal the ADMINISTRATION
MutableAcl aclNoACE = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger()); // permission, with granting access
try { MutableAcl aclFirstAllow = new AclImpl(identity, new Long(1), aclAuthorizationStrategy,
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_AUDITING); new ConsoleAuditLogger());
Assert.fail("It should have thrown NotFoundException"); aclFirstAllow.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
}
catch (NotFoundException expected) {
Assert.assertTrue(true);
}
// and still grant access for CHANGE_GENERAL
try {
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_GENERAL);
Assert.assertTrue(true);
}
catch (NotFoundException expected) {
Assert.fail("It shouldn't have thrown NotFoundException");
}
}
public void testSecurityCheckWithInheritableACEs() throws Exception { // The CHANGE_AUDITING test should pass as there is one ACE with
// Create a simple authentication with ROLE_GENERAL // granting access
Authentication auth = new TestingAuthenticationToken("user", "password",
new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_GENERAL") });
auth.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(auth);
ObjectIdentity identity = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100)); aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING);
// Authorization strategy will require a different role for each access
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"),
new GrantedAuthorityImpl("ROLE_GENERAL") });
// Let's give the principal an ADMINISTRATION permission, with granting // Add a deny ACE and test again for CHANGE_AUDITING
// access aclFirstAllow.insertAce(1, BasePermission.ADMINISTRATION, new PrincipalSid(auth), false);
MutableAcl parentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger()); try {
parentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true); aclAuthorizationStrategy.securityCheck(aclFirstAllow, AclAuthorizationStrategy.CHANGE_AUDITING);
MutableAcl childAcl = new AclImpl(identity, new Long(2), aclAuthorizationStrategy, new ConsoleAuditLogger()); Assert.assertTrue(true);
}
catch (AccessDeniedException notExpected) {
Assert.fail("It shouldn't have thrown AccessDeniedException");
}
// Check against the 'child' acl, which doesn't offer any authorization // Create an ACL with no ACE
// rights on CHANGE_OWNERSHIP MutableAcl aclNoACE = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
try { try {
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP); aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_AUDITING);
Assert.fail("It should have thrown NotFoundException"); Assert.fail("It should have thrown NotFoundException");
} }
catch (NotFoundException expected) { catch (NotFoundException expected) {
Assert.assertTrue(true); Assert.assertTrue(true);
} }
// and still grant access for CHANGE_GENERAL
try {
aclAuthorizationStrategy.securityCheck(aclNoACE, AclAuthorizationStrategy.CHANGE_GENERAL);
Assert.assertTrue(true);
}
catch (NotFoundException expected) {
Assert.fail("It shouldn't have thrown NotFoundException");
}
}
// Link the child with its parent and test again against the public void testSecurityCheckWithInheritableACEs() throws Exception {
// CHANGE_OWNERSHIP right // Create a simple authentication with ROLE_GENERAL
childAcl.setParent(parentAcl); Authentication auth = new TestingAuthenticationToken("user", "password",
childAcl.setEntriesInheriting(true); new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_GENERAL") });
try { auth.setAuthenticated(true);
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP); SecurityContextHolder.getContext().setAuthentication(auth);
Assert.assertTrue(true);
}
catch (NotFoundException expected) {
Assert.fail("It shouldn't have thrown NotFoundException");
}
// Create a root parent and link it to the middle parent ObjectIdentity identity = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100));
MutableAcl rootParentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, // Authorization strategy will require a different role for each access
new ConsoleAuditLogger()); AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
parentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger()); new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_TWO"),
rootParentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true); new GrantedAuthorityImpl("ROLE_GENERAL") });
parentAcl.setEntriesInheriting(true);
parentAcl.setParent(rootParentAcl);
childAcl.setParent(parentAcl);
try {
aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
Assert.assertTrue(true);
}
catch (NotFoundException expected) {
Assert.fail("It shouldn't have thrown NotFoundException");
}
}
public void testSecurityCheckPrincipalOwner() throws Exception { // Let's give the principal an ADMINISTRATION permission, with granting
Authentication auth = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] { // access
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_ONE"), MutableAcl parentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
new GrantedAuthorityImpl("ROLE_ONE") }); parentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
auth.setAuthenticated(true); MutableAcl childAcl = new AclImpl(identity, new Long(2), aclAuthorizationStrategy, new ConsoleAuditLogger());
SecurityContextHolder.getContext().setAuthentication(auth);
ObjectIdentity identity = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100)); // Check against the 'child' acl, which doesn't offer any authorization
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] { // rights on CHANGE_OWNERSHIP
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"), try {
new GrantedAuthorityImpl("ROLE_GENERAL") }); aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
Assert.fail("It should have thrown NotFoundException");
}
catch (NotFoundException expected) {
Assert.assertTrue(true);
}
Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger(), null, null, // Link the child with its parent and test again against the
false, new PrincipalSid(auth)); // CHANGE_OWNERSHIP right
try { childAcl.setParent(parentAcl);
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL); childAcl.setEntriesInheriting(true);
Assert.assertTrue(true); try {
} aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
catch (AccessDeniedException notExpected) { Assert.assertTrue(true);
Assert.fail("It shouldn't have thrown AccessDeniedException"); }
} catch (NotFoundException expected) {
try { Assert.fail("It shouldn't have thrown NotFoundException");
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING); }
Assert.fail("It shouldn't have thrown AccessDeniedException");
} // Create a root parent and link it to the middle parent
catch (NotFoundException expected) { MutableAcl rootParentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy,
Assert.assertTrue(true); new ConsoleAuditLogger());
} parentAcl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger());
try { rootParentAcl.insertAce(0, BasePermission.ADMINISTRATION, new PrincipalSid(auth), true);
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP); parentAcl.setEntriesInheriting(true);
Assert.assertTrue(true); parentAcl.setParent(rootParentAcl);
} childAcl.setParent(parentAcl);
catch (AccessDeniedException notExpected) { try {
Assert.fail("It shouldn't have thrown AccessDeniedException"); aclAuthorizationStrategy.securityCheck(childAcl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
} Assert.assertTrue(true);
} }
catch (NotFoundException expected) {
Assert.fail("It shouldn't have thrown NotFoundException");
}
}
public void testSecurityCheckPrincipalOwner() throws Exception {
Authentication auth = new TestingAuthenticationToken("user", "password", new GrantedAuthority[] {
new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl("ROLE_ONE"),
new GrantedAuthorityImpl("ROLE_ONE") });
auth.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(auth);
ObjectIdentity identity = new ObjectIdentityImpl("org.springframework.security.TargetObject", new Long(100));
AclAuthorizationStrategy aclAuthorizationStrategy = new AclAuthorizationStrategyImpl(new GrantedAuthority[] {
new GrantedAuthorityImpl("ROLE_OWNERSHIP"), new GrantedAuthorityImpl("ROLE_AUDITING"),
new GrantedAuthorityImpl("ROLE_GENERAL") });
Acl acl = new AclImpl(identity, new Long(1), aclAuthorizationStrategy, new ConsoleAuditLogger(), null, null,
false, new PrincipalSid(auth));
try {
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_GENERAL);
Assert.assertTrue(true);
}
catch (AccessDeniedException notExpected) {
Assert.fail("It shouldn't have thrown AccessDeniedException");
}
try {
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_AUDITING);
Assert.fail("It shouldn't have thrown AccessDeniedException");
}
catch (NotFoundException expected) {
Assert.assertTrue(true);
}
try {
aclAuthorizationStrategy.securityCheck(acl, AclAuthorizationStrategy.CHANGE_OWNERSHIP);
Assert.assertTrue(true);
}
catch (AccessDeniedException notExpected) {
Assert.fail("It shouldn't have thrown AccessDeniedException");
}
}
} }

6
core/src/main/java/org/springframework/security/expression/ExpressionUtils.java

@ -5,12 +5,12 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException; import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression; import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.StandardEvaluationContext;
public class ExpressionUtils { public class ExpressionUtils {
public static Object doFilter(Object filterTarget, Expression filterExpression, StandardEvaluationContext ctx) { public static Object doFilter(Object filterTarget, Expression filterExpression, EvaluationContext ctx) {
SecurityExpressionRoot rootObject = (SecurityExpressionRoot) ctx.getRootContextObject(); SecurityExpressionRoot rootObject = (SecurityExpressionRoot) ctx.getRootContextObject();
Set removeList = new HashSet(); Set removeList = new HashSet();
@ -55,7 +55,7 @@ public class ExpressionUtils {
throw new IllegalArgumentException("Filter target must be a collection or array type, but was " + filterTarget); throw new IllegalArgumentException("Filter target must be a collection or array type, but was " + filterTarget);
} }
public static boolean evaluateAsBoolean(Expression expr, StandardEvaluationContext ctx) { public static boolean evaluateAsBoolean(Expression expr, EvaluationContext ctx) {
try { try {
return ((Boolean) expr.getValue(ctx, Boolean.class)).booleanValue(); return ((Boolean) expr.getValue(ctx, Boolean.class)).booleanValue();
} catch (EvaluationException e) { } catch (EvaluationException e) {

48
core/src/main/java/org/springframework/security/expression/SecurityEvaluationContext.java

@ -0,0 +1,48 @@
package org.springframework.security.expression;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.spel.standard.StandardEvaluationContext;
import org.springframework.security.Authentication;
import org.springframework.util.ClassUtils;
/**
*
* @author Luke Taylor
* @since 2.5
*/
public class SecurityEvaluationContext extends StandardEvaluationContext {
private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
private boolean argumentsAdded;
private MethodInvocation mi;
public SecurityEvaluationContext(Authentication user, MethodInvocation mi) {
setRootObject(new SecurityExpressionRoot(user));
this.mi = mi;
}
@Override
public Object lookupVariable(String name) {
if (!argumentsAdded) {
addArgumentsAsVariables();
}
return super.lookupVariable(name);
}
private void addArgumentsAsVariables() {
Object[] args = mi.getArguments();
Object targetObject = mi.getThis();
Method method = ClassUtils.getMostSpecificMethod(mi.getMethod(), targetObject.getClass());
String[] paramNames = parameterNameDiscoverer.getParameterNames(method);
for(int i=0; i < args.length; i++) {
super.setVariable(paramNames[i], args[i]);
}
}
}

11
core/src/main/java/org/springframework/security/expression/annotation/PreFilter.java

@ -11,7 +11,11 @@ import java.lang.annotation.Target;
* Annotation for specifying a method filtering expression which will be evaluated before a method has been invoked. * Annotation for specifying a method filtering expression which will be evaluated before a method has been invoked.
* The name of the argument to be filtered is specified using the <tt>filterTarget</tt> attribute. This must be a * The name of the argument to be filtered is specified using the <tt>filterTarget</tt> attribute. This must be a
* Java Collection implementation which supports the {@link java.util.Collection#remove(Object) remove} method. * Java Collection implementation which supports the {@link java.util.Collection#remove(Object) remove} method.
* Pre-filtering isn't supported on array types. * Pre-filtering isn't supported on array types and will fail if the value of named filter target argument is null
* at runtime.
* <p>
* For methods which have a single argument which is a collection type, this argument will be used as the filter
* target.
* <p> * <p>
* The annotation value contains the expression which will be evaluated for each element in the collection. If the * The annotation value contains the expression which will be evaluated for each element in the collection. If the
* expression evaluates to false, the element will be removed. The reserved name "filterObject" can be used within the * expression evaluates to false, the element will be removed. The reserved name "filterObject" can be used within the
@ -32,7 +36,8 @@ public @interface PreFilter {
public String value(); public String value();
/** /**
* @return the name of the parameter which should be filtered (must be an array or collection) * @return the name of the parameter which should be filtered (must be a non-null collection instance)
* If the method contains a single collection argument, then this attribute can be omitted.
*/ */
public String filterTarget(); public String filterTarget() default "";
} }

10
core/src/main/java/org/springframework/security/expression/support/AbstractExpressionBasedMethodConfigAttribute.java

@ -21,6 +21,9 @@ abstract class AbstractExpressionBasedMethodConfigAttribute implements ConfigAtt
private final Expression filterExpression; private final Expression filterExpression;
private final Expression authorizeExpression; private final Expression authorizeExpression;
/**
* Parses the supplied expressions as Spring-EL.
*/
AbstractExpressionBasedMethodConfigAttribute(String filterExpression, String authorizeExpression) throws ParseException { AbstractExpressionBasedMethodConfigAttribute(String filterExpression, String authorizeExpression) throws ParseException {
Assert.isTrue(filterExpression != null || authorizeExpression != null, "Filter and authorization Expressions cannot both be null"); Assert.isTrue(filterExpression != null || authorizeExpression != null, "Filter and authorization Expressions cannot both be null");
SpelExpressionParser parser = new SpelExpressionParser(); SpelExpressionParser parser = new SpelExpressionParser();
@ -28,6 +31,13 @@ abstract class AbstractExpressionBasedMethodConfigAttribute implements ConfigAtt
this.authorizeExpression = authorizeExpression == null ? null : parser.parseExpression(authorizeExpression); this.authorizeExpression = authorizeExpression == null ? null : parser.parseExpression(authorizeExpression);
} }
AbstractExpressionBasedMethodConfigAttribute(Expression filterExpression, Expression authorizeExpression) throws ParseException {
Assert.isTrue(filterExpression != null || authorizeExpression != null, "Filter and authorization Expressions cannot both be null");
SpelExpressionParser parser = new SpelExpressionParser();
this.filterExpression = filterExpression == null ? null : filterExpression;
this.authorizeExpression = authorizeExpression == null ? null : authorizeExpression;
}
Expression getFilterExpression() { Expression getFilterExpression() {
return filterExpression; return filterExpression;
} }

4
core/src/main/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSource.java

@ -122,9 +122,9 @@ public class ExpressionAnnotationMethodDefinitionSource extends AbstractMethodDe
String postFilterExpression = postFilter == null ? null : postFilter.value(); String postFilterExpression = postFilter == null ? null : postFilter.value();
try { try {
pre = new PreInvocationExpressionConfigAttribute(preFilterExpression, filterObject, preAuthorizeExpression); pre = new PreInvocationExpressionAttribute(preFilterExpression, filterObject, preAuthorizeExpression);
if (postFilterExpression != null || postAuthorizeExpression != null) { if (postFilterExpression != null || postAuthorizeExpression != null) {
post = new PostInvocationExpressionConfigAttribute(postFilterExpression, postAuthorizeExpression); post = new PostInvocationExpressionAttribute(postFilterExpression, postAuthorizeExpression);
} }
} catch (ParseException e) { } catch (ParseException e) {
throw new SecurityConfigurationException("Failed to parse expression '" + e.getExpressionString() + "'", e); throw new SecurityConfigurationException("Failed to parse expression '" + e.getExpressionString() + "'", e);

10
core/src/main/java/org/springframework/security/expression/support/MethodExpressionAfterInvocationProvider.java

@ -35,7 +35,7 @@ public class MethodExpressionAfterInvocationProvider implements AfterInvocationP
public Object decide(Authentication authentication, Object object, List<ConfigAttribute> config, Object returnedObject) public Object decide(Authentication authentication, Object object, List<ConfigAttribute> config, Object returnedObject)
throws AccessDeniedException { throws AccessDeniedException {
PostInvocationExpressionConfigAttribute mca = findMethodAccessControlExpression(config); PostInvocationExpressionAttribute mca = findMethodAccessControlExpression(config);
if (mca == null) { if (mca == null) {
return returnedObject; return returnedObject;
@ -86,11 +86,11 @@ public class MethodExpressionAfterInvocationProvider implements AfterInvocationP
} }
} }
private PostInvocationExpressionConfigAttribute findMethodAccessControlExpression(List<ConfigAttribute> config) { private PostInvocationExpressionAttribute findMethodAccessControlExpression(List<ConfigAttribute> config) {
// Find the MethodAccessControlExpression attribute // Find the MethodAccessControlExpression attribute
for (ConfigAttribute attribute : config) { for (ConfigAttribute attribute : config) {
if (attribute instanceof PostInvocationExpressionConfigAttribute) { if (attribute instanceof PostInvocationExpressionAttribute) {
return (PostInvocationExpressionConfigAttribute)attribute; return (PostInvocationExpressionAttribute)attribute;
} }
} }
@ -98,7 +98,7 @@ public class MethodExpressionAfterInvocationProvider implements AfterInvocationP
} }
public boolean supports(ConfigAttribute attribute) { public boolean supports(ConfigAttribute attribute) {
return attribute instanceof PostInvocationExpressionConfigAttribute; return attribute instanceof PostInvocationExpressionAttribute;
} }
public boolean supports(Class clazz) { public boolean supports(Class clazz) {

69
core/src/main/java/org/springframework/security/expression/support/MethodExpressionVoter.java

@ -1,22 +1,18 @@
package org.springframework.security.expression.support; package org.springframework.security.expression.support;
import java.lang.reflect.Method; import java.util.Collection;
import java.util.List; import java.util.List;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext; import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression; import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.StandardEvaluationContext;
import org.springframework.security.Authentication; import org.springframework.security.Authentication;
import org.springframework.security.ConfigAttribute; import org.springframework.security.ConfigAttribute;
import org.springframework.security.expression.ExpressionUtils; import org.springframework.security.expression.ExpressionUtils;
import org.springframework.security.expression.SecurityExpressionRoot; import org.springframework.security.expression.SecurityEvaluationContext;
import org.springframework.security.vote.AccessDecisionVoter; import org.springframework.security.vote.AccessDecisionVoter;
import org.springframework.util.ClassUtils;
/** /**
* Voter which performs the actions for @PreFilter and @PostAuthorize annotations. * Voter which performs the actions for @PreFilter and @PostAuthorize annotations.
@ -32,9 +28,6 @@ import org.springframework.util.ClassUtils;
public class MethodExpressionVoter implements AccessDecisionVoter { public class MethodExpressionVoter implements AccessDecisionVoter {
protected final Log logger = LogFactory.getLog(getClass()); protected final Log logger = LogFactory.getLog(getClass());
// TODO: Share this between classes
private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
public boolean supports(ConfigAttribute attribute) { public boolean supports(ConfigAttribute attribute) {
return attribute instanceof AbstractExpressionBasedMethodConfigAttribute; return attribute instanceof AbstractExpressionBasedMethodConfigAttribute;
} }
@ -44,24 +37,21 @@ public class MethodExpressionVoter implements AccessDecisionVoter {
} }
public int vote(Authentication authentication, Object object, List<ConfigAttribute> attributes) { public int vote(Authentication authentication, Object object, List<ConfigAttribute> attributes) {
PreInvocationExpressionConfigAttribute mace = findMethodAccessControlExpression(attributes); PreInvocationExpressionAttribute mace = findMethodAccessControlExpression(attributes);
if (mace == null) { if (mace == null) {
// No expression based metadata, so abstain // No expression based metadata, so abstain
return ACCESS_ABSTAIN; return ACCESS_ABSTAIN;
} }
StandardEvaluationContext ctx = new StandardEvaluationContext(); MethodInvocation mi = (MethodInvocation)object;
Object filterTarget = EvaluationContext ctx = new SecurityEvaluationContext(authentication, mi);
populateContextVariablesAndFindFilterTarget(ctx, (MethodInvocation)object, mace.getFilterTarget());
ctx.setRootObject(new SecurityExpressionRoot(authentication));
Expression preFilter = mace.getFilterExpression(); Expression preFilter = mace.getFilterExpression();
Expression preAuthorize = mace.getAuthorizeExpression(); Expression preAuthorize = mace.getAuthorizeExpression();
if (preFilter != null) { if (preFilter != null) {
// TODO: Allow null target if only single parameter, or single collection/array? Object filterTarget = findFilterTarget(mace.getFilterTarget(), ctx, mi);
ExpressionUtils.doFilter(filterTarget, preFilter, ctx); ExpressionUtils.doFilter(filterTarget, preFilter, ctx);
} }
@ -72,41 +62,40 @@ public class MethodExpressionVoter implements AccessDecisionVoter {
return ExpressionUtils.evaluateAsBoolean(preAuthorize, ctx) ? ACCESS_GRANTED : ACCESS_DENIED; return ExpressionUtils.evaluateAsBoolean(preAuthorize, ctx) ? ACCESS_GRANTED : ACCESS_DENIED;
} }
private Object populateContextVariablesAndFindFilterTarget(EvaluationContext ctx, MethodInvocation mi, private Object findFilterTarget(String filterTargetName, EvaluationContext ctx, MethodInvocation mi) {
String filterTargetName) {
Object[] args = mi.getArguments();
Object targetObject = mi.getThis();
Method method = ClassUtils.getMostSpecificMethod(mi.getMethod(), targetObject.getClass());
Object filterTarget = null; Object filterTarget = null;
String[] paramNames = parameterNameDiscoverer.getParameterNames(method);
for(int i=0; i < args.length; i++) {
ctx.setVariable(paramNames[i], args[i]);
if (filterTargetName != null && paramNames[i].equals(filterTargetName)) {
filterTarget = args[i];
}
}
if (filterTargetName != null) { if (filterTargetName.length() > 0) {
filterTarget = ctx.lookupVariable(filterTargetName);
if (filterTarget == null) { if (filterTarget == null) {
throw new IllegalArgumentException("No filter target argument with name " + filterTargetName + throw new IllegalArgumentException("Filter target was null, or no argument with name "
" found in method: " + method.getName()); + filterTargetName + " found in method");
}
} else if (mi.getArguments().length == 1) {
Object arg = mi.getArguments()[0];
if (arg.getClass().isArray() ||
arg instanceof Collection) {
filterTarget = arg;
} }
if (filterTarget.getClass().isArray()) { if (filterTarget == null) {
throw new IllegalArgumentException("Pre-filtering on array types is not supported. Changing '" + throw new IllegalArgumentException("A PreFilter expression was set but the method argument type" +
filterTargetName +"' to a collection will solve this problem"); arg.getClass() + " is not filterable");
} }
} }
if (filterTarget.getClass().isArray()) {
throw new IllegalArgumentException("Pre-filtering on array types is not supported. " +
"Using a Collection will solve this problem");
}
return filterTarget; return filterTarget;
} }
private PreInvocationExpressionConfigAttribute findMethodAccessControlExpression(List<ConfigAttribute> config) { private PreInvocationExpressionAttribute findMethodAccessControlExpression(List<ConfigAttribute> config) {
// Find the MethodAccessControlExpression attribute // Find the MethodAccessControlExpression attribute
for (ConfigAttribute attribute : config) { for (ConfigAttribute attribute : config) {
if (attribute instanceof PreInvocationExpressionConfigAttribute) { if (attribute instanceof PreInvocationExpressionAttribute) {
return (PreInvocationExpressionConfigAttribute)attribute; return (PreInvocationExpressionAttribute)attribute;
} }
} }

4
core/src/main/java/org/springframework/security/expression/support/PostInvocationExpressionConfigAttribute.java → core/src/main/java/org/springframework/security/expression/support/PostInvocationExpressionAttribute.java

@ -2,9 +2,9 @@ package org.springframework.security.expression.support;
import org.springframework.expression.ParseException; import org.springframework.expression.ParseException;
class PostInvocationExpressionConfigAttribute extends AbstractExpressionBasedMethodConfigAttribute { class PostInvocationExpressionAttribute extends AbstractExpressionBasedMethodConfigAttribute {
PostInvocationExpressionConfigAttribute(String filterExpression, String authorizeExpression) PostInvocationExpressionAttribute(String filterExpression, String authorizeExpression)
throws ParseException { throws ParseException {
super(filterExpression, authorizeExpression); super(filterExpression, authorizeExpression);
} }

4
core/src/main/java/org/springframework/security/expression/support/PreInvocationExpressionConfigAttribute.java → core/src/main/java/org/springframework/security/expression/support/PreInvocationExpressionAttribute.java

@ -2,10 +2,10 @@ package org.springframework.security.expression.support;
import org.springframework.expression.ParseException; import org.springframework.expression.ParseException;
class PreInvocationExpressionConfigAttribute extends AbstractExpressionBasedMethodConfigAttribute { class PreInvocationExpressionAttribute extends AbstractExpressionBasedMethodConfigAttribute {
private final String filterTarget; private final String filterTarget;
PreInvocationExpressionConfigAttribute(String filterExpression, String filterTarget, String authorizeExpression) PreInvocationExpressionAttribute(String filterExpression, String filterTarget, String authorizeExpression)
throws ParseException { throws ParseException {
super(filterExpression, authorizeExpression); super(filterExpression, authorizeExpression);

27
core/src/main/java/org/springframework/security/expression/support/WebExpressionConfigAttribute.java

@ -0,0 +1,27 @@
package org.springframework.security.expression.support;
import org.springframework.expression.Expression;
import org.springframework.expression.ParseException;
import org.springframework.expression.spel.SpelExpressionParser;
import org.springframework.security.ConfigAttribute;
public class WebExpressionConfigAttribute implements ConfigAttribute {
private final Expression authorizeExpression;
public WebExpressionConfigAttribute(String authorizeExpression) throws ParseException {
this.authorizeExpression = new SpelExpressionParser().parseExpression(authorizeExpression);
}
public WebExpressionConfigAttribute(Expression authorizeExpression) {
this.authorizeExpression = authorizeExpression;
}
Expression getAuthorizeExpression() {
return authorizeExpression;
}
public String getAttribute() {
return null;
}
}

26
core/src/main/java/org/springframework/security/expression/support/WebExpressionVoter.java

@ -0,0 +1,26 @@
package org.springframework.security.expression.support;
import java.util.List;
import org.springframework.security.Authentication;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.intercept.web.FilterInvocation;
import org.springframework.security.vote.AccessDecisionVoter;
public class WebExpressionVoter implements AccessDecisionVoter {
public boolean supports(ConfigAttribute attribute) {
return false;
}
public boolean supports(Class clazz) {
return clazz.isAssignableFrom(FilterInvocation.class);
}
public int vote(Authentication authentication, Object object,
List<ConfigAttribute> attributes) {
// TODO Auto-generated method stub
return 0;
}
}

6
core/src/main/java/org/springframework/security/util/SimpleMethodInvocation.java

@ -36,10 +36,10 @@ public class SimpleMethodInvocation implements MethodInvocation {
//~ Constructors =================================================================================================== //~ Constructors ===================================================================================================
public SimpleMethodInvocation(Object targetObject, Method method, Object[] arguments) { public SimpleMethodInvocation(Object targetObject, Method method, Object... arguments) {
this.targetObject = targetObject; this.targetObject = targetObject;
this.method = method; this.method = method;
this.arguments = arguments; this.arguments = arguments == null ? new Object[0] : arguments;
} }
public SimpleMethodInvocation() {} public SimpleMethodInvocation() {}

14
core/src/test/java/org/springframework/security/context/rmi/ContextPropagatingRemoteInvocationTests.java

@ -38,28 +38,18 @@ import java.lang.reflect.Method;
* @version $Id$ * @version $Id$
*/ */
public class ContextPropagatingRemoteInvocationTests extends TestCase { public class ContextPropagatingRemoteInvocationTests extends TestCase {
//~ Constructors ===================================================================================================
public ContextPropagatingRemoteInvocationTests() {
}
public ContextPropagatingRemoteInvocationTests(String arg0) {
super(arg0);
}
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
super.tearDown(); super.tearDown();
SecurityContextHolder.clearContext(); SecurityContextHolder.clearContext();
} }
private ContextPropagatingRemoteInvocation getRemoteInvocation() private ContextPropagatingRemoteInvocation getRemoteInvocation() throws Exception {
throws Exception {
Class clazz = TargetObject.class; Class clazz = TargetObject.class;
Method method = clazz.getMethod("makeLowerCase", new Class[] {String.class}); Method method = clazz.getMethod("makeLowerCase", new Class[] {String.class});
MethodInvocation mi = new SimpleMethodInvocation(new TargetObject(), method, new Object[] {"SOME_STRING"}); MethodInvocation mi = new SimpleMethodInvocation(new TargetObject(), method, "SOME_STRING");
ContextPropagatingRemoteInvocationFactory factory = new ContextPropagatingRemoteInvocationFactory(); ContextPropagatingRemoteInvocationFactory factory = new ContextPropagatingRemoteInvocationFactory();

30
core/src/test/java/org/springframework/security/expression/SecurityExpressionTests.java

@ -0,0 +1,30 @@
package org.springframework.security.expression;
import org.junit.Test;
import org.springframework.expression.spel.standard.StandardEvaluationContext;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
/**
*
* @author Luke Taylor
* @version $Id$
*/
public class SecurityExpressionTests {
@Test
public void someTestMethod() throws Exception {
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken("joe", "password");
SecurityExpressionRoot root = new SecurityExpressionRoot(authToken);
StandardEvaluationContext ctx = new StandardEvaluationContext();
}
@Test
public void someTestMethod2() throws Exception {
}
}

28
core/src/test/java/org/springframework/security/expression/support/ExpressionAnnotationMethodDefinitionSourceTests.java

@ -39,8 +39,8 @@ public class ExpressionAnnotationMethodDefinitionSourceTests {
List<ConfigAttribute> attrs = mds.getAttributes(voidImpl1); List<ConfigAttribute> attrs = mds.getAttributes(voidImpl1);
assertEquals(1, attrs.size()); assertEquals(1, attrs.size());
assertTrue(attrs.get(0) instanceof PreInvocationExpressionConfigAttribute); assertTrue(attrs.get(0) instanceof PreInvocationExpressionAttribute);
PreInvocationExpressionConfigAttribute pre = (PreInvocationExpressionConfigAttribute) attrs.get(0); PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute) attrs.get(0);
assertNotNull(pre.getAuthorizeExpression()); assertNotNull(pre.getAuthorizeExpression());
assertEquals("someExpression", pre.getAuthorizeExpression().getExpressionString()); assertEquals("someExpression", pre.getAuthorizeExpression().getExpressionString());
assertNull(pre.getFilterExpression()); assertNull(pre.getFilterExpression());
@ -51,8 +51,8 @@ public class ExpressionAnnotationMethodDefinitionSourceTests {
List<ConfigAttribute> attrs = mds.getAttributes(voidImpl2); List<ConfigAttribute> attrs = mds.getAttributes(voidImpl2);
assertEquals(1, attrs.size()); assertEquals(1, attrs.size());
assertTrue(attrs.get(0) instanceof PreInvocationExpressionConfigAttribute); assertTrue(attrs.get(0) instanceof PreInvocationExpressionAttribute);
PreInvocationExpressionConfigAttribute pre = (PreInvocationExpressionConfigAttribute)attrs.get(0); PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute)attrs.get(0);
assertEquals("someExpression", pre.getAuthorizeExpression().getExpressionString()); assertEquals("someExpression", pre.getAuthorizeExpression().getExpressionString());
assertNotNull(pre.getFilterExpression()); assertNotNull(pre.getFilterExpression());
assertEquals("somePreFilterExpression", pre.getFilterExpression().getExpressionString()); assertEquals("somePreFilterExpression", pre.getFilterExpression().getExpressionString());
@ -63,8 +63,8 @@ public class ExpressionAnnotationMethodDefinitionSourceTests {
List<ConfigAttribute> attrs = mds.getAttributes(voidImpl3); List<ConfigAttribute> attrs = mds.getAttributes(voidImpl3);
assertEquals(1, attrs.size()); assertEquals(1, attrs.size());
assertTrue(attrs.get(0) instanceof PreInvocationExpressionConfigAttribute); assertTrue(attrs.get(0) instanceof PreInvocationExpressionAttribute);
PreInvocationExpressionConfigAttribute pre = (PreInvocationExpressionConfigAttribute)attrs.get(0); PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute)attrs.get(0);
assertEquals("permitAll", pre.getAuthorizeExpression().getExpressionString()); assertEquals("permitAll", pre.getAuthorizeExpression().getExpressionString());
assertNotNull(pre.getFilterExpression()); assertNotNull(pre.getFilterExpression());
assertEquals("somePreFilterExpression", pre.getFilterExpression().getExpressionString()); assertEquals("somePreFilterExpression", pre.getFilterExpression().getExpressionString());
@ -75,10 +75,10 @@ public class ExpressionAnnotationMethodDefinitionSourceTests {
List<ConfigAttribute> attrs = mds.getAttributes(listImpl1); List<ConfigAttribute> attrs = mds.getAttributes(listImpl1);
assertEquals(2, attrs.size()); assertEquals(2, attrs.size());
assertTrue(attrs.get(0) instanceof PreInvocationExpressionConfigAttribute); assertTrue(attrs.get(0) instanceof PreInvocationExpressionAttribute);
assertTrue(attrs.get(1) instanceof PostInvocationExpressionConfigAttribute); assertTrue(attrs.get(1) instanceof PostInvocationExpressionAttribute);
PreInvocationExpressionConfigAttribute pre = (PreInvocationExpressionConfigAttribute)attrs.get(0); PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute)attrs.get(0);
PostInvocationExpressionConfigAttribute post = (PostInvocationExpressionConfigAttribute)attrs.get(1); PostInvocationExpressionAttribute post = (PostInvocationExpressionAttribute)attrs.get(1);
assertEquals("permitAll", pre.getAuthorizeExpression().getExpressionString()); assertEquals("permitAll", pre.getAuthorizeExpression().getExpressionString());
assertNotNull(post.getFilterExpression()); assertNotNull(post.getFilterExpression());
assertEquals("somePostFilterExpression", post.getFilterExpression().getExpressionString()); assertEquals("somePostFilterExpression", post.getFilterExpression().getExpressionString());
@ -89,8 +89,8 @@ public class ExpressionAnnotationMethodDefinitionSourceTests {
List<ConfigAttribute> attrs = mds.getAttributes(notherListImpl1); List<ConfigAttribute> attrs = mds.getAttributes(notherListImpl1);
assertEquals(1, attrs.size()); assertEquals(1, attrs.size());
assertTrue(attrs.get(0) instanceof PreInvocationExpressionConfigAttribute); assertTrue(attrs.get(0) instanceof PreInvocationExpressionAttribute);
PreInvocationExpressionConfigAttribute pre = (PreInvocationExpressionConfigAttribute)attrs.get(0); PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute)attrs.get(0);
assertNotNull(pre.getFilterExpression()); assertNotNull(pre.getFilterExpression());
assertNotNull(pre.getAuthorizeExpression()); assertNotNull(pre.getAuthorizeExpression());
assertEquals("interfaceMethodAuthzExpression", pre.getAuthorizeExpression().getExpressionString()); assertEquals("interfaceMethodAuthzExpression", pre.getAuthorizeExpression().getExpressionString());
@ -102,8 +102,8 @@ public class ExpressionAnnotationMethodDefinitionSourceTests {
List<ConfigAttribute> attrs = mds.getAttributes(notherListImpl2); List<ConfigAttribute> attrs = mds.getAttributes(notherListImpl2);
assertEquals(1, attrs.size()); assertEquals(1, attrs.size());
assertTrue(attrs.get(0) instanceof PreInvocationExpressionConfigAttribute); assertTrue(attrs.get(0) instanceof PreInvocationExpressionAttribute);
PreInvocationExpressionConfigAttribute pre = (PreInvocationExpressionConfigAttribute)attrs.get(0); PreInvocationExpressionAttribute pre = (PreInvocationExpressionAttribute)attrs.get(0);
assertNotNull(pre.getFilterExpression()); assertNotNull(pre.getFilterExpression());
assertNotNull(pre.getAuthorizeExpression()); assertNotNull(pre.getAuthorizeExpression());
assertEquals("interfaceMethodAuthzExpression", pre.getAuthorizeExpression().getExpressionString()); assertEquals("interfaceMethodAuthzExpression", pre.getAuthorizeExpression().getExpressionString());

100
core/src/test/java/org/springframework/security/expression/support/MethodExpressionVoterTests.java

@ -5,6 +5,7 @@ import static org.junit.Assert.assertEquals;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
@ -18,7 +19,6 @@ import org.springframework.security.vote.AccessDecisionVoter;
public class MethodExpressionVoterTests { public class MethodExpressionVoterTests {
private TestingAuthenticationToken joe = new TestingAuthenticationToken("joe", "joespass", "blah"); private TestingAuthenticationToken joe = new TestingAuthenticationToken("joe", "joespass", "blah");
private MethodInvocation miStringArgs;
private MethodInvocation miListArg; private MethodInvocation miListArg;
private MethodInvocation miArrayArg; private MethodInvocation miArrayArg;
private List listArg; private List listArg;
@ -29,7 +29,6 @@ public class MethodExpressionVoterTests {
public void setUp() throws Exception { public void setUp() throws Exception {
Method m = ExpressionProtectedBusinessServiceImpl.class.getMethod("methodReturningAList", Method m = ExpressionProtectedBusinessServiceImpl.class.getMethod("methodReturningAList",
String.class, String.class); String.class, String.class);
miStringArgs = new SimpleMethodInvocation(new Object(), m, new String[] {"joe", "arg2Value"});
m = ExpressionProtectedBusinessServiceImpl.class.getMethod("methodReturningAList", List.class); m = ExpressionProtectedBusinessServiceImpl.class.getMethod("methodReturningAList", List.class);
listArg = new ArrayList(Arrays.asList("joe", "bob", "sam")); listArg = new ArrayList(Arrays.asList("joe", "bob", "sam"));
miListArg = new SimpleMethodInvocation(new Object(), m, new Object[] {listArg}); miListArg = new SimpleMethodInvocation(new Object(), m, new Object[] {listArg});
@ -40,53 +39,116 @@ public class MethodExpressionVoterTests {
@Test @Test
public void hasRoleExpressionAllowsUserWithRole() throws Exception { public void hasRoleExpressionAllowsUserWithRole() throws Exception {
assertEquals(AccessDecisionVoter.ACCESS_GRANTED, am.vote(joe, miStringArgs, createAttributes(new PreInvocationExpressionConfigAttribute(null, null, "hasRole('blah')")))); MethodInvocation mi = new SimpleMethodInvocation(new TargetImpl(), methodTakingAnArray());
assertEquals(AccessDecisionVoter.ACCESS_GRANTED, am.vote(joe, mi, createAttributes(new PreInvocationExpressionAttribute(null, null, "hasRole('blah')"))));
} }
@Test @Test
public void hasRoleExpressionDeniesUserWithoutRole() throws Exception { public void hasRoleExpressionDeniesUserWithoutRole() throws Exception {
List<ConfigAttribute> cad = new ArrayList<ConfigAttribute>(1); List<ConfigAttribute> cad = new ArrayList<ConfigAttribute>(1);
cad.add(new PreInvocationExpressionConfigAttribute(null, null, "hasRole('joedoesnt')")); cad.add(new PreInvocationExpressionAttribute(null, null, "hasRole('joedoesnt')"));
assertEquals(AccessDecisionVoter.ACCESS_DENIED, am.vote(joe, miStringArgs, cad)); MethodInvocation mi = new SimpleMethodInvocation(new TargetImpl(), methodTakingAnArray());
assertEquals(AccessDecisionVoter.ACCESS_DENIED, am.vote(joe, mi, cad));
} }
@Test @Test
public void matchingArgAgainstAuthenticationNameIsSuccessful() throws Exception { public void matchingArgAgainstAuthenticationNameIsSuccessful() throws Exception {
MethodInvocation mi = new SimpleMethodInvocation(new TargetImpl(), methodTakingAString(), "joe");
assertEquals(AccessDecisionVoter.ACCESS_GRANTED, assertEquals(AccessDecisionVoter.ACCESS_GRANTED,
am.vote(joe, miStringArgs, createAttributes(new PreInvocationExpressionConfigAttribute(null, null, "(#userName == principal) and (principal == 'joe')")))); am.vote(joe, mi, createAttributes(new PreInvocationExpressionAttribute(null, null, "(#argument == principal) and (principal == 'joe')"))));
} }
@Test @Test
public void accessIsGrantedIfNoPreAuthorizeAttributeIsUsed() throws Exception { public void accessIsGrantedIfNoPreAuthorizeAttributeIsUsed() throws Exception {
Collection arg = createCollectionArg("joe", "bob", "sam");
MethodInvocation mi = new SimpleMethodInvocation(new TargetImpl(), methodTakingACollection(), arg);
assertEquals(AccessDecisionVoter.ACCESS_GRANTED, assertEquals(AccessDecisionVoter.ACCESS_GRANTED,
am.vote(joe, miListArg, createAttributes(new PreInvocationExpressionConfigAttribute("(filterObject == 'jim')", "someList", null)))); am.vote(joe, mi, createAttributes(new PreInvocationExpressionAttribute("(filterObject == 'jim')", "collection", null))));
// All objects should have been removed, because the expression is always false // All objects should have been removed, because the expression is always false
assertEquals(0, listArg.size()); assertEquals(0, arg.size());
}
@Test
public void collectionPreFilteringIsSuccessful() throws Exception {
List arg = createCollectionArg("joe", "bob", "sam");
MethodInvocation mi = new SimpleMethodInvocation(new TargetImpl(), methodTakingACollection(), arg);
am.vote(joe, mi, createAttributes(new PreInvocationExpressionAttribute("(filterObject == 'joe' or filterObject == 'sam')", "collection", "permitAll")));
assertEquals("joe and sam should still be in the list", 2, arg.size());
assertEquals("joe", arg.get(0));
assertEquals("sam", arg.get(1));
} }
@Test(expected=IllegalArgumentException.class) @Test(expected=IllegalArgumentException.class)
public void arraysCannotBePrefiltered() throws Exception { public void arraysCannotBePrefiltered() throws Exception {
am.vote(joe, miArrayArg, MethodInvocation mi = new SimpleMethodInvocation(new TargetImpl(), methodTakingAnArray(), createArrayArg("sam","joe"));
createAttributes(new PreInvocationExpressionConfigAttribute("(filterObject == 'jim')", "someArray", null))); am.vote(joe, mi, createAttributes(new PreInvocationExpressionAttribute("(filterObject == 'jim')", "someArray", null)));
} }
@Test @Test(expected=IllegalArgumentException.class)
public void listPreFilteringIsSuccessful() throws Exception { public void incorrectFilterTargetNameIsRejected() throws Exception {
am.vote(joe, miListArg, MethodInvocation mi = new SimpleMethodInvocation(new TargetImpl(), methodTakingACollection(), createCollectionArg("joe", "bob"));
createAttributes(new PreInvocationExpressionConfigAttribute("(filterObject == 'joe' or filterObject == 'sam')", "someList", null))); am.vote(joe, mi, createAttributes(new PreInvocationExpressionAttribute("(filterObject == 'joe')", "collcetion", null)));
assertEquals("joe and sam should still be in the list", 2, listArg.size()); }
assertEquals("joe", listArg.get(0));
assertEquals("sam", listArg.get(1)); @Test(expected=IllegalArgumentException.class)
public void nullNamedFilterTargetIsRejected() throws Exception {
MethodInvocation mi = new SimpleMethodInvocation(new TargetImpl(), methodTakingACollection(), new Object[] {null});
am.vote(joe, mi, createAttributes(new PreInvocationExpressionAttribute("(filterObject == 'joe')", "collection", null)));
} }
@Test @Test
public void ruleDefinedInAClassMethodIsApplied() throws Exception { public void ruleDefinedInAClassMethodIsApplied() throws Exception {
assertEquals(AccessDecisionVoter.ACCESS_GRANTED, am.vote(joe, miStringArgs, MethodInvocation mi = new SimpleMethodInvocation(new TargetImpl(), methodTakingAString(), "joe");
createAttributes(new PreInvocationExpressionConfigAttribute(null, null, "new org.springframework.security.expression.support.SecurityRules().isJoe(#userName)")))); assertEquals(AccessDecisionVoter.ACCESS_GRANTED, am.vote(joe, mi,
createAttributes(new PreInvocationExpressionAttribute(null, null, "new org.springframework.security.expression.support.SecurityRules().isJoe(#argument)"))));
} }
private List<ConfigAttribute> createAttributes(ConfigAttribute... attributes) { private List<ConfigAttribute> createAttributes(ConfigAttribute... attributes) {
return Arrays.asList(attributes); return Arrays.asList(attributes);
} }
private List createCollectionArg(Object... elts) {
ArrayList result = new ArrayList(elts.length);
result.addAll(Arrays.asList(elts));
return result;
}
private Object createArrayArg(Object... elts) {
ArrayList result = new ArrayList(elts.length);
result.addAll(Arrays.asList(elts));
return result.toArray(new Object[0]);
}
private Method methodTakingAnArray() throws Exception {
return Target.class.getMethod("methodTakingAnArray", Object[].class);
}
private Method methodTakingAString() throws Exception {
return Target.class.getMethod("methodTakingAString", String.class);
}
private Method methodTakingACollection() throws Exception {
return Target.class.getMethod("methodTakingACollection", Collection.class);
}
//~ Inner Classes ==================================================================================================
private interface Target {
void methodTakingAnArray(Object[] args);
void methodTakingAString(String argument);
Collection methodTakingACollection(Collection collection);
}
private static class TargetImpl implements Target {
public void methodTakingAnArray(Object[] args) {}
public void methodTakingAString(String argument) {};
public Collection methodTakingACollection(Collection collection) {return collection;}
}
} }

3
core/src/test/java/org/springframework/security/intercept/method/aspectj/AspectJSecurityInterceptorTests.java

@ -32,6 +32,7 @@ import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.intercept.method.MapBasedMethodDefinitionSource; import org.springframework.security.intercept.method.MapBasedMethodDefinitionSource;
import org.springframework.security.intercept.method.MethodDefinitionSourceEditor; import org.springframework.security.intercept.method.MethodDefinitionSourceEditor;
import org.springframework.security.providers.TestingAuthenticationToken; import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.util.AuthorityUtils;
/** /**
@ -116,7 +117,7 @@ public class AspectJSecurityInterceptorTests extends TestCase {
SecurityContextHolder.getContext() SecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken("rod", "koala", .setAuthentication(new TestingAuthenticationToken("rod", "koala",
new GrantedAuthority[] {})); AuthorityUtils.NO_AUTHORITIES ));
try { try {
si.invoke(joinPoint, aspectJCallback); si.invoke(joinPoint, aspectJCallback);

3
core/src/test/java/org/springframework/security/providers/anonymous/AnonymousAuthenticationTokenTests.java

@ -20,6 +20,7 @@ import junit.framework.TestCase;
import org.springframework.security.GrantedAuthority; import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl; import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.util.AuthorityUtils;
/** /**
@ -63,7 +64,7 @@ public class AnonymousAuthenticationTokenTests extends TestCase {
} }
try { try {
new AnonymousAuthenticationToken("key", "Test", new GrantedAuthority[] {}); new AnonymousAuthenticationToken("key", "Test", AuthorityUtils.NO_AUTHORITIES );
fail("Should have thrown IllegalArgumentException"); fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException expected) { } catch (IllegalArgumentException expected) {
assertTrue(true); assertTrue(true);

3
core/src/test/java/org/springframework/security/providers/jaas/JaasAuthenticationProviderTests.java

@ -38,6 +38,7 @@ import org.springframework.security.context.SecurityContextImpl;
import org.springframework.security.providers.TestingAuthenticationToken; import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.ui.session.HttpSessionDestroyedEvent; import org.springframework.security.ui.session.HttpSessionDestroyedEvent;
import org.springframework.security.util.AuthorityUtils;
/** /**
@ -225,7 +226,7 @@ public class JaasAuthenticationProviderTests extends TestCase {
} }
public void testUnsupportedAuthenticationObjectReturnsNull() { public void testUnsupportedAuthenticationObjectReturnsNull() {
assertNull(jaasProvider.authenticate(new TestingAuthenticationToken("foo", "bar", new GrantedAuthority[] {}))); assertNull(jaasProvider.authenticate(new TestingAuthenticationToken("foo", "bar", AuthorityUtils.NO_AUTHORITIES )));
} }
//~ Inner Classes ================================================================================================== //~ Inner Classes ==================================================================================================

128
core/src/test/java/org/springframework/security/providers/preauth/PreAuthenticatedAuthenticationProviderTests.java

@ -1,39 +1,43 @@
package org.springframework.security.providers.preauth; package org.springframework.security.providers.preauth;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.security.Authentication;
import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
import org.springframework.security.userdetails.AuthenticationUserDetailsService; import org.springframework.security.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.userdetails.User; import org.springframework.security.userdetails.User;
import org.springframework.security.userdetails.UserDetails; import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UsernameNotFoundException; import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.security.Authentication; import org.springframework.security.util.AuthorityUtils;
import org.springframework.security.GrantedAuthority;
import org.junit.Test;
import static org.junit.Assert.*;
/** /**
* *
* @author TSARDD * @author TSARDD
* @since 18-okt-2007 * @since 18-okt-2007
*/ */
public class PreAuthenticatedAuthenticationProviderTests { public class PreAuthenticatedAuthenticationProviderTests {
private static final String SUPPORTED_USERNAME = "dummyUser"; private static final String SUPPORTED_USERNAME = "dummyUser";
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public final void afterPropertiesSet() { public final void afterPropertiesSet() {
PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider(); PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
provider.afterPropertiesSet(); provider.afterPropertiesSet();
} }
@Test @Test
public final void authenticateInvalidToken() throws Exception { public final void authenticateInvalidToken() throws Exception {
UserDetails ud = new User("dummyUser", "dummyPwd", true, true, true, true, new GrantedAuthority[] {}); UserDetails ud = new User("dummyUser", "dummyPwd", true, true, true, true, AuthorityUtils.NO_AUTHORITIES );
PreAuthenticatedAuthenticationProvider provider = getProvider(ud); PreAuthenticatedAuthenticationProvider provider = getProvider(ud);
Authentication request = new UsernamePasswordAuthenticationToken("dummyUser", "dummyPwd"); Authentication request = new UsernamePasswordAuthenticationToken("dummyUser", "dummyPwd");
Authentication result = provider.authenticate(request); Authentication result = provider.authenticate(request);
assertNull(result); assertNull(result);
} }
@Test @Test
public final void nullPrincipalReturnsNullAuthentication() throws Exception { public final void nullPrincipalReturnsNullAuthentication() throws Exception {
@ -45,70 +49,70 @@ public class PreAuthenticatedAuthenticationProviderTests {
@Test @Test
public final void authenticateKnownUser() throws Exception { public final void authenticateKnownUser() throws Exception {
UserDetails ud = new User("dummyUser", "dummyPwd", true, true, true, true, new GrantedAuthority[] {}); UserDetails ud = new User("dummyUser", "dummyPwd", true, true, true, true, AuthorityUtils.NO_AUTHORITIES );
PreAuthenticatedAuthenticationProvider provider = getProvider(ud); PreAuthenticatedAuthenticationProvider provider = getProvider(ud);
Authentication request = new PreAuthenticatedAuthenticationToken("dummyUser", "dummyPwd"); Authentication request = new PreAuthenticatedAuthenticationToken("dummyUser", "dummyPwd");
Authentication result = provider.authenticate(request); Authentication result = provider.authenticate(request);
assertNotNull(result); assertNotNull(result);
assertEquals(result.getPrincipal(), ud); assertEquals(result.getPrincipal(), ud);
// @TODO: Add more asserts? // @TODO: Add more asserts?
} }
@Test @Test
public final void authenticateIgnoreCredentials() throws Exception { public final void authenticateIgnoreCredentials() throws Exception {
UserDetails ud = new User("dummyUser1", "dummyPwd1", true, true, true, true, new GrantedAuthority[] {}); UserDetails ud = new User("dummyUser1", "dummyPwd1", true, true, true, true, AuthorityUtils.NO_AUTHORITIES );
PreAuthenticatedAuthenticationProvider provider = getProvider(ud); PreAuthenticatedAuthenticationProvider provider = getProvider(ud);
Authentication request = new PreAuthenticatedAuthenticationToken("dummyUser1", "dummyPwd2"); Authentication request = new PreAuthenticatedAuthenticationToken("dummyUser1", "dummyPwd2");
Authentication result = provider.authenticate(request); Authentication result = provider.authenticate(request);
assertNotNull(result); assertNotNull(result);
assertEquals(result.getPrincipal(), ud); assertEquals(result.getPrincipal(), ud);
// @TODO: Add more asserts? // @TODO: Add more asserts?
} }
@Test(expected=UsernameNotFoundException.class) @Test(expected=UsernameNotFoundException.class)
public final void authenticateUnknownUserThrowsException() throws Exception { public final void authenticateUnknownUserThrowsException() throws Exception {
UserDetails ud = new User("dummyUser1", "dummyPwd", true, true, true, true, new GrantedAuthority[] {}); UserDetails ud = new User("dummyUser1", "dummyPwd", true, true, true, true, AuthorityUtils.NO_AUTHORITIES );
PreAuthenticatedAuthenticationProvider provider = getProvider(ud); PreAuthenticatedAuthenticationProvider provider = getProvider(ud);
Authentication request = new PreAuthenticatedAuthenticationToken("dummyUser2", "dummyPwd"); Authentication request = new PreAuthenticatedAuthenticationToken("dummyUser2", "dummyPwd");
provider.authenticate(request); provider.authenticate(request);
} }
@Test @Test
public final void supportsArbitraryObject() throws Exception { public final void supportsArbitraryObject() throws Exception {
PreAuthenticatedAuthenticationProvider provider = getProvider(null); PreAuthenticatedAuthenticationProvider provider = getProvider(null);
assertFalse(provider.supports(Authentication.class)); assertFalse(provider.supports(Authentication.class));
} }
@Test @Test
public final void supportsPreAuthenticatedAuthenticationToken() throws Exception { public final void supportsPreAuthenticatedAuthenticationToken() throws Exception {
PreAuthenticatedAuthenticationProvider provider = getProvider(null); PreAuthenticatedAuthenticationProvider provider = getProvider(null);
assertTrue(provider.supports(PreAuthenticatedAuthenticationToken.class)); assertTrue(provider.supports(PreAuthenticatedAuthenticationToken.class));
} }
@Test @Test
public void getSetOrder() throws Exception { public void getSetOrder() throws Exception {
PreAuthenticatedAuthenticationProvider provider = getProvider(null); PreAuthenticatedAuthenticationProvider provider = getProvider(null);
provider.setOrder(333); provider.setOrder(333);
assertEquals(provider.getOrder(), 333); assertEquals(provider.getOrder(), 333);
} }
private PreAuthenticatedAuthenticationProvider getProvider(UserDetails aUserDetails) throws Exception { private PreAuthenticatedAuthenticationProvider getProvider(UserDetails aUserDetails) throws Exception {
PreAuthenticatedAuthenticationProvider result = new PreAuthenticatedAuthenticationProvider(); PreAuthenticatedAuthenticationProvider result = new PreAuthenticatedAuthenticationProvider();
result.setPreAuthenticatedUserDetailsService(getPreAuthenticatedUserDetailsService(aUserDetails)); result.setPreAuthenticatedUserDetailsService(getPreAuthenticatedUserDetailsService(aUserDetails));
result.afterPropertiesSet(); result.afterPropertiesSet();
return result; return result;
} }
private AuthenticationUserDetailsService getPreAuthenticatedUserDetailsService(final UserDetails aUserDetails) { private AuthenticationUserDetailsService getPreAuthenticatedUserDetailsService(final UserDetails aUserDetails) {
return new AuthenticationUserDetailsService() { return new AuthenticationUserDetailsService() {
public UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException { public UserDetails loadUserDetails(Authentication token) throws UsernameNotFoundException {
if (aUserDetails != null && aUserDetails.getUsername().equals(token.getName())) { if (aUserDetails != null && aUserDetails.getUsername().equals(token.getName())) {
return aUserDetails; return aUserDetails;
} }
throw new UsernameNotFoundException("notfound"); throw new UsernameNotFoundException("notfound");
} }
}; };
} }
} }

6
core/src/test/java/org/springframework/security/wrapper/SecurityContextHolderAwareRequestWrapperTests.java

@ -17,13 +17,13 @@ package org.springframework.security.wrapper;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.Authentication; import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.TestingAuthenticationToken; import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.userdetails.User; import org.springframework.security.userdetails.User;
import org.springframework.security.util.AuthorityUtils;
import org.springframework.security.util.PortResolverImpl; import org.springframework.security.util.PortResolverImpl;
import org.springframework.mock.web.MockHttpServletRequest;
/** /**
@ -78,7 +78,7 @@ public class SecurityContextHolderAwareRequestWrapperTests extends TestCase {
public void testCorrectOperationWithUserDetailsBasedPrincipal() throws Exception { public void testCorrectOperationWithUserDetailsBasedPrincipal() throws Exception {
Authentication auth = new TestingAuthenticationToken(new User("rodAsUserDetails", "koala", true, true, Authentication auth = new TestingAuthenticationToken(new User("rodAsUserDetails", "koala", true, true,
true, true, new GrantedAuthority[] {}), "koala", "ROLE_HELLO", "ROLE_FOOBAR"); true, true, AuthorityUtils.NO_AUTHORITIES ), "koala", "ROLE_HELLO", "ROLE_FOOBAR");
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletRequest request = new MockHttpServletRequest();

34
taglibs/src/test/java/org/springframework/security/taglibs/authz/AclTagTests.java

@ -15,24 +15,22 @@
package org.springframework.security.taglibs.authz; package org.springframework.security.taglibs.authz;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.security.Authentication; import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.acl.AclEntry; import org.springframework.security.acl.AclEntry;
import org.springframework.security.acl.AclManager; import org.springframework.security.acl.AclManager;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.springframework.security.acl.basic.AclObjectIdentity; import org.springframework.security.acl.basic.AclObjectIdentity;
import org.springframework.security.acl.basic.SimpleAclEntry;
import org.springframework.security.context.SecurityContextHolder; import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.providers.TestingAuthenticationToken; import org.springframework.security.providers.TestingAuthenticationToken;
import org.springframework.security.util.AuthorityUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.StaticApplicationContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
/** /**
@ -54,7 +52,7 @@ public class AclTagTests extends TestCase {
} }
public void testInclusionDeniedWhenAclManagerUnawareOfObject() throws JspException { public void testInclusionDeniedWhenAclManagerUnawareOfObject() throws JspException {
Authentication auth = new TestingAuthenticationToken("rod", "koala", new GrantedAuthority[] {}); Authentication auth = new TestingAuthenticationToken("rod", "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION).toString()); aclTag.setHasPermission(new Long(SimpleAclEntry.ADMINISTRATION).toString());
@ -63,7 +61,7 @@ public class AclTagTests extends TestCase {
} }
public void testInclusionDeniedWhenNoListOfPermissionsGiven() throws JspException { public void testInclusionDeniedWhenNoListOfPermissionsGiven() throws JspException {
Authentication auth = new TestingAuthenticationToken("rod", "koala", new GrantedAuthority[] {}); Authentication auth = new TestingAuthenticationToken("rod", "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(null); aclTag.setHasPermission(null);
@ -72,7 +70,7 @@ public class AclTagTests extends TestCase {
} }
public void testInclusionDeniedWhenPrincipalDoesNotHoldAnyPermissions() throws JspException { public void testInclusionDeniedWhenPrincipalDoesNotHoldAnyPermissions() throws JspException {
Authentication auth = new TestingAuthenticationToken("john", "crow", new GrantedAuthority[] {}); Authentication auth = new TestingAuthenticationToken("john", "crow", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ)); aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ));
@ -84,7 +82,7 @@ public class AclTagTests extends TestCase {
} }
public void testInclusionDeniedWhenPrincipalDoesNotHoldRequiredPermissions() throws JspException { public void testInclusionDeniedWhenPrincipalDoesNotHoldRequiredPermissions() throws JspException {
Authentication auth = new TestingAuthenticationToken("rod", "koala", new GrantedAuthority[] {}); Authentication auth = new TestingAuthenticationToken("rod", "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(new Integer(SimpleAclEntry.DELETE).toString()); aclTag.setHasPermission(new Integer(SimpleAclEntry.DELETE).toString());
@ -107,7 +105,7 @@ public class AclTagTests extends TestCase {
} }
public void testJspExceptionThrownIfHasPermissionNotValidFormat() throws JspException { public void testJspExceptionThrownIfHasPermissionNotValidFormat() throws JspException {
Authentication auth = new TestingAuthenticationToken("john", "crow", new GrantedAuthority[] {}); Authentication auth = new TestingAuthenticationToken("john", "crow", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission("0,5, 6"); // shouldn't be any space aclTag.setHasPermission("0,5, 6"); // shouldn't be any space
@ -121,7 +119,7 @@ public class AclTagTests extends TestCase {
} }
public void testOperationWhenPrincipalHoldsPermissionOfMultipleList() throws JspException { public void testOperationWhenPrincipalHoldsPermissionOfMultipleList() throws JspException {
Authentication auth = new TestingAuthenticationToken("rod", "koala", new GrantedAuthority[] {}); Authentication auth = new TestingAuthenticationToken("rod", "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ)); aclTag.setHasPermission(new Integer(SimpleAclEntry.ADMINISTRATION) + "," + new Integer(SimpleAclEntry.READ));
@ -130,7 +128,7 @@ public class AclTagTests extends TestCase {
} }
public void testOperationWhenPrincipalHoldsPermissionOfSingleList() throws JspException { public void testOperationWhenPrincipalHoldsPermissionOfSingleList() throws JspException {
Authentication auth = new TestingAuthenticationToken("rod", "koala", new GrantedAuthority[] {}); Authentication auth = new TestingAuthenticationToken("rod", "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
aclTag.setHasPermission(new Integer(SimpleAclEntry.READ).toString()); aclTag.setHasPermission(new Integer(SimpleAclEntry.READ).toString());
@ -177,5 +175,5 @@ public class AclTagTests extends TestCase {
} }
private static class MockAclObjectIdentity implements AclObjectIdentity { private static class MockAclObjectIdentity implements AclObjectIdentity {
} }
} }

4
taglibs/src/test/java/org/springframework/security/taglibs/authz/AuthenticationTagTests.java

@ -58,7 +58,7 @@ public class AuthenticationTagTests extends TestCase {
public void testOperationWhenPrincipalIsAString() throws JspException { public void testOperationWhenPrincipalIsAString() throws JspException {
SecurityContextHolder.getContext().setAuthentication( SecurityContextHolder.getContext().setAuthentication(
new TestingAuthenticationToken("rodAsString", "koala", new GrantedAuthority[] {})); new TestingAuthenticationToken("rodAsString", "koala", AuthorityUtils.NO_AUTHORITIES ));
authenticationTag.setProperty("principal"); authenticationTag.setProperty("principal");
assertEquals(Tag.SKIP_BODY, authenticationTag.doStartTag()); assertEquals(Tag.SKIP_BODY, authenticationTag.doStartTag());
@ -77,7 +77,7 @@ public class AuthenticationTagTests extends TestCase {
public void testOperationWhenPrincipalIsNull() throws JspException { public void testOperationWhenPrincipalIsNull() throws JspException {
SecurityContextHolder.getContext().setAuthentication( SecurityContextHolder.getContext().setAuthentication(
new TestingAuthenticationToken(null, "koala", new GrantedAuthority[] {})); new TestingAuthenticationToken(null, "koala", AuthorityUtils.NO_AUTHORITIES ));
authenticationTag.setProperty("principal"); authenticationTag.setProperty("principal");
assertEquals(Tag.SKIP_BODY, authenticationTag.doStartTag()); assertEquals(Tag.SKIP_BODY, authenticationTag.doStartTag());

4
taglibs/src/test/java/org/springframework/security/taglibs/velocity/AuthzImplTests.java

@ -33,7 +33,7 @@ public class AuthzImplTests extends TestCase {
//~ Methods ======================================================================================================== //~ Methods ========================================================================================================
public void testOperationWhenPrincipalIsAString() { public void testOperationWhenPrincipalIsAString() {
Authentication auth = new TestingAuthenticationToken("rodAsString", "koala", new GrantedAuthority[] {}); Authentication auth = new TestingAuthenticationToken("rodAsString", "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
assertEquals("rodAsString", authz.getPrincipal()); assertEquals("rodAsString", authz.getPrincipal());
@ -48,7 +48,7 @@ public class AuthzImplTests extends TestCase {
} }
public void testOperationWhenPrincipalIsNull() { public void testOperationWhenPrincipalIsNull() {
Authentication auth = new TestingAuthenticationToken(null, "koala", new GrantedAuthority[] {}); Authentication auth = new TestingAuthenticationToken(null, "koala", AuthorityUtils.NO_AUTHORITIES );
SecurityContextHolder.getContext().setAuthentication(auth); SecurityContextHolder.getContext().setAuthentication(auth);
assertNull(authz.getPrincipal()); assertNull(authz.getPrincipal());

Loading…
Cancel
Save