Skip to content

Commit 8b2a453

Browse files
committed
Advise Favoring PostAuthorize on Reads
Closes gh-17797
1 parent 894105a commit 8b2a453

File tree

1 file changed

+9
-33
lines changed

1 file changed

+9
-33
lines changed

docs/modules/ROOT/pages/servlet/authorization/method-security.adoc

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,14 @@ open class BankService {
544544
The result is that the above method will only return the `Account` if its `owner` attribute matches the logged-in user's `name`.
545545
If not, Spring Security will throw an `AccessDeniedException` and return a 403 status code.
546546

547+
[NOTE]
548+
=====
549+
Note that `@PostAuthorize` is not recommended for classes that perform database writes since that typically means that a database change was made before the security invariants were checked.
550+
A common example of doing this is if you have `@Transactional` and `@PostAuthorize` on the same method.
551+
Instead, read the value first, using `@PostAuthorize` on the read, and then perform the database write, should that read is authorized.
552+
If you must do something like this, you can <<changing-the-order, ensure that `@EnableTransactionManagement` comes before `@EnableMethodSecurity`>>.
553+
=====
554+
547555
[[use-prefilter]]
548556
=== Filtering Method Parameters with `@PreFilter`
549557

@@ -1795,39 +1803,7 @@ As already noted, there is a Spring AOP method interceptor for each annotation,
17951803

17961804
Namely, the `@PreFilter` method interceptor's order is 100, ``@PreAuthorize``'s is 200, and so on.
17971805

1798-
The reason this is important to note is that there are other AOP-based annotations like `@EnableTransactionManagement` that have an order of `Integer.MAX_VALUE`.
1799-
In other words, they are located at the end of the advisor chain by default.
1800-
1801-
At times, it can be valuable to have other advice execute before Spring Security.
1802-
For example, if you have a method annotated with `@Transactional` and `@PostAuthorize`, you might want the transaction to still be open when `@PostAuthorize` runs so that an `AccessDeniedException` will cause a rollback.
1803-
1804-
To get `@EnableTransactionManagement` to open a transaction before method authorization advice runs, you can set ``@EnableTransactionManagement``'s order like so:
1805-
1806-
[tabs]
1807-
======
1808-
Java::
1809-
+
1810-
[source,java,role="primary"]
1811-
----
1812-
@EnableTransactionManagement(order = 0)
1813-
----
1814-
1815-
Kotlin::
1816-
+
1817-
[source,kotlin,role="secondary"]
1818-
----
1819-
@EnableTransactionManagement(order = 0)
1820-
----
1821-
1822-
Xml::
1823-
+
1824-
[source,xml,role="secondary"]
1825-
----
1826-
<tx:annotation-driven ref="txManager" order="0"/>
1827-
----
1828-
======
1829-
1830-
Since the earliest method interceptor (`@PreFilter`) is set to an order of 100, a setting of zero means that the transaction advice will run before all Spring Security advice.
1806+
You can use the `offset` parameter on `@EnableMethodSecurity` to move all interceptors en masse to provide their advice earlier or later in a method invocation.
18311807

18321808
[[authorization-expressions]]
18331809
== Expressing Authorization with SpEL

0 commit comments

Comments
 (0)