Skip to content

Commit a191f9f

Browse files
committed
ReactiveAuthorizationManager replace deprecated #check calls with #authorize
Closes gh-16936 Signed-off-by: Evgeniy Cheban <[email protected]>
1 parent 863e016 commit a191f9f

File tree

7 files changed

+61
-17
lines changed

7 files changed

+61
-17
lines changed

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

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -62,6 +62,17 @@ public ObservationReactiveAuthorizationManager(ObservationRegistry registry,
6262
@Deprecated
6363
@Override
6464
public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, T object) {
65+
return authorize(authentication, object).flatMap((result) -> {
66+
if (result instanceof AuthorizationDecision decision) {
67+
return Mono.just(decision);
68+
}
69+
return Mono.error(new IllegalArgumentException(
70+
"Please call #authorize or ensure that the returned result is of type Mono<AuthorizationDecision>"));
71+
});
72+
}
73+
74+
@Override
75+
public Mono<AuthorizationResult> authorize(Mono<Authentication> authentication, T object) {
6576
AuthorizationObservationContext<T> context = new AuthorizationObservationContext<>(object);
6677
Mono<Authentication> wrapped = authentication.map((auth) -> {
6778
context.setAuthentication(auth);
@@ -71,9 +82,9 @@ public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, T
7182
Observation observation = Observation.createNotStarted(this.convention, () -> context, this.registry)
7283
.parentObservation(contextView.getOrDefault(ObservationThreadLocalAccessor.KEY, null))
7384
.start();
74-
return this.delegate.check(wrapped, object).doOnSuccess((decision) -> {
75-
context.setAuthorizationResult(decision);
76-
if (decision == null || !decision.isGranted()) {
85+
return this.delegate.authorize(wrapped, object).doOnSuccess((result) -> {
86+
context.setAuthorizationResult(result);
87+
if (result == null || !result.isGranted()) {
7788
observation.error(new AccessDeniedException("Access Denied"));
7889
}
7990
observation.stop();

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -50,8 +50,8 @@ public interface ReactiveAuthorizationManager<T> {
5050
*/
5151
default Mono<Void> verify(Mono<Authentication> authentication, T object) {
5252
// @formatter:off
53-
return check(authentication, object)
54-
.filter(AuthorizationDecision::isGranted)
53+
return authorize(authentication, object)
54+
.filter(AuthorizationResult::isGranted)
5555
.switchIfEmpty(Mono.defer(() -> Mono.error(new AccessDeniedException("Access Denied"))))
5656
.flatMap((decision) -> Mono.empty());
5757
// @formatter:on

core/src/test/java/org/springframework/security/authorization/ObservationReactiveAuthorizationManagerTests.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -70,6 +70,7 @@ void setup() {
7070
void verifyWhenDefaultsThenObserves() {
7171
given(this.handler.supportsContext(any())).willReturn(true);
7272
given(this.authorizationManager.check(any(), any())).willReturn(Mono.just(this.grant));
73+
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
7374
this.tested.verify(this.token, this.object).block();
7475
ArgumentCaptor<Observation.Context> captor = ArgumentCaptor.forClass(Observation.Context.class);
7576
verify(this.handler).onStart(captor.capture());
@@ -86,6 +87,7 @@ void verifyWhenDefaultsThenObserves() {
8687
void verifyWhenErrorsThenObserves() {
8788
given(this.handler.supportsContext(any())).willReturn(true);
8889
given(this.authorizationManager.check(any(), any())).willReturn(Mono.just(this.deny));
90+
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
8991
assertThatExceptionOfType(AccessDeniedException.class)
9092
.isThrownBy(() -> this.tested.verify(this.token, this.object).block());
9193
ArgumentCaptor<Observation.Context> captor = ArgumentCaptor.forClass(Observation.Context.class);
@@ -106,6 +108,7 @@ void verifyWhenLooksUpAuthenticationThenObserves() {
106108
((Mono<Authentication>) invocation.getArgument(0)).block();
107109
return Mono.just(this.grant);
108110
});
111+
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
109112
this.tested.verify(this.token, this.object).block();
110113
ArgumentCaptor<Observation.Context> captor = ArgumentCaptor.forClass(Observation.Context.class);
111114
verify(this.handler).onStart(captor.capture());

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

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
2323
import reactor.core.publisher.Mono;
2424

2525
import org.springframework.security.authorization.AuthorizationDecision;
26+
import org.springframework.security.authorization.AuthorizationResult;
2627
import org.springframework.security.authorization.ReactiveAuthorizationManager;
2728
import org.springframework.security.core.Authentication;
2829
import org.springframework.security.rsocket.api.PayloadExchange;
@@ -51,18 +52,29 @@ private PayloadExchangeMatcherReactiveAuthorizationManager(
5152
}
5253

5354
/**
54-
* @deprecated please use {@link #authorize(Mono, Object)} instead
55+
* @deprecated please use {@link #authorize(Mono, PayloadExchange)} instead
5556
*/
5657
@Deprecated
5758
@Override
5859
public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, PayloadExchange exchange) {
60+
return authorize(authentication, exchange).flatMap((result) -> {
61+
if (result instanceof AuthorizationDecision decision) {
62+
return Mono.just(decision);
63+
}
64+
return Mono.error(new IllegalArgumentException(
65+
"Please call #authorize or ensure that the returned result is of type Mono<AuthorizationDecision>"));
66+
});
67+
}
68+
69+
@Override
70+
public Mono<AuthorizationResult> authorize(Mono<Authentication> authentication, PayloadExchange exchange) {
5971
return Flux.fromIterable(this.mappings)
6072
.concatMap((mapping) -> mapping.getMatcher()
6173
.matches(exchange)
6274
.filter(PayloadExchangeMatcher.MatchResult::isMatch)
6375
.map(MatchResult::getVariables)
6476
.flatMap((variables) -> mapping.getEntry()
65-
.check(authentication, new PayloadExchangeAuthorizationContext(exchange, variables))))
77+
.authorize(authentication, new PayloadExchangeAuthorizationContext(exchange, variables))))
6678
.next()
6779
.switchIfEmpty(Mono.fromCallable(() -> new AuthorizationDecision(false)));
6880
}

rsocket/src/test/java/org/springframework/security/rsocket/authorization/PayloadExchangeMatcherReactiveAuthorizationManagerTests.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -53,6 +53,7 @@ public class PayloadExchangeMatcherReactiveAuthorizationManagerTests {
5353
public void checkWhenGrantedThenGranted() {
5454
AuthorizationDecision expected = new AuthorizationDecision(true);
5555
given(this.authz.check(any(), any())).willReturn(Mono.just(expected));
56+
given(this.authz.authorize(any(), any())).willCallRealMethod();
5657
PayloadExchangeMatcherReactiveAuthorizationManager manager = PayloadExchangeMatcherReactiveAuthorizationManager
5758
.builder()
5859
.add(new PayloadExchangeMatcherEntry<>(PayloadExchangeMatchers.anyExchange(), this.authz))
@@ -64,6 +65,7 @@ public void checkWhenGrantedThenGranted() {
6465
public void checkWhenDeniedThenDenied() {
6566
AuthorizationDecision expected = new AuthorizationDecision(false);
6667
given(this.authz.check(any(), any())).willReturn(Mono.just(expected));
68+
given(this.authz.authorize(any(), any())).willCallRealMethod();
6769
PayloadExchangeMatcherReactiveAuthorizationManager manager = PayloadExchangeMatcherReactiveAuthorizationManager
6870
.builder()
6971
.add(new PayloadExchangeMatcherEntry<>(PayloadExchangeMatchers.anyExchange(), this.authz))
@@ -75,6 +77,7 @@ public void checkWhenDeniedThenDenied() {
7577
public void checkWhenFirstMatchThenSecondUsed() {
7678
AuthorizationDecision expected = new AuthorizationDecision(true);
7779
given(this.authz.check(any(), any())).willReturn(Mono.just(expected));
80+
given(this.authz.authorize(any(), any())).willCallRealMethod();
7881
PayloadExchangeMatcherReactiveAuthorizationManager manager = PayloadExchangeMatcherReactiveAuthorizationManager
7982
.builder()
8083
.add(new PayloadExchangeMatcherEntry<>(PayloadExchangeMatchers.anyExchange(), this.authz))
@@ -87,6 +90,7 @@ public void checkWhenFirstMatchThenSecondUsed() {
8790
public void checkWhenSecondMatchThenSecondUsed() {
8891
AuthorizationDecision expected = new AuthorizationDecision(true);
8992
given(this.authz2.check(any(), any())).willReturn(Mono.just(expected));
93+
given(this.authz2.authorize(any(), any())).willCallRealMethod();
9094
PayloadExchangeMatcherReactiveAuthorizationManager manager = PayloadExchangeMatcherReactiveAuthorizationManager
9195
.builder()
9296
.add(new PayloadExchangeMatcherEntry<>((e) -> PayloadExchangeMatcher.MatchResult.notMatch(), this.authz))

web/src/main/java/org/springframework/security/web/server/authorization/DelegatingReactiveAuthorizationManager.java

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
2626

2727
import org.springframework.core.log.LogMessage;
2828
import org.springframework.security.authorization.AuthorizationDecision;
29+
import org.springframework.security.authorization.AuthorizationResult;
2930
import org.springframework.security.authorization.ReactiveAuthorizationManager;
3031
import org.springframework.security.core.Authentication;
3132
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher.MatchResult;
@@ -49,11 +50,22 @@ private DelegatingReactiveAuthorizationManager(
4950
}
5051

5152
/**
52-
* @deprecated please use {@link #authorize(Mono, Object)} instead
53+
* @deprecated please use {@link #authorize(Mono, ServerWebExchange)} instead
5354
*/
5455
@Deprecated
5556
@Override
5657
public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, ServerWebExchange exchange) {
58+
return authorize(authentication, exchange).flatMap((result) -> {
59+
if (result instanceof AuthorizationDecision decision) {
60+
return Mono.just(decision);
61+
}
62+
return Mono.error(new IllegalArgumentException(
63+
"Please call #authorize or ensure that the returned result is of type Mono<AuthorizationDecision>"));
64+
});
65+
}
66+
67+
@Override
68+
public Mono<AuthorizationResult> authorize(Mono<Authentication> authentication, ServerWebExchange exchange) {
5769
return Flux.fromIterable(this.mappings)
5870
.concatMap((mapping) -> mapping.getMatcher()
5971
.matches(exchange)
@@ -63,10 +75,10 @@ public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, Se
6375
logger.debug(LogMessage.of(() -> "Checking authorization on '"
6476
+ exchange.getRequest().getPath().pathWithinApplication() + "' using "
6577
+ mapping.getEntry()));
66-
return mapping.getEntry().check(authentication, new AuthorizationContext(exchange, variables));
78+
return mapping.getEntry().authorize(authentication, new AuthorizationContext(exchange, variables));
6779
}))
6880
.next()
69-
.defaultIfEmpty(new AuthorizationDecision(false));
81+
.switchIfEmpty(Mono.fromCallable(() -> new AuthorizationDecision(false)));
7082
}
7183

7284
public static DelegatingReactiveAuthorizationManager.Builder builder() {

web/src/test/java/org/springframework/security/web/server/authorization/DelegatingReactiveAuthorizationManagerTests.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -81,6 +81,7 @@ public void checkWhenFirstMatchesThenNoMoreMatchersAndNoMoreDelegatesInvoked() {
8181
given(this.match1.matches(any())).willReturn(ServerWebExchangeMatcher.MatchResult.match());
8282
given(this.delegate1.check(eq(this.authentication), any(AuthorizationContext.class)))
8383
.willReturn(Mono.just(this.decision));
84+
given(this.delegate1.authorize(eq(this.authentication), any(AuthorizationContext.class))).willCallRealMethod();
8485
assertThat(this.manager.check(this.authentication, this.exchange).block()).isEqualTo(this.decision);
8586
verifyNoMoreInteractions(this.match2, this.delegate2);
8687
}
@@ -91,6 +92,7 @@ public void checkWhenSecondMatchesThenNoMoreMatchersAndNoMoreDelegatesInvoked()
9192
given(this.match2.matches(any())).willReturn(ServerWebExchangeMatcher.MatchResult.match());
9293
given(this.delegate2.check(eq(this.authentication), any(AuthorizationContext.class)))
9394
.willReturn(Mono.just(this.decision));
95+
given(this.delegate2.authorize(eq(this.authentication), any(AuthorizationContext.class))).willCallRealMethod();
9496
assertThat(this.manager.check(this.authentication, this.exchange).block()).isEqualTo(this.decision);
9597
verifyNoMoreInteractions(this.delegate1);
9698
}

0 commit comments

Comments
 (0)