diff --git a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionOperations.java b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionOperations.java index a710eb9475..61f8f7749f 100644 --- a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionOperations.java +++ b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionOperations.java @@ -12,30 +12,91 @@ import org.springframework.security.core.Authentication; */ public interface SecurityExpressionOperations { + /** + * Gets the {@link Authentication} used for evaluating the expressions + * @return the {@link Authentication} for evaluating the expressions + */ Authentication getAuthentication(); + /** + * Determines if the {@link #getAuthentication()} has a particular authority within {@link Authentication#getAuthorities()}. This is a synonym for {@link #hasAuthority(String)}. + * @param authority the authority to test (i.e. "ROLE_USER") + * @return true if the authority is found, else false + */ boolean hasAuthority(String authority); + /** + * Determines if the {@link #getAuthentication()} has any of the specified authorities within {@link Authentication#getAuthorities()}. This is a synonym for {@link #hasAnyRole(String...)}. + * @param authorities the authorities to test (i.e. "ROLE_USER", "ROLE_ADMIN") + * @return true if any of the authorities is found, else false + */ boolean hasAnyAuthority(String... authorities); + /** + * Determines if the {@link #getAuthentication()} has a particular authority within {@link Authentication#getAuthorities()}. This is a synonym for {@link #hasAuthority(String)}. + * @param authority the authority to test (i.e. "ROLE_USER") + * @return true if the authority is found, else false + */ boolean hasRole(String role); + /** + * Determines if the {@link #getAuthentication()} has any of the specified authorities within {@link Authentication#getAuthorities()}. This is a synonym for {@link #hasAnyAuthority(String...)}. + * @param authorities the authorities to test (i.e. "ROLE_USER", "ROLE_ADMIN") + * @return true if any of the authorities is found, else false + */ boolean hasAnyRole(String... roles); + /** + * Always grants access. + * @return true + */ boolean permitAll(); + /** + * Always denies access + * @return false + */ boolean denyAll(); + /** + * Determines if the {@link #getAuthentication()} is anonymous + * @return true if the user is anonymous, else false + */ boolean isAnonymous(); + /** + * Determines ifthe {@link #getAuthentication()} is authenticated + * @return true if the {@link #getAuthentication()} is authenticated, else false + */ boolean isAuthenticated(); + /** + * Determines if the {@link #getAuthentication()} was authenticated using remember me + * @return true if the {@link #getAuthentication()} authenticated using remember me, else false + */ boolean isRememberMe(); + /** + * Determines if the {@link #getAuthentication()} authenticated without the use of remember me + * @return true if the {@link #getAuthentication()} authenticated without the use of remember me, else false + */ boolean isFullyAuthenticated(); + /** + * Determines if the {@link #getAuthentication()} has permission to access the target given the permission + * @param target the target domain object to check permission on + * @param permission the permission to check on the domain object (i.e. "read", "write", etc). + * @return true if permission is granted to the {@link #getAuthentication()}, else false + */ boolean hasPermission(Object target, Object permission); + /** + * Determines if the {@link #getAuthentication()} has permission to access the domain object with a given id, type, and permission. + * @param targetId the identifier of the domain object to determine access + * @param targetType the type (i.e. com.example.domain.Message) + * @param permission the perission to check on the domain object (i.e. "read", "write", etc) + * @return true if permission is granted to the {@link #getAuthentication()}, else false + */ boolean hasPermission(Object targetId, String targetType, Object permission); } diff --git a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java index 49fb22b6a8..fe0a08c463 100644 --- a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java +++ b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java @@ -5,7 +5,6 @@ import java.util.Collection; import java.util.HashSet; import java.util.Set; -import org.springframework.context.ApplicationContext; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; import org.springframework.security.authentication.AuthenticationTrustResolver; @@ -38,11 +37,15 @@ public abstract class SecurityExpressionRoot implements SecurityExpressionOperat public final String delete = "delete"; public final String admin = "administration"; - public SecurityExpressionRoot(Authentication a) { - if (a == null) { + /** + * Creates a new instance + * @param authentication the {@link Authentication} to use. Cannot be null. + */ + public SecurityExpressionRoot(Authentication authentication) { + if (authentication == null) { throw new IllegalArgumentException("Authentication object cannot be null"); } - this.authentication = a; + this.authentication = authentication; } public final boolean hasAuthority(String authority) { @@ -97,6 +100,10 @@ public abstract class SecurityExpressionRoot implements SecurityExpressionOperat return !trustResolver.isAnonymous(authentication) && !trustResolver.isRememberMe(authentication); } + /** + * Convenience method to access {@link Authentication#getPrincipal()} from {@link #getAuthentication()} + * @return + */ public Object getPrincipal() { return authentication.getPrincipal(); } diff --git a/docs/manual/src/asciidoc/index.adoc b/docs/manual/src/asciidoc/index.adoc index 714374a9d5..2a24056be1 100644 --- a/docs/manual/src/asciidoc/index.adoc +++ b/docs/manual/src/asciidoc/index.adoc @@ -4089,10 +4089,16 @@ The base class for expression root objects is `SecurityExpressionRoot`. This pro | Expression | Description | `hasRole([role])` -| Returns `true` if the current principal has the specified role. +| Returns `true` if the current principal has the specified role. This is a synonym for `hasAuthority([authority])` | `hasAnyRole([role1,role2])` -| Returns `true` if the current principal has any of the supplied roles (given as a comma-separated list of strings) +| Returns `true` if the current principal has any of the supplied roles (given as a comma-separated list of strings) This is a synonym for `hasAnyAuthority([authority1,authority2])` + +| `hasAuthority([authority])` +| Returns `true` if the current principal has the specified authority. This is a synonym for `hasRole([role])` + +| `hasAnyAuthority([authority1,authority2])` +| Returns `true` if the current principal has any of the supplied roles (given as a comma-separated list of strings) `hasAnyRole([role1,role2])``hasAnyRole([role1,role2])` | `principal` | Allows direct access to the principal object representing the current user @@ -4117,6 +4123,12 @@ The base class for expression root objects is `SecurityExpressionRoot`. This pro | `isFullyAuthenticated()` | Returns `true` if the user is not an anonymous or a remember-me user + +| `hasPermission(Object target, Object permission)` +| Returns `true` if the user has access to the provided target for the given permission. For example, `hasPermission(domainObject, 'read')` + +| `hasPermission(Object targetId, String targetType, Object permission)` +| Returns `true` if the user has access to the provided target for the given permission. For example, `hasPermission(1, 'com.example.domain.Message', 'read')` |===