Przeglądaj źródła

Sort Default Advisors and Added Advisors

This commit ensures that the default advisors and added advisors
are sorted in the event that this component is not being published
as a Spring bean.

Issue gh-16819
Josh Cummings 4 miesięcy temu
rodzic
commit
456604ab45

+ 9 - 5
core/src/main/java/org/springframework/security/authorization/method/AuthorizationAdvisorProxyFactory.java

@@ -109,7 +109,9 @@ public final class AuthorizationAdvisorProxyFactory
 		advisors.add(AuthorizationManagerAfterMethodInterceptor.postAuthorize());
 		advisors.add(AuthorizationManagerAfterMethodInterceptor.postAuthorize());
 		advisors.add(new PreFilterAuthorizationMethodInterceptor());
 		advisors.add(new PreFilterAuthorizationMethodInterceptor());
 		advisors.add(new PostFilterAuthorizationMethodInterceptor());
 		advisors.add(new PostFilterAuthorizationMethodInterceptor());
-		return new AuthorizationAdvisorProxyFactory(advisors);
+		AuthorizationAdvisorProxyFactory factory = new AuthorizationAdvisorProxyFactory(advisors);
+		AnnotationAwareOrderComparator.sort(factory.advisors);
+		return factory;
 	}
 	}
 
 
 	/**
 	/**
@@ -124,7 +126,9 @@ public final class AuthorizationAdvisorProxyFactory
 		advisors.add(AuthorizationManagerAfterReactiveMethodInterceptor.postAuthorize());
 		advisors.add(AuthorizationManagerAfterReactiveMethodInterceptor.postAuthorize());
 		advisors.add(new PreFilterAuthorizationReactiveMethodInterceptor());
 		advisors.add(new PreFilterAuthorizationReactiveMethodInterceptor());
 		advisors.add(new PostFilterAuthorizationReactiveMethodInterceptor());
 		advisors.add(new PostFilterAuthorizationReactiveMethodInterceptor());
-		return new AuthorizationAdvisorProxyFactory(advisors);
+		AuthorizationAdvisorProxyFactory factory = new AuthorizationAdvisorProxyFactory(advisors);
+		AnnotationAwareOrderComparator.sort(factory.advisors);
+		return factory;
 	}
 	}
 
 
 	@Override
 	@Override
@@ -160,9 +164,9 @@ public final class AuthorizationAdvisorProxyFactory
 			return proxied;
 			return proxied;
 		}
 		}
 		ProxyFactory factory = new ProxyFactory(target);
 		ProxyFactory factory = new ProxyFactory(target);
-		for (Advisor advisor : this.advisors) {
-			factory.addAdvisors(advisor);
-		}
+		List<Advisor> advisors = new ArrayList<>(this.advisors);
+		AnnotationAwareOrderComparator.sort(advisors);
+		factory.addAdvisors(advisors);
 		factory.setProxyTargetClass(!Modifier.isFinal(target.getClass().getModifiers()));
 		factory.setProxyTargetClass(!Modifier.isFinal(target.getClass().getModifiers()));
 		return factory.getProxy();
 		return factory.getProxy();
 	}
 	}

+ 28 - 1
core/src/test/java/org/springframework/security/authorization/AuthorizationAdvisorProxyFactoryTests.java

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2002-2024 the original author or authors.
+ * Copyright 2002-2025 the original author or authors.
  *
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ import org.jetbrains.annotations.NotNull;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
 
 
 import org.springframework.aop.Pointcut;
 import org.springframework.aop.Pointcut;
+import org.springframework.core.annotation.AnnotationAwareOrderComparator;
 import org.springframework.security.access.AccessDeniedException;
 import org.springframework.security.access.AccessDeniedException;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.authentication.TestAuthentication;
 import org.springframework.security.authentication.TestAuthentication;
@@ -336,6 +337,32 @@ public class AuthorizationAdvisorProxyFactoryTests {
 		assertThat(factory.proxy(35)).isEqualTo(35);
 		assertThat(factory.proxy(35)).isEqualTo(35);
 	}
 	}
 
 
+	// gh-16819
+	@Test
+	void advisorsWhenWithDefaultsThenAreSorted() {
+		AuthorizationAdvisorProxyFactory proxyFactory = AuthorizationAdvisorProxyFactory.withDefaults();
+		AnnotationAwareOrderComparator comparator = AnnotationAwareOrderComparator.INSTANCE;
+		AuthorizationAdvisor previous = null;
+		for (AuthorizationAdvisor advisor : proxyFactory) {
+			boolean ordered = previous == null || comparator.compare(previous, advisor) < 0;
+			assertThat(ordered).isTrue();
+			previous = advisor;
+		}
+	}
+
+	// gh-16819
+	@Test
+	void advisorsWhenWithReactiveDefaultsThenAreSorted() {
+		AuthorizationAdvisorProxyFactory proxyFactory = AuthorizationAdvisorProxyFactory.withReactiveDefaults();
+		AnnotationAwareOrderComparator comparator = AnnotationAwareOrderComparator.INSTANCE;
+		AuthorizationAdvisor previous = null;
+		for (AuthorizationAdvisor advisor : proxyFactory) {
+			boolean ordered = previous == null || comparator.compare(previous, advisor) < 0;
+			assertThat(ordered).isTrue();
+			previous = advisor;
+		}
+	}
+
 	private Authentication authenticated(String user, String... authorities) {
 	private Authentication authenticated(String user, String... authorities) {
 		return TestAuthentication.authenticated(TestAuthentication.withUsername(user).authorities(authorities).build());
 		return TestAuthentication.authenticated(TestAuthentication.withUsername(user).authorities(authorities).build());
 	}
 	}