From 04e187d1a725c5f27a424fccb574cbfaa9aee365 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Fri, 15 Feb 2008 18:09:26 +0000 Subject: [PATCH] Tiding up code in acl package (formatting, reduction onf nesting etc). --- .../security/acls/AclFormattingUtils.java | 11 +- .../security/acls/domain/BasePermission.java | 18 +- .../security/acls/jdbc/JdbcAclService.java | 18 +- .../security/acls/jdbc/LookupStrategy.java | 2 +- .../objectidentity/ObjectIdentityImpl.java | 6 +- .../security/acls/sid/PrincipalSid.java | 3 +- .../acls/sid/SidRetrievalStrategyImpl.java | 21 +- .../afterinvocation/AbstractAclProvider.java | 6 +- ...InvocationCollectionFilteringProvider.java | 132 ++++++------ .../AclEntryAfterInvocationProvider.java | 98 ++++----- .../AfterInvocationProvider.java | 3 +- .../AfterInvocationProviderManager.java | 13 +- .../security/vote/AclEntryVoter.java | 190 +++++++++--------- .../acls/sid/SidRetrievalStrategyTests.java | 11 +- 14 files changed, 262 insertions(+), 270 deletions(-) diff --git a/core/src/main/java/org/springframework/security/acls/AclFormattingUtils.java b/core/src/main/java/org/springframework/security/acls/AclFormattingUtils.java index a853a4a30a..caff1cd087 100644 --- a/core/src/main/java/org/springframework/security/acls/AclFormattingUtils.java +++ b/core/src/main/java/org/springframework/security/acls/AclFormattingUtils.java @@ -91,7 +91,9 @@ public final class AclFormattingUtils { /** * Returns a representation of the active bits in the presented mask, with each active bit being denoted by - * the passed character.

Inactive bits will be denoted by character {@link Permission#RESERVED_OFF}.

+ * the passed character. + *

+ * Inactive bits will be denoted by character {@link Permission#RESERVED_OFF}. * * @param mask the integer bit mask to print the active bits for * @param code the character to print when an active bit is detected @@ -99,12 +101,11 @@ public final class AclFormattingUtils { * @return a 32-character representation of the bit mask */ public static String printBinary(int mask, char code) { - Assert.doesNotContain(new Character(code).toString(), new Character(Permission.RESERVED_ON).toString(), + Assert.doesNotContain(Character.toString(code), Character.toString(Permission.RESERVED_ON), Permission.RESERVED_ON + " is a reserved character code"); - Assert.doesNotContain(new Character(code).toString(), new Character(Permission.RESERVED_OFF).toString(), + Assert.doesNotContain(Character.toString(code), Character.toString(Permission.RESERVED_OFF), Permission.RESERVED_OFF + " is a reserved character code"); - return printBinary(mask, Permission.RESERVED_ON, Permission.RESERVED_OFF) - .replace(Permission.RESERVED_ON, code); + return printBinary(mask, Permission.RESERVED_ON, Permission.RESERVED_OFF).replace(Permission.RESERVED_ON, code); } } diff --git a/core/src/main/java/org/springframework/security/acls/domain/BasePermission.java b/core/src/main/java/org/springframework/security/acls/domain/BasePermission.java index d545ed91a5..f585dac306 100644 --- a/core/src/main/java/org/springframework/security/acls/domain/BasePermission.java +++ b/core/src/main/java/org/springframework/security/acls/domain/BasePermission.java @@ -22,9 +22,7 @@ import org.springframework.util.Assert; import java.lang.reflect.Field; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.Vector; /** @@ -108,16 +106,16 @@ public final class BasePermission implements Permission { public static Permission[] buildFromMask(int[] masks) { if ((masks == null) || (masks.length == 0)) { - return new Permission[] {}; + return new Permission[0]; } - List list = new Vector(); + Permission[] permissions = new Permission[masks.length]; for (int i = 0; i < masks.length; i++) { - list.add(BasePermission.buildFromMask(masks[i])); + permissions[i] = buildFromMask(masks[i]); } - return (Permission[]) list.toArray(new Permission[] {}); + return permissions; } public static Permission buildFromName(String name) { @@ -128,16 +126,16 @@ public final class BasePermission implements Permission { public static Permission[] buildFromName(String[] names) { if ((names == null) || (names.length == 0)) { - return new Permission[] {}; + return new Permission[0]; } - List list = new Vector(); + Permission[] permissions = new Permission[names.length]; for (int i = 0; i < names.length; i++) { - list.add(BasePermission.buildFromName(names[i])); + permissions[i] = buildFromName(names[i]); } - return (Permission[]) list.toArray(new Permission[] {}); + return permissions; } public boolean equals(Object arg0) { diff --git a/core/src/main/java/org/springframework/security/acls/jdbc/JdbcAclService.java b/core/src/main/java/org/springframework/security/acls/jdbc/JdbcAclService.java index 47e07fec6d..fe65229c48 100644 --- a/core/src/main/java/org/springframework/security/acls/jdbc/JdbcAclService.java +++ b/core/src/main/java/org/springframework/security/acls/jdbc/JdbcAclService.java @@ -39,9 +39,11 @@ import javax.sql.DataSource; /** - * Simple JDBC-based implementation of AclService.

Requires the "dirty" flags in {@link - * org.springframework.security.acls.domain.AclImpl} and {@link org.springframework.security.acls.domain.AccessControlEntryImpl} to be set, - * so that the implementation can detect changed parameters easily.

+ * Simple JDBC-based implementation of AclService. + *

+ * Requires the "dirty" flags in {@link org.springframework.security.acls.domain.AclImpl} and + * {@link org.springframework.security.acls.domain.AccessControlEntryImpl} to be set, so that the implementation can + * detect changed parameters easily. * * @author Ben Alex * @version $Id$ @@ -88,15 +90,14 @@ public class JdbcAclService implements AclService { return (ObjectIdentityImpl[]) objects.toArray(new ObjectIdentityImpl[] {}); } - public Acl readAclById(ObjectIdentity object, Sid[] sids) - throws NotFoundException { + public Acl readAclById(ObjectIdentity object, Sid[] sids) throws NotFoundException { Map map = readAclsById(new ObjectIdentity[] {object}, sids); if (map.size() == 0) { throw new NotFoundException("Could not find ACL"); - } else { - return (Acl) map.get(object); } + + return (Acl) map.get(object); } public Acl readAclById(ObjectIdentity object) throws NotFoundException { @@ -107,8 +108,7 @@ public class JdbcAclService implements AclService { return readAclsById(objects, null); } - public Map readAclsById(ObjectIdentity[] objects, Sid[] sids) - throws NotFoundException { + public Map readAclsById(ObjectIdentity[] objects, Sid[] sids) throws NotFoundException { return lookupStrategy.readAclsById(objects, sids); } } diff --git a/core/src/main/java/org/springframework/security/acls/jdbc/LookupStrategy.java b/core/src/main/java/org/springframework/security/acls/jdbc/LookupStrategy.java index e8791916a7..1ea5b6bcfd 100644 --- a/core/src/main/java/org/springframework/security/acls/jdbc/LookupStrategy.java +++ b/core/src/main/java/org/springframework/security/acls/jdbc/LookupStrategy.java @@ -21,7 +21,7 @@ import java.util.Map; /** - * Performs optimised lookups for {@link JdbcAclService}. + * Performs lookups for {@link org.springframework.security.acls.AclService}. * * @author Ben Alex * @version $Id$ diff --git a/core/src/main/java/org/springframework/security/acls/objectidentity/ObjectIdentityImpl.java b/core/src/main/java/org/springframework/security/acls/objectidentity/ObjectIdentityImpl.java index 80f0801c4f..c33570d257 100644 --- a/core/src/main/java/org/springframework/security/acls/objectidentity/ObjectIdentityImpl.java +++ b/core/src/main/java/org/springframework/security/acls/objectidentity/ObjectIdentityImpl.java @@ -25,11 +25,13 @@ import java.lang.reflect.Method; /** - * Simple implementation of {@link org.springframework.security.acl.basic.AclObjectIdentity AclObjectIdentity}. + * Simple implementation of {@link ObjectIdentity}. *

* Uses Strings to store the identity of the domain object instance. Also offers a constructor that uses * reflection to build the identity information. - *

+ * + * @author Ben Alex + * @version $Id$ */ public class ObjectIdentityImpl implements ObjectIdentity { //~ Instance fields ================================================================================================ diff --git a/core/src/main/java/org/springframework/security/acls/sid/PrincipalSid.java b/core/src/main/java/org/springframework/security/acls/sid/PrincipalSid.java index 6a64440c23..0d9f8d94db 100644 --- a/core/src/main/java/org/springframework/security/acls/sid/PrincipalSid.java +++ b/core/src/main/java/org/springframework/security/acls/sid/PrincipalSid.java @@ -44,10 +44,11 @@ public class PrincipalSid implements Sid { public PrincipalSid(Authentication authentication) { Assert.notNull(authentication, "Authentication required"); Assert.notNull(authentication.getPrincipal(), "Principal required"); - this.principal = authentication.getPrincipal().toString(); if (authentication.getPrincipal() instanceof UserDetails) { this.principal = ((UserDetails) authentication.getPrincipal()).getUsername(); + } else { + this.principal = authentication.getPrincipal().toString(); } } diff --git a/core/src/main/java/org/springframework/security/acls/sid/SidRetrievalStrategyImpl.java b/core/src/main/java/org/springframework/security/acls/sid/SidRetrievalStrategyImpl.java index c70f0dd63b..01d71fb0c8 100644 --- a/core/src/main/java/org/springframework/security/acls/sid/SidRetrievalStrategyImpl.java +++ b/core/src/main/java/org/springframework/security/acls/sid/SidRetrievalStrategyImpl.java @@ -18,14 +18,11 @@ package org.springframework.security.acls.sid; import org.springframework.security.Authentication; import org.springframework.security.GrantedAuthority; -import java.util.List; -import java.util.Vector; - - /** * Basic implementation of {@link SidRetrievalStrategy} that creates a {@link Sid} for the principal, as well as - * every granted authority the principal holds.

The returned array will always contain the {@link PrincipalSid} - * before any {@link GrantedAuthoritySid} elements.

+ * every granted authority the principal holds. + *

+ * The returned array will always contain the {@link PrincipalSid} before any {@link GrantedAuthoritySid} elements. * * @author Ben Alex * @version $Id$ @@ -34,15 +31,15 @@ public class SidRetrievalStrategyImpl implements SidRetrievalStrategy { //~ Methods ======================================================================================================== public Sid[] getSids(Authentication authentication) { - List list = new Vector(); - list.add(new PrincipalSid(authentication)); - GrantedAuthority[] authorities = authentication.getAuthorities(); + Sid[] sids = new Sid[authorities.length + 1]; - for (int i = 0; i < authorities.length; i++) { - list.add(new GrantedAuthoritySid(authorities[i])); + sids[0] = new PrincipalSid(authentication); + + for (int i = 1; i <= authorities.length; i++) { + sids[i] = new GrantedAuthoritySid(authorities[i - 1]); } - return (Sid[]) list.toArray(new Sid[] {}); + return sids; } } diff --git a/core/src/main/java/org/springframework/security/afterinvocation/AbstractAclProvider.java b/core/src/main/java/org/springframework/security/afterinvocation/AbstractAclProvider.java index 17f58e9335..4847535d4f 100644 --- a/core/src/main/java/org/springframework/security/afterinvocation/AbstractAclProvider.java +++ b/core/src/main/java/org/springframework/security/afterinvocation/AbstractAclProvider.java @@ -110,11 +110,7 @@ public abstract class AbstractAclProvider implements AfterInvocationProvider { } public boolean supports(ConfigAttribute attribute) { - if ((attribute.getAttribute() != null) && attribute.getAttribute().equals(this.processConfigAttribute)) { - return true; - } else { - return false; - } + return processConfigAttribute.equals(attribute.getAttribute()); } /** diff --git a/core/src/main/java/org/springframework/security/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java b/core/src/main/java/org/springframework/security/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java index a9d16be050..95c05e30cb 100644 --- a/core/src/main/java/org/springframework/security/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java +++ b/core/src/main/java/org/springframework/security/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java @@ -31,26 +31,32 @@ import java.util.Iterator; /** - *

Given a Collection of domain object instances returned from a secure object invocation, remove + *

+ * Given a Collection of domain object instances returned from a secure object invocation, remove * any Collection elements the principal does not have appropriate permission to access as defined by the - * {@link AclService}.

- *

The AclService is used to retrieve the access control list (ACL) permissions associated with - * each Collection domain object instance element for the current Authentication object.

- *

This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link + * {@link AclService}. + *

+ * The AclService is used to retrieve the access control list (ACL) permissions associated with + * each Collection domain object instance element for the current Authentication object. + *

+ * This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link * #processConfigAttribute}. The provider will then lookup the ACLs from the AclService and ensure the - * principal is - * {@link org.springframework.security.acls.Acl#isGranted(org.springframework.security.acls.Permission[], + * principal is {@link org.springframework.security.acls.Acl#isGranted(org.springframework.security.acls.Permission[], * org.springframework.security.acls.sid.Sid[], boolean) Acl.isGranted(Permission[], Sid[], boolean)} - * when presenting the {@link #requirePermission} array to that method.

- *

If the principal does not have permission, that element will not be included in the returned - * Collection.

- *

Often users will setup a BasicAclEntryAfterInvocationProvider with a {@link + * when presenting the {@link #requirePermission} array to that method. + *

+ * If the principal does not have permission, that element will not be included in the returned + * Collection. + *

+ * Often users will setup a BasicAclEntryAfterInvocationProvider with a {@link * #processConfigAttribute} of AFTER_ACL_COLLECTION_READ and a {@link #requirePermission} of - * BasePermission.READ. These are also the defaults.

- *

If the provided returnObject is null, a nullCollection + * BasePermission.READ. These are also the defaults. + *

+ * If the provided returnObject is null, a nullCollection * will be returned. If the provided returnObject is not a Collection, an {@link - * AuthorizationServiceException} will be thrown.

- *

All comparisons and prefixes are case sensitive.

+ * AuthorizationServiceException} will be thrown. + *

+ * All comparisons and prefixes are case sensitive. * * @author Ben Alex * @author Paulo Neves @@ -70,62 +76,58 @@ public class AclEntryAfterInvocationCollectionFilteringProvider extends Abstract //~ Methods ======================================================================================================== public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config, - Object returnedObject) throws AccessDeniedException { + Object returnedObject) throws AccessDeniedException { + + if (returnedObject == null) { + if (logger.isDebugEnabled()) { + logger.debug("Return object is null, skipping"); + } + + return null; + } + Iterator iter = config.getConfigAttributes().iterator(); while (iter.hasNext()) { ConfigAttribute attr = (ConfigAttribute) iter.next(); - if (this.supports(attr)) { - // Need to process the Collection for this invocation - if (returnedObject == null) { - if (logger.isDebugEnabled()) { - logger.debug("Return object is null, skipping"); - } - - return null; - } - - Filterer filterer = null; - - if (returnedObject instanceof Collection) { - Collection collection = (Collection) returnedObject; - filterer = new CollectionFilterer(collection); - } else if (returnedObject.getClass().isArray()) { - Object[] array = (Object[]) returnedObject; - filterer = new ArrayFilterer(array); - } else { - throw new AuthorizationServiceException("A Collection or an array (or null) was required as the " - + "returnedObject, but the returnedObject was: " + returnedObject); - } - - // Locate unauthorised Collection elements - Iterator collectionIter = filterer.iterator(); - - while (collectionIter.hasNext()) { - Object domainObject = collectionIter.next(); - - boolean hasPermission = false; - - if (domainObject == null) { - hasPermission = true; - } else if (!getProcessDomainObjectClass().isAssignableFrom(domainObject.getClass())) { - hasPermission = true; - } else { - hasPermission = hasPermission(authentication, domainObject); - - if (!hasPermission) { - filterer.remove(domainObject); - - if (logger.isDebugEnabled()) { - logger.debug("Principal is NOT authorised for element: " + domainObject); - } - } - } - } - - return filterer.getFilteredObject(); + if (!this.supports(attr)) { + continue; } + + // Need to process the Collection for this invocation + Filterer filterer; + + if (returnedObject instanceof Collection) { + filterer = new CollectionFilterer((Collection) returnedObject); + } else if (returnedObject.getClass().isArray()) { + filterer = new ArrayFilterer((Object[]) returnedObject); + } else { + throw new AuthorizationServiceException("A Collection or an array (or null) was required as the " + + "returnedObject, but the returnedObject was: " + returnedObject); + } + + // Locate unauthorised Collection elements + Iterator collectionIter = filterer.iterator(); + + while (collectionIter.hasNext()) { + Object domainObject = collectionIter.next(); + + // Ignore nulls or entries which aren't instances of the configured domain object class + if (domainObject == null || !getProcessDomainObjectClass().isAssignableFrom(domainObject.getClass())) { + continue; + } + + if(!hasPermission(authentication, domainObject)) { + filterer.remove(domainObject); + + if (logger.isDebugEnabled()) { + logger.debug("Principal is NOT authorised for element: " + domainObject); + } + } + } + + return filterer.getFilteredObject(); } return returnedObject; diff --git a/core/src/main/java/org/springframework/security/afterinvocation/AclEntryAfterInvocationProvider.java b/core/src/main/java/org/springframework/security/afterinvocation/AclEntryAfterInvocationProvider.java index 38031a288f..915cde4091 100644 --- a/core/src/main/java/org/springframework/security/afterinvocation/AclEntryAfterInvocationProvider.java +++ b/core/src/main/java/org/springframework/security/afterinvocation/AclEntryAfterInvocationProvider.java @@ -34,22 +34,28 @@ import java.util.Iterator; /** - *

Given a domain object instance returned from a secure object invocation, ensures the principal has - * appropriate permission as defined by the {@link AclService}.

- *

The AclService is used to retrieve the access control list (ACL) permissions associated with a - * domain object instance for the current Authentication object.

- *

This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link - * #processConfigAttribute}. The provider will then lookup the ACLs from the AclService and ensure the + * Given a domain object instance returned from a secure object invocation, ensures the principal has + * appropriate permission as defined by the {@link AclService}. + *

+ * The AclService is used to retrieve the access control list (ACL) permissions associated with a + * domain object instance for the current Authentication object. + *

+ * This after invocation provider will fire if any {@link ConfigAttribute#getAttribute()} matches the {@link + * #processConfigAttribute}. The provider will then lookup the ACLs from the AclService and ensure the * principal is {@link org.springframework.security.acls.Acl#isGranted(org.springframework.security.acls.Permission[], org.springframework.security.acls.sid.Sid[], boolean) Acl.isGranted(Permission[], Sid[], boolean)} - * when presenting the {@link #requirePermission} array to that method.

- *

Often users will setup an AclEntryAfterInvocationProvider with a {@link + * when presenting the {@link #requirePermission} array to that method. + *

+ * Often users will setup an AclEntryAfterInvocationProvider with a {@link * #processConfigAttribute} of AFTER_ACL_READ and a {@link #requirePermission} of - * BasePermission.READ. These are also the defaults.

- *

If the principal does not have sufficient permissions, an AccessDeniedException will be thrown.

- *

If the provided returnObject is null, permission will always be granted and - * null will be returned.

- *

All comparisons and prefixes are case sensitive.

+ * BasePermission.READ. These are also the defaults. + *

+ * If the principal does not have sufficient permissions, an AccessDeniedException will be thrown. + *

+ * If the provided returnedObject is null, permission will always be granted and + * null will be returned. + *

+ * All comparisons and prefixes are case sensitive. */ public class AclEntryAfterInvocationProvider extends AbstractAclProvider implements MessageSourceAware { //~ Static fields/initializers ===================================================================================== @@ -69,45 +75,45 @@ public class AclEntryAfterInvocationProvider extends AbstractAclProvider impleme //~ Methods ======================================================================================================== public Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config, - Object returnedObject) throws AccessDeniedException { + Object returnedObject) throws AccessDeniedException { + Iterator iter = config.getConfigAttributes().iterator(); + if (returnedObject == null) { + // AclManager interface contract prohibits nulls + // As they have permission to null/nothing, grant access + if (logger.isDebugEnabled()) { + logger.debug("Return object is null, skipping"); + } + + return null; + } + + if (!getProcessDomainObjectClass().isAssignableFrom(returnedObject.getClass())) { + if (logger.isDebugEnabled()) { + logger.debug("Return object is not applicable for this provider, skipping"); + } + + return returnedObject; + } + while (iter.hasNext()) { ConfigAttribute attr = (ConfigAttribute) iter.next(); - if (this.supports(attr)) { - // Need to make an access decision on this invocation - if (returnedObject == null) { - // AclManager interface contract prohibits nulls - // As they have permission to null/nothing, grant access - if (logger.isDebugEnabled()) { - logger.debug("Return object is null, skipping"); - } - - return null; - } - - if (!getProcessDomainObjectClass().isAssignableFrom(returnedObject.getClass())) { - if (logger.isDebugEnabled()) { - logger.debug("Return object is not applicable for this provider, skipping"); - } - - return returnedObject; - } - - if (hasPermission(authentication, returnedObject)) { - return returnedObject; - } else { - if (logger.isDebugEnabled()) { - logger.debug("Denying access"); - } - - throw new AccessDeniedException(messages.getMessage( - "BasicAclEntryAfterInvocationProvider.noPermission", - new Object[] {authentication.getName(), returnedObject}, - "Authentication {0} has NO permissions to the domain object {1}")); - } + if (!this.supports(attr)) { + continue; } + // Need to make an access decision on this invocation + + if (hasPermission(authentication, returnedObject)) { + return returnedObject; + } + + logger.debug("Denying access"); + + throw new AccessDeniedException(messages.getMessage("BasicAclEntryAfterInvocationProvider.noPermission", + new Object[] {authentication.getName(), returnedObject}, + "Authentication {0} has NO permissions to the domain object {1}")); } return returnedObject; diff --git a/core/src/main/java/org/springframework/security/afterinvocation/AfterInvocationProvider.java b/core/src/main/java/org/springframework/security/afterinvocation/AfterInvocationProvider.java index 62857cad92..a568195e3b 100644 --- a/core/src/main/java/org/springframework/security/afterinvocation/AfterInvocationProvider.java +++ b/core/src/main/java/org/springframework/security/afterinvocation/AfterInvocationProvider.java @@ -22,8 +22,7 @@ import org.springframework.security.ConfigAttributeDefinition; /** - * Indicates a class is responsible for participating in an {@link - * AfterInvocationProviderManager} decision. + * Indicates a class is responsible for participating in an {@link AfterInvocationProviderManager} decision. * * @author Ben Alex * @version $Id$ diff --git a/core/src/main/java/org/springframework/security/afterinvocation/AfterInvocationProviderManager.java b/core/src/main/java/org/springframework/security/afterinvocation/AfterInvocationProviderManager.java index 52964479f3..7b529b0392 100644 --- a/core/src/main/java/org/springframework/security/afterinvocation/AfterInvocationProviderManager.java +++ b/core/src/main/java/org/springframework/security/afterinvocation/AfterInvocationProviderManager.java @@ -25,6 +25,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; import java.util.Iterator; import java.util.List; @@ -87,16 +88,10 @@ public class AfterInvocationProviderManager implements AfterInvocationManager, I Iterator iter = newList.iterator(); while (iter.hasNext()) { - Object currentObject = null; + Object currentObject = iter.next(); - try { - currentObject = iter.next(); - - AfterInvocationProvider attemptToCast = (AfterInvocationProvider) currentObject; - } catch (ClassCastException cce) { - throw new IllegalArgumentException("AfterInvocationProvider " + currentObject.getClass().getName() - + " must implement AfterInvocationProvider"); - } + Assert.isInstanceOf(AfterInvocationProvider.class, currentObject, "AfterInvocationProvider " + + currentObject.getClass().getName() + " must implement AfterInvocationProvider"); } this.providers = newList; diff --git a/core/src/main/java/org/springframework/security/vote/AclEntryVoter.java b/core/src/main/java/org/springframework/security/vote/AclEntryVoter.java index e46b31db57..51148b7da5 100644 --- a/core/src/main/java/org/springframework/security/vote/AclEntryVoter.java +++ b/core/src/main/java/org/springframework/security/vote/AclEntryVoter.java @@ -35,29 +35,36 @@ import org.springframework.security.acls.sid.SidRetrievalStrategyImpl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** - *

Given a domain object instance passed as a method argument, ensures the principal has appropriate permission - * as indicated by the {@link AclService}.

- *

The AclService is used to retrieve the access control list (ACL) permissions associated with a - * domain object instance for the current Authentication object.

- *

The voter will vote if any {@link ConfigAttribute#getAttribute()} matches the {@link - * #processConfigAttribute}. The provider will then locate the first method argument of type {@link - * #processDomainObjectClass}. Assuming that method argument is non-null, the provider will then lookup the ACLs from - * the AclManager and ensure the principal is {@link Acl#isGranted(org.springframework.security.acls.Permission[], - * org.springframework.security.acls.sid.Sid[], boolean)} when presenting the {@link #requirePermission} array to that method.

- *

If the method argument is null, the voter will abstain from voting. If the method argument - * could not be found, an {@link org.springframework.security.AuthorizationServiceException} will be thrown.

- *

In practical terms users will typically setup a number of AclEntryVoters. Each will have a + *

+ * Given a domain object instance passed as a method argument, ensures the principal has appropriate permission + * as indicated by the {@link AclService}. + *

+ * The AclService is used to retrieve the access control list (ACL) permissions associated with a + * domain object instance for the current Authentication object. + *

+ * The voter will vote if any {@link ConfigAttribute#getAttribute()} matches the {@link #processConfigAttribute}. + * The provider will then locate the first method argument of type {@link #processDomainObjectClass}. Assuming that + * method argument is non-null, the provider will then lookup the ACLs from the AclManager and ensure the + * principal is {@link Acl#isGranted(org.springframework.security.acls.Permission[], + * org.springframework.security.acls.sid.Sid[], boolean)} when presenting the {@link #requirePermission} array to that + * method. + *

+ * If the method argument is null, the voter will abstain from voting. If the method argument + * could not be found, an {@link org.springframework.security.AuthorizationServiceException} will be thrown. + *

+ * In practical terms users will typically setup a number of AclEntryVoters. Each will have a * different {@link #processDomainObjectClass}, {@link #processConfigAttribute} and {@link #requirePermission} - * combination. For example, a small application might employ the following instances of AclEntryVoter: + * combination. For example, a small application might employ the following instances of AclEntryVoter: *