Polish ReactiveMethodSecurity Support

- Changed annotation property to useAuthorizationManager
to match related XML support
- Moved support found in bean post-processors back into
interceptors directly. This reduces the number of components to
maintain and simplifies ongoing support
- Added @Deprecated annotation to indicate that applications
should use AuthorizationManagerBeforeReactiveMethodInterceptor and
AuthorizationManagerAfterReactiveMethodInterceptor instead. While
true that the new support does not support coroutines, the existing
coroutine support is problematic since it cannot be reliably paired
with other method interceptors
- Moved expression handler configuration to the constructors
- Constrain all method security interceptors to require publisher types
- Use ReactiveAdapter to check for single-value types as well

Issue gh-9401

Polish
This commit is contained in:
Josh Cummings
2022-08-17 22:29:51 -06:00
parent 6fd23d2567
commit e990174c89
30 changed files with 290 additions and 419 deletions

View File

@@ -112,6 +112,11 @@ public class DelegatingReactiveMessageService implements ReactiveMessageService
return flux;
}
@PostFilter("filterObject.length > 5")
public Flux<String> fluxPostFilter(Flux<String> flux) {
return flux;
}
@Override
public Publisher<String> publisherFindById(long id) {
return this.delegate.publisherFindById(id);

View File

@@ -42,7 +42,7 @@ import static org.mockito.Mockito.reset;
/**
* Tests for {@link EnableReactiveMethodSecurity} with the
* {@link EnableReactiveMethodSecurity#authorizationManager()} flag set to true.
* {@link EnableReactiveMethodSecurity#useAuthorizationManager()} flag set to true.
*
* @author Evgeniy Cheban
*/
@@ -79,8 +79,7 @@ public class EnableAuthorizationManagerReactiveMethodSecurityTests {
.withMessage("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) or the function must be a Kotlin coroutine "
+ "function in order to support Reactor Context");
+ ".Publisher (for example, a Mono or Flux) in order to support Reactor Context");
}
@Test
@@ -340,6 +339,13 @@ public class EnableAuthorizationManagerReactiveMethodSecurityTests {
StepVerifier.create(flux).expectNext("harold", "jonathan").expectError(AccessDeniedException.class).verify();
}
@Test
public void fluxPostFilterWhenFilteringThenWorks() {
Flux<String> flux = this.messageService.fluxPostFilter(Flux.just("harold", "jonathan", "michael", "pete", "bo"))
.contextWrite(this.withAdmin);
StepVerifier.create(flux).expectNext("harold", "jonathan", "michael").verifyComplete();
}
// Publisher tests
@Test
public void publisherWhenPermitAllThenAopDoesNotSubscribe() {
@@ -458,7 +464,7 @@ public class EnableAuthorizationManagerReactiveMethodSecurityTests {
return publisher(Flux.just(data));
}
@EnableReactiveMethodSecurity(authorizationManager = true)
@EnableReactiveMethodSecurity(useAuthorizationManager = true)
static class Config {
ReactiveMessageService delegate = mock(ReactiveMessageService.class);

View File

@@ -48,6 +48,8 @@ public interface ReactiveMessageService {
Flux<String> fluxManyAnnotations(Flux<String> flux);
Flux<String> fluxPostFilter(Flux<String> flux);
Publisher<String> publisherFindById(long id);
Publisher<String> publisherPreAuthorizeHasRoleFindById(long id);