Bläddra i källkod

Merge remote-tracking branch 'origin/6.3.x'

Josh Cummings 11 månader sedan
förälder
incheckning
c0a10b90ba

+ 30 - 0
config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfigurationTests.java

@@ -1009,6 +1009,15 @@ public class PrePostMethodSecurityConfigurationTests {
 		verify(expressionHandler, times(4)).createEvaluationContext(any(Supplier.class), any());
 	}
 
+	// gh-15721
+	@Test
+	@WithMockUser(roles = "uid")
+	public void methodWhenMetaAnnotationPropertiesHasClassProperties() {
+		this.spring.register(MetaAnnotationPlaceholderConfig.class).autowire();
+		MetaAnnotationService service = this.spring.getContext().getBean(MetaAnnotationService.class);
+		assertThat(service.getIdPath("uid")).isEqualTo("uid");
+	}
+
 	private static Consumer<ConfigurableWebApplicationContext> disallowBeanOverriding() {
 		return (context) -> ((AnnotationConfigWebApplicationContext) context).setAllowBeanDefinitionOverriding(false);
 	}
@@ -1403,6 +1412,27 @@ public class PrePostMethodSecurityConfigurationTests {
 			return list;
 		}
 
+		@RestrictedAccess(entityClass = EntityClass.class)
+		String getIdPath(String id) {
+			return id;
+		}
+
+	}
+
+	@Retention(RetentionPolicy.RUNTIME)
+	@PreAuthorize("hasRole({idPath})")
+	@interface RestrictedAccess {
+
+		String idPath() default "#id";
+
+		Class<?> entityClass();
+
+		String[] recipes() default {};
+
+	}
+
+	static class EntityClass {
+
 	}
 
 	@Retention(RetentionPolicy.RUNTIME)

+ 25 - 1
core/src/main/java/org/springframework/security/core/annotation/ExpressionTemplateSecurityAnnotationScanner.java

@@ -20,11 +20,15 @@ import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 
 import org.springframework.core.MethodClassKey;
 import org.springframework.core.annotation.MergedAnnotation;
+import org.springframework.core.convert.TypeDescriptor;
+import org.springframework.core.convert.converter.GenericConverter;
 import org.springframework.core.convert.support.DefaultConversionService;
 import org.springframework.util.Assert;
 import org.springframework.util.PropertyPlaceholderHelper;
@@ -64,6 +68,12 @@ import org.springframework.util.PropertyPlaceholderHelper;
 final class ExpressionTemplateSecurityAnnotationScanner<A extends Annotation>
 		extends AbstractSecurityAnnotationScanner<A> {
 
+	private static final DefaultConversionService conversionService = new DefaultConversionService();
+
+	static {
+		conversionService.addConverter(new ClassToStringConverter());
+	}
+
 	private final Class<A> type;
 
 	private final UniqueSecurityAnnotationScanner<A> unique;
@@ -120,7 +130,7 @@ final class ExpressionTemplateSecurityAnnotationScanner<A extends Annotation>
 			String key = property.getKey();
 			Object value = property.getValue();
 			String asString = (value instanceof String) ? (String) value
-					: DefaultConversionService.getSharedInstance().convert(value, String.class);
+					: conversionService.convert(value, String.class);
 			stringProperties.put(key, asString);
 		}
 		Map<String, Object> annotationProperties = mergedAnnotation.asMap();
@@ -136,4 +146,18 @@ final class ExpressionTemplateSecurityAnnotationScanner<A extends Annotation>
 		return MergedAnnotation.of(annotatedElement, this.type, properties);
 	}
 
+	static class ClassToStringConverter implements GenericConverter {
+
+		@Override
+		public Set<ConvertiblePair> getConvertibleTypes() {
+			return Collections.singleton(new ConvertiblePair(Class.class, String.class));
+		}
+
+		@Override
+		public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
+			return (source != null) ? source.toString() : null;
+		}
+
+	}
+
 }