Skip to content

Commit 1a5f29c

Browse files
Add AuthorizationResult support for AuthorizationManager
Closes gh-14843
1 parent e006507 commit 1a5f29c

File tree

9 files changed

+33
-14
lines changed

9 files changed

+33
-14
lines changed

config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfigurationTests.java

+4
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import org.springframework.security.authorization.AuthorizationDecision;
7676
import org.springframework.security.authorization.AuthorizationEventPublisher;
7777
import org.springframework.security.authorization.AuthorizationManager;
78+
import org.springframework.security.authorization.AuthorizationResult;
7879
import org.springframework.security.authorization.method.AuthorizationAdvisor;
7980
import org.springframework.security.authorization.method.AuthorizationAdvisorProxyFactory;
8081
import org.springframework.security.authorization.method.AuthorizationAdvisorProxyFactory.TargetVisitor;
@@ -110,6 +111,7 @@
110111
import static org.mockito.ArgumentMatchers.any;
111112
import static org.mockito.Mockito.atLeastOnce;
112113
import static org.mockito.Mockito.clearInvocations;
114+
import static org.mockito.Mockito.doCallRealMethod;
113115
import static org.mockito.Mockito.mock;
114116
import static org.mockito.Mockito.never;
115117
import static org.mockito.Mockito.spy;
@@ -1293,6 +1295,8 @@ static class AuthorizationEventPublisherConfig {
12931295

12941296
@Bean
12951297
AuthorizationEventPublisher authorizationEventPublisher() {
1298+
doCallRealMethod().when(this.publisher)
1299+
.publishAuthorizationEvent(any(), any(), any(AuthorizationResult.class));
12961300
return this.publisher;
12971301
}
12981302

config/src/test/java/org/springframework/security/config/annotation/web/configurers/AuthorizeHttpRequestsConfigurerTests.java

+5-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-2024 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.
@@ -42,6 +42,7 @@
4242
import org.springframework.security.authorization.AuthorizationEventPublisher;
4343
import org.springframework.security.authorization.AuthorizationManager;
4444
import org.springframework.security.authorization.AuthorizationObservationContext;
45+
import org.springframework.security.authorization.AuthorizationResult;
4546
import org.springframework.security.config.ObjectPostProcessor;
4647
import org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry;
4748
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -78,6 +79,7 @@
7879
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
7980
import static org.mockito.Mockito.any;
8081
import static org.mockito.Mockito.atLeastOnce;
82+
import static org.mockito.Mockito.doCallRealMethod;
8183
import static org.mockito.Mockito.mock;
8284
import static org.mockito.Mockito.spy;
8385
import static org.mockito.Mockito.verify;
@@ -1241,6 +1243,8 @@ static class AuthorizationEventPublisherConfig {
12411243

12421244
@Bean
12431245
AuthorizationEventPublisher authorizationEventPublisher() {
1246+
doCallRealMethod().when(this.publisher)
1247+
.publishAuthorizationEvent(any(), any(), any(AuthorizationResult.class));
12441248
return this.publisher;
12451249
}
12461250

config/src/test/java/org/springframework/security/config/http/DefaultFilterChainValidatorTests.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -113,6 +113,7 @@ public void validateCheckLoginPageIsntProtectedThrowsIllegalArgumentException()
113113
@Test
114114
public void validateCheckLoginPageAllowsAnonymous() {
115115
given(this.authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(false));
116+
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
116117
this.validator.validate(this.chainAuthorizationFilter);
117118
verify(this.logger).warn("Anonymous access to the login page doesn't appear to be enabled. "
118119
+ "This is almost certainly an error. Please check your configuration allows unauthenticated "

config/src/test/java/org/springframework/security/config/websocket/WebSocketMessageBrokerConfigTests.java

+1
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ public void sendWhenCustomAuthorizationManagerThenAuthorizesAccordingly() {
514514
AuthorizationManager<Message<?>> authorizationManager = this.spring.getContext()
515515
.getBean(AuthorizationManager.class);
516516
given(authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(false));
517+
given(authorizationManager.authorize(any(), any())).willCallRealMethod();
517518
Message<?> message = message("/any");
518519
assertThatExceptionOfType(Exception.class).isThrownBy(send(message))
519520
.withCauseInstanceOf(AccessDeniedException.class);

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

+2-5
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,10 @@ <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T ob
6464
*/
6565
default <T> void publishAuthorizationEvent(Supplier<Authentication> authentication, T object,
6666
AuthorizationResult decision) {
67-
if (decision == null) {
68-
return;
69-
}
70-
if (!(decision instanceof AuthorizationDecision result)) {
67+
if (decision != null && !(decision instanceof AuthorizationDecision)) {
7168
throw new UnsupportedOperationException("Decision must be of type AuthorizationDecision");
7269
}
73-
publishAuthorizationEvent(authentication, object, result);
70+
publishAuthorizationEvent(authentication, object, (AuthorizationDecision) decision);
7471
}
7572

7673
}

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

+6-2
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,24 @@ public T getObject() {
7373
/**
7474
* Get the observed {@link AuthorizationDecision}
7575
* @return the observed {@link AuthorizationDecision}
76+
* @deprecated please use {@link #getAuthorizationResult()} instead
7677
*/
78+
@Deprecated
7779
public AuthorizationDecision getDecision() {
78-
Assert.isInstanceOf(AuthorizationDecision.class,
80+
Assert.isInstanceOf(AuthorizationDecision.class, this.authorizationResult,
7981
"Please call getAuthorizationResult instead. If you must call getDecision, please ensure that the result you provide is of type AuthorizationDecision");
8082
return (AuthorizationDecision) this.authorizationResult;
8183
}
8284

8385
/**
8486
* Set the observed {@link AuthorizationDecision}
8587
* @param decision the observed {@link AuthorizationDecision}
86-
* @deprecated
88+
* @deprecated please use {@link #setAuthorizationResult(AuthorizationResult)} instead
8789
*/
8890
@Deprecated
8991
public void setDecision(AuthorizationDecision decision) {
92+
Assert.isInstanceOf(AuthorizationDecision.class, decision,
93+
"Please call setAuthorizationResult instead. If you must call getDecision, please ensure that the result you provide is of type AuthorizationDecision");
9094
this.decision = decision;
9195
}
9296

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

+2-2
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-2024 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.
@@ -71,7 +71,7 @@ public AuthorizationDecision check(Supplier<Authentication> authentication, T ob
7171
Observation observation = Observation.createNotStarted(this.convention, () -> context, this.registry).start();
7272
try (Observation.Scope scope = observation.openScope()) {
7373
AuthorizationDecision decision = this.delegate.check(wrapped, object);
74-
context.setDecision(decision);
74+
context.setAuthorizationResult(decision);
7575
if (decision != null && !decision.isGranted()) {
7676
observation.error(new AccessDeniedException(
7777
this.messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access Denied")));

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

+2-2
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-2024 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.
@@ -68,7 +68,7 @@ public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, T
6868
.parentObservation(contextView.getOrDefault(ObservationThreadLocalAccessor.KEY, null))
6969
.start();
7070
return this.delegate.check(wrapped, object).doOnSuccess((decision) -> {
71-
context.setDecision(decision);
71+
context.setAuthorizationResult(decision);
7272
if (decision == null || !decision.isGranted()) {
7373
observation.error(new AccessDeniedException("Access Denied"));
7474
}

messaging/src/test/java/org/springframework/security/messaging/access/intercept/AuthorizationChannelInterceptorTests.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -30,6 +30,7 @@
3030
import org.springframework.security.authorization.AuthorizationDecision;
3131
import org.springframework.security.authorization.AuthorizationEventPublisher;
3232
import org.springframework.security.authorization.AuthorizationManager;
33+
import org.springframework.security.authorization.AuthorizationResult;
3334
import org.springframework.security.core.Authentication;
3435
import org.springframework.security.core.context.SecurityContextHolder;
3536

@@ -38,6 +39,7 @@
3839
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
3940
import static org.mockito.ArgumentMatchers.any;
4041
import static org.mockito.BDDMockito.given;
42+
import static org.mockito.Mockito.lenient;
4143
import static org.mockito.Mockito.verify;
4244

4345
/**
@@ -82,12 +84,14 @@ public void constructorWhenAuthorizationManagerNullThenIllegalArgument() {
8284
@Test
8385
public void preSendWhenAllowThenSameMessage() {
8486
given(this.authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(true));
87+
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
8588
assertThat(this.interceptor.preSend(this.message, this.channel)).isSameAs(this.message);
8689
}
8790

8891
@Test
8992
public void preSendWhenDenyThenException() {
9093
given(this.authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(false));
94+
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
9195
assertThatExceptionOfType(AccessDeniedException.class)
9296
.isThrownBy(() -> this.interceptor.preSend(this.message, this.channel));
9397
}
@@ -102,6 +106,10 @@ public void setEventPublisherWhenNullThenException() {
102106
public void preSendWhenAuthorizationEventPublisherThenPublishes() {
103107
this.interceptor.setAuthorizationEventPublisher(this.eventPublisher);
104108
given(this.authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(true));
109+
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
110+
lenient().doCallRealMethod()
111+
.when(this.eventPublisher)
112+
.publishAuthorizationEvent(any(), any(), any(AuthorizationResult.class));
105113
this.interceptor.preSend(this.message, this.channel);
106114
verify(this.eventPublisher).publishAuthorizationEvent(any(), any(), any());
107115
}

0 commit comments

Comments
 (0)