parent
0286d368c3
commit
320567128a
|
@ -114,7 +114,9 @@ So if you aren't using the namespace and want to use expressions, you will have
|
|||
If you wish to extend the expressions that are available, you can easily refer to any Spring Bean you expose.
|
||||
For example, assuming you have a Bean with the name of `webSecurity` that contains the following method signature:
|
||||
|
||||
[source,java]
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
public class WebSecurity {
|
||||
public boolean check(Authentication authentication, HttpServletRequest request) {
|
||||
|
@ -123,6 +125,17 @@ public class WebSecurity {
|
|||
}
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
class WebSecurity {
|
||||
fun check(authentication: Authentication?, request: HttpServletRequest?): Boolean {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
You could refer to the method using:
|
||||
|
||||
.Refer to method
|
||||
|
@ -167,7 +180,9 @@ For example, consider a RESTful application that looks up a user by id from the
|
|||
You can easily refer to the path variable by placing it in the pattern.
|
||||
For example, if you had a Bean with the name of `webSecurity` that contains the following method signature:
|
||||
|
||||
[source,java]
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
public class WebSecurity {
|
||||
public boolean checkUserId(Authentication authentication, int id) {
|
||||
|
@ -176,6 +191,17 @@ public class WebSecurity {
|
|||
}
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
class WebSecurity {
|
||||
fun checkUserId(authentication: Authentication?, id: Int): Boolean {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
You could refer to the method using:
|
||||
|
||||
.Path Variables
|
||||
|
@ -234,22 +260,42 @@ Their use is enabled through the `global-method-security` namespace element:
|
|||
The most obviously useful annotation is `@PreAuthorize` which decides whether a method can actually be invoked or not.
|
||||
For example (from the "Contacts" sample application)
|
||||
|
||||
[source,java]
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@PreAuthorize("hasRole('USER')")
|
||||
public void create(Contact contact);
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
@PreAuthorize("hasRole('USER')")
|
||||
fun create(contact: Contact?)
|
||||
----
|
||||
====
|
||||
|
||||
which means that access will only be allowed for users with the role "ROLE_USER".
|
||||
Obviously the same thing could easily be achieved using a traditional configuration and a simple configuration attribute for the required role.
|
||||
But what about:
|
||||
|
||||
[source,java]
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@PreAuthorize("hasPermission(#contact, 'admin')")
|
||||
public void deletePermission(Contact contact, Sid recipient, Permission permission);
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
@PreAuthorize("hasPermission(#contact, 'admin')")
|
||||
fun deletePermission(contact: Contact?, recipient: Sid?, permission: Permission?)
|
||||
----
|
||||
====
|
||||
|
||||
Here we're actually using a method argument as part of the expression to decide whether the current user has the "admin"permission for the given contact.
|
||||
The built-in `hasPermission()` expression is linked into the Spring Security ACL module through the application context, as we'll <<el-permission-evaluator,see below>>.
|
||||
You can access any of the method arguments by name as expression variables.
|
||||
|
@ -264,7 +310,9 @@ For example:
|
|||
|
||||
+
|
||||
|
||||
[source,java]
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
import org.springframework.security.access.method.P;
|
||||
|
||||
|
@ -274,6 +322,18 @@ import org.springframework.security.access.method.P;
|
|||
public void doSomething(@P("c") Contact contact);
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
import org.springframework.security.access.method.P
|
||||
|
||||
...
|
||||
|
||||
@PreAuthorize("#c.name == authentication.name")
|
||||
fun doSomething(@P("c") contact: Contact?)
|
||||
----
|
||||
====
|
||||
|
||||
+
|
||||
|
||||
Behind the scenes this is implemented using `AnnotationParameterNameDiscoverer` which can be customized to support the value attribute of any specified annotation.
|
||||
|
@ -284,7 +344,9 @@ For example:
|
|||
|
||||
+
|
||||
|
||||
[source,java]
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
import org.springframework.data.repository.query.Param;
|
||||
|
||||
|
@ -294,6 +356,18 @@ import org.springframework.data.repository.query.Param;
|
|||
Contact findContactByName(@Param("n") String name);
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
import org.springframework.data.repository.query.Param
|
||||
|
||||
...
|
||||
|
||||
@PreAuthorize("#n == authentication.name")
|
||||
fun findContactByName(@Param("n") name: String?): Contact?
|
||||
----
|
||||
====
|
||||
|
||||
+
|
||||
|
||||
Behind the scenes this is implemented using `AnnotationParameterNameDiscoverer` which can be customized to support the value attribute of any specified annotation.
|
||||
|
@ -311,12 +385,22 @@ Any Spring-EL functionality is available within the expression, so you can also
|
|||
For example, if you wanted a particular method to only allow access to a user whose username matched that of the contact, you could write
|
||||
--
|
||||
|
||||
[source,java]
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@PreAuthorize("#contact.name == authentication.name")
|
||||
public void doSomething(Contact contact);
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
@PreAuthorize("#contact.name == authentication.name")
|
||||
fun doSomething(contact: Contact?)
|
||||
----
|
||||
====
|
||||
|
||||
Here we are accessing another built-in expression, `authentication`, which is the `Authentication` stored in the security context.
|
||||
You can also access its "principal" property directly, using the expression `principal`.
|
||||
The value will often be a `UserDetails` instance, so you might use an expression like `principal.username` or `principal.enabled`.
|
||||
|
@ -333,13 +417,24 @@ Spring Security supports filtering of collections, arrays, maps and streams usin
|
|||
This is most commonly performed on the return value of a method.
|
||||
For example:
|
||||
|
||||
[source,java]
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@PreAuthorize("hasRole('USER')")
|
||||
@PostFilter("hasPermission(filterObject, 'read') or hasPermission(filterObject, 'admin')")
|
||||
public List<Contact> getAll();
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
@PreAuthorize("hasRole('USER')")
|
||||
@PostFilter("hasPermission(filterObject, 'read') or hasPermission(filterObject, 'admin')")
|
||||
fun getAll(): List<Contact?>
|
||||
----
|
||||
====
|
||||
|
||||
When using the `@PostFilter` annotation, Spring Security iterates through the returned collection or map and removes any elements for which the supplied expression is false.
|
||||
For an array, a new array instance will be returned containing filtered elements.
|
||||
The name `filterObject` refers to the current object in the collection.
|
||||
|
@ -412,13 +507,24 @@ For example, consider the following:
|
|||
|
||||
Instead of repeating this everywhere, we can create a meta annotation that can be used instead.
|
||||
|
||||
[source,java]
|
||||
====
|
||||
.Java
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@PreAuthorize("#contact.name == authentication.name")
|
||||
public @interface ContactPermission {}
|
||||
----
|
||||
|
||||
.Kotlin
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@PreAuthorize("#contact.name == authentication.name")
|
||||
annotation class ContactPermission
|
||||
----
|
||||
====
|
||||
|
||||
Meta annotations can be used for any of the Spring Security method security annotations.
|
||||
In order to remain compliant with the specification JSR-250 annotations do not support meta annotations.
|
||||
|
||||
|
|
Loading…
Reference in New Issue