@ -68,6 +69,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@@ -68,6 +69,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@ -75,6 +77,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@@ -75,6 +77,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@ -84,12 +87,14 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@@ -84,12 +87,14 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@ -104,12 +109,14 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@@ -104,12 +109,14 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@ -124,6 +131,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@@ -124,6 +131,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@ -131,6 +139,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@@ -131,6 +139,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware {
@ -50,32 +51,48 @@ final class ReactiveAuthorizationManagerMethodSecurityConfiguration {
@@ -50,32 +51,48 @@ final class ReactiveAuthorizationManagerMethodSecurityConfiguration {
@ -890,4 +965,100 @@ public class PrePostMethodSecurityConfigurationTests {
@@ -890,4 +965,100 @@ public class PrePostMethodSecurityConfigurationTests {
@ -46,7 +46,19 @@ public final class PostAuthorizeAuthorizationManager implements AuthorizationMan
@@ -46,7 +46,19 @@ public final class PostAuthorizeAuthorizationManager implements AuthorizationMan
@ -59,15 +43,14 @@ final class PostAuthorizeExpressionAttributeRegistry extends AbstractExpressionA
@@ -59,15 +43,14 @@ final class PostAuthorizeExpressionAttributeRegistry extends AbstractExpressionA
@ -46,7 +46,19 @@ public final class PostAuthorizeReactiveAuthorizationManager
@@ -46,7 +46,19 @@ public final class PostAuthorizeReactiveAuthorizationManager
@ -67,7 +67,19 @@ public final class PostFilterAuthorizationMethodInterceptor
@@ -67,7 +67,19 @@ public final class PostFilterAuthorizationMethodInterceptor
@ -67,7 +67,19 @@ public final class PostFilterAuthorizationReactiveMethodInterceptor
@@ -67,7 +67,19 @@ public final class PostFilterAuthorizationReactiveMethodInterceptor
@ -58,15 +42,15 @@ final class PostFilterExpressionAttributeRegistry extends AbstractExpressionAttr
@@ -58,15 +42,15 @@ final class PostFilterExpressionAttributeRegistry extends AbstractExpressionAttr
@ -46,7 +46,19 @@ public final class PreAuthorizeAuthorizationManager implements AuthorizationMana
@@ -46,7 +46,19 @@ public final class PreAuthorizeAuthorizationManager implements AuthorizationMana
@ -63,15 +43,14 @@ final class PreAuthorizeExpressionAttributeRegistry extends AbstractExpressionAt
@@ -63,15 +43,14 @@ final class PreAuthorizeExpressionAttributeRegistry extends AbstractExpressionAt
@ -45,7 +45,19 @@ public final class PreAuthorizeReactiveAuthorizationManager implements ReactiveA
@@ -45,7 +45,19 @@ public final class PreAuthorizeReactiveAuthorizationManager implements ReactiveA
@ -68,7 +68,19 @@ public final class PreFilterAuthorizationMethodInterceptor
@@ -68,7 +68,19 @@ public final class PreFilterAuthorizationMethodInterceptor
@ -70,7 +70,19 @@ public final class PreFilterAuthorizationReactiveMethodInterceptor
@@ -70,7 +70,19 @@ public final class PreFilterAuthorizationReactiveMethodInterceptor
fun prePostTemplateDefaults(): PrePostTemplateDefaults {
return PrePostTemplateDefaults()
}
}
----
======
Now instead of `@IsAdmin`, you can create something more powerful like `@HasRole` like so:
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasRole('{value}')")
public @interface HasRole {
String value();
}
----
Kotlin::
+
[source,kotlin,role="secondary"]
----
@Target(ElementType.METHOD, ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasRole('{value}')")
annotation class IsAdmin(val value: String)
----
======
And the result is that on your secured methods you can now do the following instead:
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Component
public class BankService {
@HasRole("ADMIN")
public Account readAccount(Long id) {
// ... is only returned if the `Account` belongs to the logged in user
}
}
----
Kotlin::
+
[source,kotlin,role="secondary"]
----
@Component
open class BankService {
@HasRole("ADMIN")
fun readAccount(val id: Long): Account {
// ... is only returned if the `Account` belongs to the logged in user
}
}
----
======
Note that this works with method variables and all annotation types, too, though you will want to be careful to correctly take care of quotation marks so the resulting SpEL expression is correct.
For example, consider the following `@HasAnyRole` annotation:
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasAnyRole({roles})")
public @interface HasAnyRole {
String[] roles();
}
----
Kotlin::
+
[source,kotlin,role="secondary"]
----
@Target(ElementType.METHOD, ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasAnyRole({roles})")
annotation class HasAnyRole(val roles: Array<String>)
----
======
In that case, you'll notice that you should not use the quotation marks in the expression, but instead in the parameter value like so:
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@Component
public class BankService {
@HasAnyRole(roles = { "'USER'", "'ADMIN'" })
public Account readAccount(Long id) {
// ... is only returned if the `Account` belongs to the logged in user
}
}
----
Kotlin::
+
[source,kotlin,role="secondary"]
----
@Component
open class BankService {
@HasAnyRole(roles = arrayOf("'USER'", "'ADMIN'"))
fun readAccount(val id: Long): Account {
// ... is only returned if the `Account` belongs to the logged in user
}
}
----
======
so that, once replaced, the expression becomes `@PreAuthorize("hasAnyRole('USER', 'ADMIN')")`.