Skip to content

Commit b75600f

Browse files
committed
Use custom conversionService
Closes gh-15721
1 parent ff41521 commit b75600f

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,15 @@ public void adviseWhenPrePostEnabledThenEachInterceptorRunsExactlyOnce() {
998998
verify(expressionHandler, times(4)).createEvaluationContext(any(Supplier.class), any());
999999
}
10001000

1001+
// gh-15721
1002+
@Test
1003+
@WithMockUser(roles = "uid")
1004+
public void methodWhenMetaAnnotationPropertiesHasClassProperties() {
1005+
this.spring.register(MetaAnnotationPlaceholderConfig.class).autowire();
1006+
MetaAnnotationService service = this.spring.getContext().getBean(MetaAnnotationService.class);
1007+
assertThat(service.getIdPath("uid")).isEqualTo("uid");
1008+
}
1009+
10011010
private static Consumer<ConfigurableWebApplicationContext> disallowBeanOverriding() {
10021011
return (context) -> ((AnnotationConfigWebApplicationContext) context).setAllowBeanDefinitionOverriding(false);
10031012
}
@@ -1376,6 +1385,27 @@ List<String> resultsContainDave(List<String> list) {
13761385
return list;
13771386
}
13781387

1388+
@RestrictedAccess(entityClass = EntityClass.class)
1389+
String getIdPath(String id) {
1390+
return id;
1391+
}
1392+
1393+
}
1394+
1395+
@Retention(RetentionPolicy.RUNTIME)
1396+
@PreAuthorize("hasRole({idPath})")
1397+
@interface RestrictedAccess {
1398+
1399+
String idPath() default "#id";
1400+
1401+
Class<?> entityClass();
1402+
1403+
String[] recipes() default {};
1404+
1405+
}
1406+
1407+
static class EntityClass {
1408+
13791409
}
13801410

13811411
@Retention(RetentionPolicy.RUNTIME)

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,20 @@
1919
import java.lang.annotation.Annotation;
2020
import java.lang.reflect.AnnotatedElement;
2121
import java.lang.reflect.Method;
22+
import java.util.Collections;
2223
import java.util.HashMap;
2324
import java.util.List;
2425
import java.util.Map;
26+
import java.util.Set;
2527
import java.util.function.Function;
2628

2729
import org.springframework.core.annotation.AnnotationConfigurationException;
2830
import org.springframework.core.annotation.MergedAnnotation;
2931
import org.springframework.core.annotation.MergedAnnotations;
3032
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
3133
import org.springframework.core.annotation.RepeatableContainers;
34+
import org.springframework.core.convert.TypeDescriptor;
35+
import org.springframework.core.convert.converter.GenericConverter;
3236
import org.springframework.core.convert.support.DefaultConversionService;
3337
import org.springframework.util.PropertyPlaceholderHelper;
3438

@@ -55,6 +59,12 @@
5559
*/
5660
final class AuthorizationAnnotationUtils {
5761

62+
private static final DefaultConversionService conversionService = new DefaultConversionService();
63+
64+
static {
65+
conversionService.addConverter(new ClassToStringConverter());
66+
}
67+
5868
static <A extends Annotation> Function<AnnotatedElement, A> withDefaults(Class<A> type,
5969
PrePostTemplateDefaults defaults) {
6070
Function<MergedAnnotation<A>, A> map = (mergedAnnotation) -> {
@@ -69,8 +79,7 @@ static <A extends Annotation> Function<AnnotatedElement, A> withDefaults(Class<A
6979
for (Map.Entry<String, Object> property : annotationProperties.entrySet()) {
7080
String key = property.getKey();
7181
Object value = property.getValue();
72-
String asString = (value instanceof String) ? (String) value
73-
: DefaultConversionService.getSharedInstance().convert(value, String.class);
82+
String asString = (value instanceof String) ? (String) value : conversionService.convert(value, String.class);
7483
stringProperties.put(key, asString);
7584
}
7685
AnnotatedElement annotatedElement = (AnnotatedElement) mergedAnnotation.getSource();
@@ -156,4 +165,19 @@ private AuthorizationAnnotationUtils() {
156165

157166
}
158167

168+
static class ClassToStringConverter implements GenericConverter {
169+
170+
171+
@Override
172+
public Set<ConvertiblePair> getConvertibleTypes() {
173+
return Collections.singleton(new ConvertiblePair(Class.class, String.class));
174+
}
175+
176+
@Override
177+
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
178+
return (source != null) ? source.toString() : null;
179+
}
180+
181+
}
182+
159183
}

0 commit comments

Comments
 (0)