Chapter 15. Expression-based permission control
Spring Security 3.0 describes the ability to use spring El Expressions as a validation mechanism to add simple configuration properties to the use and access decision polls as before. Expression-based security controls are built on the same schema, but allow complex Boolean logic to be included in a separate expression.
15.1. Overview
Spring security uses spring El to support expressions, and you should look at how it works if you are interested in learning more about the topic. The expression is executed on a " root Object" as part of the execution context. Spring security uses specific classes that correspond to web and method safety, as root objects, in order to provide built-in expressions, access values, such as the current authentication principal.
15.1.1. Common built-in expressions
The basic class of the expression root object is SecurityExpressionRoot
. This provides some common expressions that can be used in Web and method permission controls.
Table 15.1. Common built-in expressions
An expression |
Description |
hasRole([role]) |
Returns true if the current principal has a specific role. |
hasAnyRole([role1,role2]) |
Returns true if the current principal has any one of the provided roles (using a comma-delimited string queue) |
principal |
Allows direct access to the principal object, representing the current user |
authentication |
Allows direct access to Authentication the current object SecurityContext obtained from the |
permitAll |
Always returntrue |
denyAll |
Always returnfalse |
isAnonymous() |
If the user is an anonymous login, the user returnstrue |
isRememberMe() |
If the user is logged on through Remember-me, the user will returntrue |
isAuthenticated() |
If the user is not an anonymous user, it returnstrue |
isFullyAuthenticated() |
If the user is not logged on anonymously or through Remember-me, it is returned true . |
15.2. Web-Safe expressions
To protect individual URLs, you need to use-expressions
set the property to true first. Spring Security considers <intercept-url>
the access
spring El expression to be included. The expression should return a Boolean that defines whether the access should be allowed, such as:
Here we have defined the application's "admin" scope (defined by the URL pattern) to be valid only forusers with "admin" permission, and the user will be under the IP address of the local subnet. We've seen the built-in hasRole
expressions in the previous section. An expression hasIpAddress
is an additional built-in expression that is provided by web security. It is defined by an WebSecurityExpressionRoot
instance of it as the expression root object when the Web permission expression is executed. This object also directly exposes the HttpServletRequest
object using request
that name, so you can call the request directly in an expression.
If an expression is used, one is WebExpressionVoter
added to AccessDecisionManager
, which is created by the namespace. So if you're not using namespaces and you want to use expressions, you have to add these to your configuration.
15.3. Method-Safe expressionsMethod security is a bit more complex than the individual allow and deny rules. Spring Security 3.0 introduces some new annotations in order to support complex expressions.
15.3.1.@Pre
And@Post
AnnotationsThere are four annotations, and support for expression properties allows both pre-and post-call validation detection, as well as filtering of submitted collection parameters or return values. They are @PreAuthorize
, @PreFilter
,, @PostAuthorize
and @PostFilter
. They can be global-method-security
enabled through namespace elements:
<global-method-security pre-post-annotations= "Enabled"/>
15.3.1.1. Access Control usage@PreAuthorize
And@PostAuthorize
The most widely used annotation is @PreAuthorize
that it can determine whether a method can be called. For example (from "Contacts" instance application)
@PreAuthorize ("Hasrole (' Role_user ')") public void Create (contact contact);
This means that only users with the "role_user" role are allowed access. Obviously, the same thing can be simple and practical traditional configuration methods, simple configuration properties to require the role. But if that's the case:
@PreAuthorize ("Haspermission (#contact, ' admin ')") public void deletepermission (Contact contact, Sid recipient, Permission Permission);
Here we actually use the method parameter as part of the expression to determine whether the current user has an "admin" expression for the given contract. The built-in hasPermission()
expression is linked to the Spring Security ACL module through the Applicaton context. You can access any method parameter by using the name of a variable like an expression, and use the debug information at compile time. Any spring El feature can be used in an expression, so you can access the properties of the parameter. For example, if you want a specific method that only allows access to a user name and contract match, you can write
@PreAuthorize ("#contact. Name = = authentication.name)") Public void dosomething (Contact contact);
Here we visit another built-in expression, which authentication
is an instance stored in the security context Authentication
. You can also directly access its "principal" property, using principal
an expression. This value is typically an UserDetails
instance, so you might use an expression that looks like it principal.username
or not principal.enabled
.
Less common is that you might want the star to have an access control detection after the method call. This can be used with @PostAuthorize
annotations. To access the return value of a method, use the built-in name in the expression returnObject
.
15.3.1.2. Filter using@PreFilter
And@PostFilter
As you may already know, Spring security supports filtering of collections and data, and can now be implemented using expressions. is usually used in the return value of a method. Like what:
@PreAuthorize ("Hasrole (' Role_user ')") @PostFilter ("Haspermission (Filterobject, ' read ') or haspermission ( Filterobject, ' admin ') "Public list<contact> getAll ();
When using @PostFilter
annotations, Spring security iterates through the returned collection to remove any elements that return false for any expression. filterObject
the name references the current object in the collection. You can also filter before the method call, although it is @PreFilter
rarely necessary to do so. This syntax is the same, but if there are more arguments, it is the collection type and then you have to select one of the attributes of the annotation filterTarget
.
Note that filtering is obviously not a workaround for you to read data queries. If you filter large collections and delete many entities, then this will be very inefficient.
Spring security Annotations (1)