mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-08 11:32:47 +00:00
Document Reactive Method security requires Publisher return types
Fixes: gh-4988
This commit is contained in:
parent
ea3dd336aa
commit
964a14b224
@ -28,6 +28,12 @@ public class DelegatingReactiveMessageService implements ReactiveMessageService
|
|||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@PreAuthorize("denyAll")
|
||||||
|
public String notPublisherPreAuthorizeFindById(long id) {
|
||||||
|
return this.delegate.notPublisherPreAuthorizeFindById(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<String> monoFindById(long id) {
|
public Mono<String> monoFindById(long id) {
|
||||||
return delegate.monoFindById(id);
|
return delegate.monoFindById(id);
|
||||||
|
@ -34,6 +34,7 @@ import reactor.test.StepVerifier;
|
|||||||
import reactor.test.publisher.TestPublisher;
|
import reactor.test.publisher.TestPublisher;
|
||||||
import reactor.util.context.Context;
|
import reactor.util.context.Context;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,6 +61,14 @@ public class EnableReactiveMethodSecurityTests {
|
|||||||
this.delegate = config.delegate;
|
this.delegate = config.delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void notPublisherPreAuthorizeFindByIdThenThrowsIllegalStateException() {
|
||||||
|
assertThatThrownBy(() -> this.messageService.notPublisherPreAuthorizeFindById(1L))
|
||||||
|
.isInstanceOf(IllegalStateException.class)
|
||||||
|
.extracting(Throwable::getMessage)
|
||||||
|
.contains("The returnType class java.lang.String on public abstract java.lang.String org.springframework.security.config.annotation.method.configuration.ReactiveMessageService.notPublisherPreAuthorizeFindById(long) must return an instance of org.reactivestreams.Publisher (i.e. Mono / Flux) in order to support Reactor Context");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void monoWhenPermitAllThenAopDoesNotSubscribe() {
|
public void monoWhenPermitAllThenAopDoesNotSubscribe() {
|
||||||
when(this.delegate.monoFindById(1L)).thenReturn(Mono.from(result));
|
when(this.delegate.monoFindById(1L)).thenReturn(Mono.from(result));
|
||||||
|
@ -20,6 +20,8 @@ import reactor.core.publisher.Flux;
|
|||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
public interface ReactiveMessageService {
|
public interface ReactiveMessageService {
|
||||||
|
String notPublisherPreAuthorizeFindById(long id);
|
||||||
|
|
||||||
Mono<String> monoFindById(long id);
|
Mono<String> monoFindById(long id);
|
||||||
Mono<String> monoPreAuthorizeHasRoleFindById(long id);
|
Mono<String> monoPreAuthorizeHasRoleFindById(long id);
|
||||||
Mono<String> monoPostAuthorizeFindById(long id);
|
Mono<String> monoPostAuthorizeFindById(long id);
|
||||||
|
@ -64,6 +64,9 @@ public class PrePostAdviceReactiveMethodInterceptor implements MethodInterceptor
|
|||||||
throws Throwable {
|
throws Throwable {
|
||||||
Method method = invocation.getMethod();
|
Method method = invocation.getMethod();
|
||||||
Class<?> returnType = method.getReturnType();
|
Class<?> returnType = method.getReturnType();
|
||||||
|
if (!Publisher.class.isAssignableFrom(returnType)) {
|
||||||
|
throw new IllegalStateException("The returnType " + returnType + " on " + method + " must return an instance of org.reactivestreams.Publisher (i.e. Mono / Flux) in order to support Reactor Context");
|
||||||
|
}
|
||||||
Class<?> targetClass = invocation.getThis().getClass();
|
Class<?> targetClass = invocation.getThis().getClass();
|
||||||
Collection<ConfigAttribute> attributes = this.attributeSource
|
Collection<ConfigAttribute> attributes = this.attributeSource
|
||||||
.getAttributes(method, targetClass);
|
.getAttributes(method, targetClass);
|
||||||
|
@ -1718,6 +1718,12 @@ For additional information about methods that can be overridden, refer to the `G
|
|||||||
Spring Security supports method security using https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context] which is setup using `ReactiveSecurityContextHolder`.
|
Spring Security supports method security using https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context] which is setup using `ReactiveSecurityContextHolder`.
|
||||||
For example, this demonstrates how to retrieve the currently logged in user's message.
|
For example, this demonstrates how to retrieve the currently logged in user's message.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
For this to work the return type of the method must be a `org.reactivestreams.Publisher` (i.e. `Mono`/`Flux`).
|
||||||
|
This is necessary to integrate with Reactor's `Context`.
|
||||||
|
====
|
||||||
|
|
||||||
[source,java]
|
[source,java]
|
||||||
----
|
----
|
||||||
Authentication authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER");
|
Authentication authentication = new TestingAuthenticationToken("user", "password", "ROLE_USER");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user