Reputation: 3526
It's not clear for me what is the difference in spring security between :
@PreAuthorize("hasRole('ROLE_USER')")
public void create(Contact contact)
And
@Secured("ROLE_USER")
public void create(Contact contact)
I understand PreAuthorize can work with spring el but in my sample, is there a real difference ?
Upvotes: 183
Views: 77548
Reputation: 667
@PreAuthorize
is different, it is more powerful than @Secured
.
The older
@Secured
annotations did not allow expressions to be used.
Starting with Spring Security 3, the more flexible annotations
@PreAuthorize
and@PostAuthorize
(as well as @PreFilter and @PostFilter) are preferred, as they support Spring Expression Language (SpEL) and provide expression-based access control.
@Secured("ROLE_ADMIN")
annotation is the same as@PreAuthorize ("hasRole('ROLE_ADMIN')")
.
The
@Secured({"ROLE_USER","ROLE_ADMIN")
is considered as ROLE_USER OR ROLE_ADMIN.
so you cannot express the AND condition using
@Secured. You can define the same with
@PreAuthorize("hasRole('ADMIN') OR hasRole('USER')")
, which is easier to understand. You can express AND, OR, or NOT(!) as well.@PreAuthorize("!isAnonymous() AND hasRole( 'ADMIN')")
Upvotes: 22
Reputation: 953
If you wanted to do something like access the method only if the user has Role1 and Role2 then you would have to use @PreAuthorize
@PreAuthorize("hasRole('ROLE_role1') and hasRole('ROLE_role2')")
Using
@Secured({"role1", "role2"}) // is treated as an OR
Upvotes: 67
Reputation: 11116
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
| | @Secured | @PreAuthorize |
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
| Spring EL expressions | Does'nt supports. | Supports |
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
| Multiple roles conjunctions with AND operator | Does'nt supports.(If there are multiple roles defined | Supports |
| |they will be automatically combined with OR operator) | |
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
| To enable annotation | Add following line to spring-security.xml | Add following line to spring-security.xml |
| | <global-method-security secured-annotations="enabled" /> | <global-method-security pre-post-annotations="enabled"/> |
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
| Example | @Secured({ROLE_ADMIN , ROLE_USER}) | @PreAuthorize("hasRole('ROLE_USER') and hasRole('ROLE_ADMIN')") |
| | public void addUser(UserInfo user){...} | public void addUser(UserInfo user){...} |
+-----------------------------------------------+----------------------------------------------------------+-----------------------------------------------------------------+
Upvotes: 15
Reputation: 242686
The real difference is that @PreAuthorize
can work with Spring Expression Language (SpEL). You can:
SecurityExpressionRoot
.Access method arguments (requires compilation with debug info or custom ParameterNameDiscoverer
):
@PreAuthorize("#contact.name == principal.name")
public void doSomething(Contact contact)
MethodSecurityExpressionHandler
and set it as <global-method-security><expression-handler ... /></...>
).Upvotes: 195
Reputation: 557
Simply,
@PreAuthorize
is newer than @Secured
.
So I say it is better to use @PreAuthorize
as it is "expression-based" and you can use expressions like hasRole, hasAnyRole, permitAll, etc.
To learn about expressions, see these example expressions.
Upvotes: 49