Skip to content

Commit 02cca6f

Browse files
committed
Polish AuthorizationAdvisorProxyFactory advisor configuration
Closes gh-15497
1 parent f90394d commit 02cca6f

File tree

3 files changed

+62
-14
lines changed

3 files changed

+62
-14
lines changed

config/src/main/java/org/springframework/security/config/annotation/method/configuration/AuthorizationProxyConfiguration.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,18 @@ static AuthorizationAdvisorProxyFactory authorizationProxyFactory(ObjectProvider
4141
ObjectProvider<Customizer<AuthorizationAdvisorProxyFactory>> customizers) {
4242
List<AuthorizationAdvisor> advisors = new ArrayList<>();
4343
provider.forEach(advisors::add);
44-
AuthorizationAdvisorProxyFactory factory = AuthorizationAdvisorProxyFactory.withDefaults();
44+
AuthorizationAdvisorProxyFactory factory = new AuthorizationAdvisorProxyFactory(advisors);
4545
customizers.forEach((c) -> c.customize(factory));
46-
factory.setAdvisors(advisors);
4746
return factory;
4847
}
4948

5049
@Bean
5150
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
52-
static MethodInterceptor authorizeReturnObjectMethodInterceptor(ObjectProvider<AuthorizationAdvisor> provider,
51+
static MethodInterceptor authorizeReturnObjectMethodInterceptor(
5352
AuthorizationAdvisorProxyFactory authorizationProxyFactory) {
5453
AuthorizeReturnObjectMethodInterceptor interceptor = new AuthorizeReturnObjectMethodInterceptor(
5554
authorizationProxyFactory);
56-
List<AuthorizationAdvisor> advisors = new ArrayList<>();
57-
provider.forEach(advisors::add);
58-
advisors.add(interceptor);
59-
authorizationProxyFactory.setAdvisors(advisors);
55+
authorizationProxyFactory.addAdvisors(interceptor);
6056
return interceptor;
6157
}
6258

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

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,28 @@ public final class AuthorizationAdvisorProxyFactory
8686
private static final TargetVisitor DEFAULT_VISITOR_SKIP_VALUE_TYPES = TargetVisitor.of(new ClassVisitor(),
8787
new IgnoreValueTypeVisitor(), DEFAULT_VISITOR);
8888

89-
private List<AuthorizationAdvisor> advisors;
89+
private List<AuthorizationAdvisor> advisors = new ArrayList<>();
9090

9191
private TargetVisitor visitor = DEFAULT_VISITOR;
9292

93-
private AuthorizationAdvisorProxyFactory(List<AuthorizationAdvisor> advisors) {
94-
this.advisors = new ArrayList<>(advisors);
95-
this.advisors.add(new AuthorizeReturnObjectMethodInterceptor(this));
96-
setAdvisors(this.advisors);
93+
/**
94+
* Construct an {@link AuthorizationAdvisorProxyFactory} with the following advisors
95+
* @param advisors the list of advisors to wrap around proxied objects
96+
* @since 6.4
97+
*/
98+
public AuthorizationAdvisorProxyFactory(List<AuthorizationAdvisor> advisors) {
99+
this.advisors.addAll(advisors);
100+
AnnotationAwareOrderComparator.sort(this.advisors);
101+
}
102+
103+
/**
104+
* Construct an {@link AuthorizationAdvisorProxyFactory} with the following advisors
105+
* @param advisors the list of advisors to wrap around proxied objects
106+
* @since 6.4
107+
*/
108+
public AuthorizationAdvisorProxyFactory(AuthorizationAdvisor... advisors) {
109+
this.advisors.addAll(List.of(advisors));
110+
AnnotationAwareOrderComparator.sort(this.advisors);
97111
}
98112

99113
/**
@@ -108,7 +122,9 @@ public static AuthorizationAdvisorProxyFactory withDefaults() {
108122
advisors.add(AuthorizationManagerAfterMethodInterceptor.postAuthorize());
109123
advisors.add(new PreFilterAuthorizationMethodInterceptor());
110124
advisors.add(new PostFilterAuthorizationMethodInterceptor());
111-
return new AuthorizationAdvisorProxyFactory(advisors);
125+
AuthorizationAdvisorProxyFactory proxyFactory = new AuthorizationAdvisorProxyFactory(advisors);
126+
proxyFactory.addAdvisors(new AuthorizeReturnObjectMethodInterceptor(proxyFactory));
127+
return proxyFactory;
112128
}
113129

114130
/**
@@ -123,7 +139,9 @@ public static AuthorizationAdvisorProxyFactory withReactiveDefaults() {
123139
advisors.add(AuthorizationManagerAfterReactiveMethodInterceptor.postAuthorize());
124140
advisors.add(new PreFilterAuthorizationReactiveMethodInterceptor());
125141
advisors.add(new PostFilterAuthorizationReactiveMethodInterceptor());
126-
return new AuthorizationAdvisorProxyFactory(advisors);
142+
AuthorizationAdvisorProxyFactory proxyFactory = new AuthorizationAdvisorProxyFactory(advisors);
143+
proxyFactory.addAdvisors(new AuthorizeReturnObjectMethodInterceptor(proxyFactory));
144+
return proxyFactory;
127145
}
128146

129147
/**
@@ -161,13 +179,21 @@ public Object proxy(Object target) {
161179
return factory.getProxy();
162180
}
163181

182+
public void addAdvisors(AuthorizationAdvisor... advisors) {
183+
this.advisors.addAll(List.of(advisors));
184+
AnnotationAwareOrderComparator.sort(this.advisors);
185+
}
186+
164187
/**
165188
* Add advisors that should be included to each proxy created.
166189
*
167190
* <p>
168191
* All advisors are re-sorted by their advisor order.
169192
* @param advisors the advisors to add
193+
* @deprecated Either use the constructor to provide a complete set of advisors or use
194+
* {@link #addAdvisors(AuthorizationAdvisor...)} to add to the existing list
170195
*/
196+
@Deprecated
171197
public void setAdvisors(AuthorizationAdvisor... advisors) {
172198
this.advisors = new ArrayList<>(List.of(advisors));
173199
AnnotationAwareOrderComparator.sort(this.advisors);
@@ -179,7 +205,10 @@ public void setAdvisors(AuthorizationAdvisor... advisors) {
179205
* <p>
180206
* All advisors are re-sorted by their advisor order.
181207
* @param advisors the advisors to add
208+
* @deprecated Either use the constructor to provide a complete set of advisors or use
209+
* {@link #addAdvisors(AuthorizationAdvisor...)} to add to the existing list
182210
*/
211+
@Deprecated
183212
public void setAdvisors(Collection<AuthorizationAdvisor> advisors) {
184213
this.advisors = new ArrayList<>(advisors);
185214
AnnotationAwareOrderComparator.sort(this.advisors);

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,29 @@ public void setAdvisorsWhenProxyThenVisits() {
319319
verify(advisor, atLeastOnce()).getPointcut();
320320
}
321321

322+
@Test
323+
public void addAdvisorsWhenProxyThenVisits() {
324+
AuthorizationAdvisor advisor = mock(AuthorizationAdvisor.class);
325+
given(advisor.getAdvice()).willReturn(advisor);
326+
given(advisor.getPointcut()).willReturn(Pointcut.TRUE);
327+
AuthorizationAdvisorProxyFactory factory = AuthorizationAdvisorProxyFactory.withDefaults();
328+
factory.addAdvisors(advisor);
329+
Flight flight = proxy(factory, this.flight);
330+
flight.getAltitude();
331+
verify(advisor, atLeastOnce()).getPointcut();
332+
}
333+
334+
@Test
335+
public void constructWhenProxyThenVisitsAdvisors() {
336+
AuthorizationAdvisor advisor = mock(AuthorizationAdvisor.class);
337+
given(advisor.getAdvice()).willReturn(advisor);
338+
given(advisor.getPointcut()).willReturn(Pointcut.TRUE);
339+
AuthorizationAdvisorProxyFactory factory = new AuthorizationAdvisorProxyFactory(advisor);
340+
Flight flight = proxy(factory, this.flight);
341+
flight.getAltitude();
342+
verify(advisor, atLeastOnce()).getPointcut();
343+
}
344+
322345
@Test
323346
public void setTargetVisitorThenUses() {
324347
TargetVisitor visitor = mock(TargetVisitor.class);

0 commit comments

Comments
 (0)