Support Class Attributes in Annotation Template Processing
Closes gh-15721
This commit is contained in:
parent
820e3f5750
commit
5c20505b0e
|
@ -998,6 +998,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);
|
||||
}
|
||||
|
@ -1376,6 +1385,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)
|
||||
|
|
|
@ -19,9 +19,11 @@ package org.springframework.security.authorization.method;
|
|||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationConfigurationException;
|
||||
|
@ -29,6 +31,8 @@ import org.springframework.core.annotation.MergedAnnotation;
|
|||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
|
||||
import org.springframework.core.annotation.RepeatableContainers;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.GenericConverter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.util.PropertyPlaceholderHelper;
|
||||
|
||||
|
@ -55,6 +59,12 @@ import org.springframework.util.PropertyPlaceholderHelper;
|
|||
*/
|
||||
final class AuthorizationAnnotationUtils {
|
||||
|
||||
private static final DefaultConversionService conversionService = new DefaultConversionService();
|
||||
|
||||
static {
|
||||
conversionService.addConverter(new ClassToStringConverter());
|
||||
}
|
||||
|
||||
static <A extends Annotation> Function<AnnotatedElement, A> withDefaults(Class<A> type,
|
||||
PrePostTemplateDefaults defaults) {
|
||||
Function<MergedAnnotation<A>, A> map = (mergedAnnotation) -> {
|
||||
|
@ -70,7 +80,7 @@ final class AuthorizationAnnotationUtils {
|
|||
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);
|
||||
}
|
||||
AnnotatedElement annotatedElement = (AnnotatedElement) mergedAnnotation.getSource();
|
||||
|
@ -156,4 +166,18 @@ final class AuthorizationAnnotationUtils {
|
|||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue