Add AuthorizeReturnObject
Closes gh-14597
This commit is contained in:
@@ -1707,8 +1707,7 @@ For interfaces, either annotations or the `-parameters` approach must be used.
|
||||
|
||||
Spring Security also supports wrapping any object that is annotated its method security annotations.
|
||||
|
||||
To achieve this, you can autowire the provided `AuthorizationProxyFactory` instance, which is based on which method security interceptors you have configured.
|
||||
If you are using `@EnableMethodSecurity`, then this means that it will by default have the interceptors for `@PreAuthorize`, `@PostAuthorize`, `@PreFilter`, and `@PostFilter`.
|
||||
The simplest way to achieve this is to mark any method that returns the object you wish to authorize with the `@AuthorizeReturnObject` annotation.
|
||||
|
||||
For example, consider the following `User` class:
|
||||
|
||||
@@ -1746,6 +1745,89 @@ class User (val name:String, @get:PreAuthorize("hasAuthority('user:read')") val
|
||||
----
|
||||
======
|
||||
|
||||
Given an interface like this one:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
public class UserRepository {
|
||||
@AuthorizeReturnObject
|
||||
Optional<User> findByName(String name) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
class UserRepository {
|
||||
@AuthorizeReturnObject
|
||||
fun findByName(name:String?): Optional<User?>? {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
Then any `User` that is returned from `findById` will be secured like other Spring Security-protected components:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@Autowired
|
||||
UserRepository users;
|
||||
|
||||
@Test
|
||||
void getEmailWhenProxiedThenAuthorizes() {
|
||||
Optional<User> securedUser = users.findByName("name");
|
||||
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(() -> securedUser.get().getEmail());
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
|
||||
import jdk.incubator.vector.VectorOperators.Test
|
||||
import java.nio.file.AccessDeniedException
|
||||
import java.util.*
|
||||
|
||||
@Autowired
|
||||
var users:UserRepository? = null
|
||||
|
||||
@Test
|
||||
fun getEmailWhenProxiedThenAuthorizes() {
|
||||
val securedUser: Optional<User> = users.findByName("name")
|
||||
assertThatExceptionOfType(AccessDeniedException::class.java).isThrownBy{securedUser.get().getEmail()}
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
`@AuthorizeReturnObject` can be placed at the class level. Note, though, that this means Spring Security will proxy any return object, including ``String``, ``Integer`` and other types.
|
||||
This is often not what you want to do.
|
||||
|
||||
In most cases, you will want to annotate the individual methods.
|
||||
====
|
||||
|
||||
=== Programmatically Proxying
|
||||
|
||||
You can also programmatically proxy a given object.
|
||||
|
||||
To achieve this, you can autowire the provided `AuthorizationProxyFactory` instance, which is based on which method security interceptors you have configured.
|
||||
If you are using `@EnableMethodSecurity`, then this means that it will by default have the interceptors for `@PreAuthorize`, `@PostAuthorize`, `@PreFilter`, and `@PostFilter`.
|
||||
|
||||
|
||||
You can proxy an instance of user in the following way:
|
||||
|
||||
[tabs]
|
||||
|
||||
@@ -11,6 +11,7 @@ Below are the highlights of the release.
|
||||
== Authorization
|
||||
|
||||
- https://github.com/spring-projects/spring-security/issues/14596[gh-14596] - xref:servlet/authorization/method-security.adoc[docs] - Add Programmatic Proxy Support for Method Security
|
||||
- https://github.com/spring-projects/spring-security/issues/14597[gh-14597] - xref:servlet/authorization/method-security.adoc[docs] - Add Securing of Return Values
|
||||
|
||||
== Configuration
|
||||
|
||||
|
||||
Reference in New Issue
Block a user