Skip to content

Commit c0a10b9

Browse files
committed
Merge remote-tracking branch 'origin/6.3.x'
2 parents c53ee19 + 5c20505 commit c0a10b9

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
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
@@ -1009,6 +1009,15 @@ public void adviseWhenPrePostEnabledThenEachInterceptorRunsExactlyOnce() {
10091009
verify(expressionHandler, times(4)).createEvaluationContext(any(Supplier.class), any());
10101010
}
10111011

1012+
// gh-15721
1013+
@Test
1014+
@WithMockUser(roles = "uid")
1015+
public void methodWhenMetaAnnotationPropertiesHasClassProperties() {
1016+
this.spring.register(MetaAnnotationPlaceholderConfig.class).autowire();
1017+
MetaAnnotationService service = this.spring.getContext().getBean(MetaAnnotationService.class);
1018+
assertThat(service.getIdPath("uid")).isEqualTo("uid");
1019+
}
1020+
10121021
private static Consumer<ConfigurableWebApplicationContext> disallowBeanOverriding() {
10131022
return (context) -> ((AnnotationConfigWebApplicationContext) context).setAllowBeanDefinitionOverriding(false);
10141023
}
@@ -1403,6 +1412,27 @@ List<String> resultsContainDave(List<String> list) {
14031412
return list;
14041413
}
14051414

1415+
@RestrictedAccess(entityClass = EntityClass.class)
1416+
String getIdPath(String id) {
1417+
return id;
1418+
}
1419+
1420+
}
1421+
1422+
@Retention(RetentionPolicy.RUNTIME)
1423+
@PreAuthorize("hasRole({idPath})")
1424+
@interface RestrictedAccess {
1425+
1426+
String idPath() default "#id";
1427+
1428+
Class<?> entityClass();
1429+
1430+
String[] recipes() default {};
1431+
1432+
}
1433+
1434+
static class EntityClass {
1435+
14061436
}
14071437

14081438
@Retention(RetentionPolicy.RUNTIME)

core/src/main/java/org/springframework/security/core/annotation/ExpressionTemplateSecurityAnnotationScanner.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@
2020
import java.lang.reflect.AnnotatedElement;
2121
import java.lang.reflect.Method;
2222
import java.lang.reflect.Parameter;
23+
import java.util.Collections;
2324
import java.util.HashMap;
2425
import java.util.Map;
26+
import java.util.Set;
2527

2628
import org.springframework.core.MethodClassKey;
2729
import org.springframework.core.annotation.MergedAnnotation;
30+
import org.springframework.core.convert.TypeDescriptor;
31+
import org.springframework.core.convert.converter.GenericConverter;
2832
import org.springframework.core.convert.support.DefaultConversionService;
2933
import org.springframework.util.Assert;
3034
import org.springframework.util.PropertyPlaceholderHelper;
@@ -64,6 +68,12 @@
6468
final class ExpressionTemplateSecurityAnnotationScanner<A extends Annotation>
6569
extends AbstractSecurityAnnotationScanner<A> {
6670

71+
private static final DefaultConversionService conversionService = new DefaultConversionService();
72+
73+
static {
74+
conversionService.addConverter(new ClassToStringConverter());
75+
}
76+
6777
private final Class<A> type;
6878

6979
private final UniqueSecurityAnnotationScanner<A> unique;
@@ -120,7 +130,7 @@ private MergedAnnotation<A> resolvePlaceholders(MergedAnnotation<A> mergedAnnota
120130
String key = property.getKey();
121131
Object value = property.getValue();
122132
String asString = (value instanceof String) ? (String) value
123-
: DefaultConversionService.getSharedInstance().convert(value, String.class);
133+
: conversionService.convert(value, String.class);
124134
stringProperties.put(key, asString);
125135
}
126136
Map<String, Object> annotationProperties = mergedAnnotation.asMap();
@@ -136,4 +146,18 @@ private MergedAnnotation<A> resolvePlaceholders(MergedAnnotation<A> mergedAnnota
136146
return MergedAnnotation.of(annotatedElement, this.type, properties);
137147
}
138148

149+
static class ClassToStringConverter implements GenericConverter {
150+
151+
@Override
152+
public Set<ConvertiblePair> getConvertibleTypes() {
153+
return Collections.singleton(new ConvertiblePair(Class.class, String.class));
154+
}
155+
156+
@Override
157+
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
158+
return (source != null) ? source.toString() : null;
159+
}
160+
161+
}
162+
139163
}

0 commit comments

Comments
 (0)