mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-01 09:42:13 +00:00
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.
This commit is contained in:
parent
ec44f2bdfe
commit
514bca669f
@ -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];
|
||||||
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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,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 "";
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -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++) {
|
if (filterTargetName.length() > 0) {
|
||||||
ctx.setVariable(paramNames[i], args[i]);
|
filterTarget = ctx.lookupVariable(filterTargetName);
|
||||||
if (filterTargetName != null && paramNames[i].equals(filterTargetName)) {
|
if (filterTarget == null) {
|
||||||
filterTarget = args[i];
|
throw new IllegalArgumentException("Filter target was null, or no argument with name "
|
||||||
|
+ 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 == null) {
|
||||||
|
throw new IllegalArgumentException("A PreFilter expression was set but the method argument type" +
|
||||||
|
arg.getClass() + " is not filterable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filterTargetName != null) {
|
if (filterTarget.getClass().isArray()) {
|
||||||
if (filterTarget == null) {
|
throw new IllegalArgumentException("Pre-filtering on array types is not supported. " +
|
||||||
throw new IllegalArgumentException("No filter target argument with name " + filterTargetName +
|
"Using a Collection will solve this problem");
|
||||||
" found in method: " + method.getName());
|
|
||||||
}
|
|
||||||
if (filterTarget.getClass().isArray()) {
|
|
||||||
throw new IllegalArgumentException("Pre-filtering on array types is not supported. Changing '" +
|
|
||||||
filterTargetName +"' to 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
@ -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);
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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() {}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -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());
|
||||||
|
@ -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;}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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 ==================================================================================================
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -15,25 +15,23 @@
|
|||||||
|
|
||||||
package org.springframework.security.taglibs.authz;
|
package org.springframework.security.taglibs.authz;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.springframework.security.Authentication;
|
|
||||||
import org.springframework.security.GrantedAuthority;
|
|
||||||
|
|
||||||
import org.springframework.security.acl.AclEntry;
|
|
||||||
import org.springframework.security.acl.AclManager;
|
|
||||||
import org.springframework.security.acl.basic.SimpleAclEntry;
|
|
||||||
import org.springframework.security.acl.basic.AclObjectIdentity;
|
|
||||||
import org.springframework.security.context.SecurityContextHolder;
|
|
||||||
import org.springframework.security.providers.TestingAuthenticationToken;
|
|
||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.context.support.StaticApplicationContext;
|
|
||||||
|
|
||||||
import javax.servlet.jsp.JspException;
|
import javax.servlet.jsp.JspException;
|
||||||
import javax.servlet.jsp.PageContext;
|
import javax.servlet.jsp.PageContext;
|
||||||
import javax.servlet.jsp.tagext.Tag;
|
import javax.servlet.jsp.tagext.Tag;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.support.StaticApplicationContext;
|
||||||
|
import org.springframework.security.Authentication;
|
||||||
|
import org.springframework.security.acl.AclEntry;
|
||||||
|
import org.springframework.security.acl.AclManager;
|
||||||
|
import org.springframework.security.acl.basic.AclObjectIdentity;
|
||||||
|
import org.springframework.security.acl.basic.SimpleAclEntry;
|
||||||
|
import org.springframework.security.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.providers.TestingAuthenticationToken;
|
||||||
|
import org.springframework.security.util.AuthorityUtils;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link AclTag}.
|
* Tests {@link AclTag}.
|
||||||
@ -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 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user