Skip to content

Commit b864be9

Browse files
committed
Update to Reactor 2025.0.0-SNAPSHOT
To prepare for the release we should update to Reactor 2025.0.0-SNAPSHOT to fix any issues that are present. Closes gh-18041
1 parent 4b6c9cc commit b864be9

18 files changed

Lines changed: 43 additions & 20 deletions

File tree

core/src/main/java/org/springframework/security/authentication/ott/reactive/InMemoryReactiveOneTimeTokenService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public Mono<OneTimeToken> generate(GenerateOneTimeTokenRequest request) {
4343
}
4444

4545
@Override
46+
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1290
4647
public Mono<OneTimeToken> consume(OneTimeTokenAuthenticationToken authenticationToken) {
4748
return Mono.just(authenticationToken).mapNotNull(this.oneTimeTokenService::consume);
4849
}

core/src/main/java/org/springframework/security/authorization/ObservationReactiveAuthorizationManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,10 @@ public ObservationReactiveAuthorizationManager(ObservationRegistry registry,
5858
}
5959

6060
@Override
61+
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1290
6162
public Mono<AuthorizationResult> authorize(Mono<Authentication> authentication, T object) {
6263
AuthorizationObservationContext<T> context = new AuthorizationObservationContext<>(object);
63-
Mono<Authentication> wrapped = authentication.map((auth) -> {
64+
Mono<Authentication> wrapped = authentication.mapNotNull((auth) -> {
6465
context.setAuthentication(auth);
6566
return context.getAuthentication();
6667
});

core/src/main/java/org/springframework/security/authorization/method/AuthorizationAdvisorProxyFactory.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,12 +588,14 @@ private static class ReactiveTypeVisitor implements TargetVisitor {
588588
return null;
589589
}
590590

591+
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1290
591592
private Mono<?> proxyMono(AuthorizationProxyFactory proxyFactory, Mono<?> mono) {
592-
return mono.map(proxyFactory::proxy);
593+
return mono.mapNotNull(proxyFactory::proxy);
593594
}
594595

596+
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1290
595597
private Flux<?> proxyFlux(AuthorizationProxyFactory proxyFactory, Flux<?> flux) {
596-
return flux.map(proxyFactory::proxy);
598+
return flux.mapNotNull(proxyFactory::proxy);
597599
}
598600

599601
}

core/src/main/java/org/springframework/security/authorization/method/AuthorizationManagerAfterReactiveMethodInterceptor.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ public Object invoke(MethodInvocation mi) throws Throwable {
120120
+ "(for example, a Mono or Flux) or the function must be a Kotlin coroutine "
121121
+ "in order to support Reactor Context");
122122
Mono<Authentication> authentication = ReactiveAuthenticationUtils.getAuthentication();
123+
@SuppressWarnings("NullAway") // Dataflow analysis limitation
123124
Function<Signal<?>, Mono<?>> postAuthorize = (signal) -> {
124125
if (signal.isOnComplete()) {
125126
return Mono.empty();
@@ -130,12 +131,16 @@ public Object invoke(MethodInvocation mi) throws Throwable {
130131
if (signal.getThrowable() instanceof AuthorizationDeniedException denied) {
131132
return postProcess(denied, mi);
132133
}
134+
// getThrowable must be non-null because hasError() is true
133135
return Mono.error(signal.getThrowable());
134136
};
135137
ReactiveAdapter adapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(type);
136138
if (hasFlowReturnType) {
137139
if (isSuspendingFunction) {
138140
Publisher<?> publisher = ReactiveMethodInvocationUtils.proceed(mi);
141+
if (publisher == null) {
142+
return Flux.empty();
143+
}
139144
return Flux.from(publisher).materialize().flatMap(postAuthorize);
140145
}
141146
else {
@@ -148,6 +153,9 @@ public Object invoke(MethodInvocation mi) throws Throwable {
148153
}
149154
}
150155
Publisher<?> publisher = ReactiveMethodInvocationUtils.proceed(mi);
156+
if (publisher == null) {
157+
return Flux.empty();
158+
}
151159
if (isMultiValue(type, adapter)) {
152160
Flux<?> flux = Flux.from(publisher).materialize().flatMap(postAuthorize);
153161
return (adapter != null) ? adapter.fromPublisher(flux) : flux;
@@ -173,7 +181,7 @@ private Mono<Object> postAuthorize(Mono<Authentication> authentication, MethodIn
173181

174182
private Mono<Object> postProcess(AuthorizationResult decision, MethodInvocationResult methodInvocationResult) {
175183
if (decision.isGranted()) {
176-
return Mono.just(methodInvocationResult.getResult());
184+
return Mono.justOrEmpty(methodInvocationResult.getResult());
177185
}
178186
return Mono.fromSupplier(() -> {
179187
if (this.authorizationManager instanceof MethodAuthorizationDeniedHandler handler) {

core/src/main/java/org/springframework/security/authorization/method/ReactiveAuthenticationUtils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ final class ReactiveAuthenticationUtils {
3535
private static final Authentication ANONYMOUS = new AnonymousAuthenticationToken("key", "anonymous",
3636
AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"));
3737

38+
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1290
3839
static Mono<Authentication> getAuthentication() {
3940
return ReactiveSecurityContextHolder.getContext()
40-
.map(SecurityContext::getAuthentication)
41+
.mapNotNull(SecurityContext::getAuthentication)
4142
.defaultIfEmpty(ANONYMOUS);
4243
}
4344

core/src/main/java/org/springframework/security/authorization/method/ReactiveMethodInvocationUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
*/
2929
final class ReactiveMethodInvocationUtils {
3030

31-
static <T> @Nullable T proceed(MethodInvocation mi) {
31+
static @Nullable <T> T proceed(MethodInvocation mi) {
3232
try {
3333
return (T) mi.proceed();
3434
}

core/src/main/java/org/springframework/security/core/session/InMemoryReactiveSessionRegistry.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ public InMemoryReactiveSessionRegistry(ConcurrentMap<Object, Set<String>> sessio
5050
}
5151

5252
@Override
53+
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1290
5354
public Flux<ReactiveSessionInformation> getAllSessions(Object principal) {
5455
return Flux.fromIterable(this.sessionIdsByPrincipal.getOrDefault(principal, Collections.emptySet()))
55-
.map(this.sessionById::get);
56+
.mapNotNull(this.sessionById::get);
5657
}
5758

5859
@Override

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ commons-collections = "commons-collections:commons-collections:3.2.2"
3030
io-micrometer-context-propagation = "io.micrometer:context-propagation:1.1.3"
3131
io-micrometer-micrometer-observation = "io.micrometer:micrometer-observation:1.14.11"
3232
io-mockk = "io.mockk:mockk:1.14.6"
33-
io-projectreactor-reactor-bom = "io.projectreactor:reactor-bom:2025.0.0-M7"
33+
io-projectreactor-reactor-bom = "io.projectreactor:reactor-bom:2025.0.0-SNAPSHOT"
3434
io-rsocket-rsocket-bom = { module = "io.rsocket:rsocket-bom", version.ref = "io-rsocket" }
3535
io-spring-javaformat-spring-javaformat-checkstyle = { module = "io.spring.javaformat:spring-javaformat-checkstyle", version.ref = "io-spring-javaformat" }
3636
io-spring-javaformat-spring-javaformat-gradle-plugin = { module = "io.spring.javaformat:spring-javaformat-gradle-plugin", version.ref = "io-spring-javaformat" }

messaging/src/main/java/org/springframework/security/messaging/handler/invocation/reactive/AuthenticationPrincipalArgumentResolver.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,12 @@ public boolean supportsParameter(MethodParameter parameter) {
138138
}
139139

140140
@Override
141+
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1290
141142
public Mono<Object> resolveArgument(MethodParameter parameter, Message<?> message) {
142143
ReactiveAdapter adapter = this.adapterRegistry.getAdapter(parameter.getParameterType());
143144
// @formatter:off
144145
return ReactiveSecurityContextHolder.getContext()
145-
.map(SecurityContext::getAuthentication)
146+
.mapNotNull(SecurityContext::getAuthentication)
146147
.flatMap((a) -> {
147148
Object p = resolvePrincipal(parameter, a.getPrincipal());
148149
Mono<Object> principal = Mono.justOrEmpty(p);

rsocket/src/main/java/org/springframework/security/rsocket/authorization/AuthorizationPayloadInterceptor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ public void setOrder(int order) {
5555
}
5656

5757
@Override
58+
@SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1290
5859
public Mono<Void> intercept(PayloadExchange exchange, PayloadInterceptorChain chain) {
5960
return ReactiveSecurityContextHolder.getContext()
60-
.filter((c) -> c.getAuthentication() != null)
61-
.map(SecurityContext::getAuthentication)
61+
.mapNotNull(SecurityContext::getAuthentication)
6262
.switchIfEmpty(Mono.error(() -> new AuthenticationCredentialsNotFoundException(
6363
"An Authentication (possibly AnonymousAuthenticationToken) is required.")))
6464
.as((authentication) -> this.authorizationManager.verify(authentication, exchange))

0 commit comments

Comments
 (0)