diff --git a/config/src/main/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfiguration.java b/config/src/main/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfiguration.java index 1b3d4c1bfa..4278e5d084 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfiguration.java +++ b/config/src/main/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfiguration.java @@ -51,6 +51,7 @@ import org.springframework.security.authorization.method.PreAuthorizeAuthorizati import org.springframework.security.authorization.method.PreFilterAuthorizationMethodInterceptor; import org.springframework.security.authorization.method.PrePostTemplateDefaults; import org.springframework.security.config.core.GrantedAuthorityDefaults; +import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults; import org.springframework.security.core.context.SecurityContextHolderStrategy; import org.springframework.util.function.SingletonSupplier; @@ -72,6 +73,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware, AopInfras @Role(BeanDefinition.ROLE_INFRASTRUCTURE) static MethodInterceptor preFilterAuthorizationMethodInterceptor( ObjectProvider defaultsProvider, + ObjectProvider templateExpressionDefaultsProvider, ObjectProvider methodSecurityDefaultsProvider, ObjectProvider expressionHandlerProvider, ObjectProvider strategyProvider, @@ -80,6 +82,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware, AopInfras PreFilterAuthorizationMethodInterceptor preFilter = new PreFilterAuthorizationMethodInterceptor(); preFilter.setOrder(preFilter.getOrder() + configuration.interceptorOrderOffset); return new DeferringMethodInterceptor<>(preFilter, (f) -> { + templateExpressionDefaultsProvider.ifAvailable(f::setTemplateDefaults); methodSecurityDefaultsProvider.ifAvailable(f::setTemplateDefaults); f.setExpressionHandler(expressionHandlerProvider .getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, roleHierarchyProvider, context))); @@ -91,6 +94,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware, AopInfras @Role(BeanDefinition.ROLE_INFRASTRUCTURE) static MethodInterceptor preAuthorizeAuthorizationMethodInterceptor( ObjectProvider defaultsProvider, + ObjectProvider templateExpressionDefaultsProvider, ObjectProvider methodSecurityDefaultsProvider, ObjectProvider expressionHandlerProvider, ObjectProvider strategyProvider, @@ -103,6 +107,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware, AopInfras .preAuthorize(manager(manager, registryProvider)); preAuthorize.setOrder(preAuthorize.getOrder() + configuration.interceptorOrderOffset); return new DeferringMethodInterceptor<>(preAuthorize, (f) -> { + templateExpressionDefaultsProvider.ifAvailable(manager::setTemplateDefaults); methodSecurityDefaultsProvider.ifAvailable(manager::setTemplateDefaults); manager.setExpressionHandler(expressionHandlerProvider .getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, roleHierarchyProvider, context))); @@ -115,6 +120,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware, AopInfras @Role(BeanDefinition.ROLE_INFRASTRUCTURE) static MethodInterceptor postAuthorizeAuthorizationMethodInterceptor( ObjectProvider defaultsProvider, + ObjectProvider templateExpressionDefaultsProvider, ObjectProvider methodSecurityDefaultsProvider, ObjectProvider expressionHandlerProvider, ObjectProvider strategyProvider, @@ -127,6 +133,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware, AopInfras .postAuthorize(manager(manager, registryProvider)); postAuthorize.setOrder(postAuthorize.getOrder() + configuration.interceptorOrderOffset); return new DeferringMethodInterceptor<>(postAuthorize, (f) -> { + templateExpressionDefaultsProvider.ifAvailable(manager::setTemplateDefaults); methodSecurityDefaultsProvider.ifAvailable(manager::setTemplateDefaults); manager.setExpressionHandler(expressionHandlerProvider .getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, roleHierarchyProvider, context))); @@ -139,6 +146,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware, AopInfras @Role(BeanDefinition.ROLE_INFRASTRUCTURE) static MethodInterceptor postFilterAuthorizationMethodInterceptor( ObjectProvider defaultsProvider, + ObjectProvider templateExpressionDefaultsProvider, ObjectProvider methodSecurityDefaultsProvider, ObjectProvider expressionHandlerProvider, ObjectProvider strategyProvider, @@ -147,6 +155,7 @@ final class PrePostMethodSecurityConfiguration implements ImportAware, AopInfras PostFilterAuthorizationMethodInterceptor postFilter = new PostFilterAuthorizationMethodInterceptor(); postFilter.setOrder(postFilter.getOrder() + configuration.interceptorOrderOffset); return new DeferringMethodInterceptor<>(postFilter, (f) -> { + templateExpressionDefaultsProvider.ifAvailable(f::setTemplateDefaults); methodSecurityDefaultsProvider.ifAvailable(f::setTemplateDefaults); f.setExpressionHandler(expressionHandlerProvider .getIfAvailable(() -> defaultExpressionHandler(defaultsProvider, roleHierarchyProvider, context))); diff --git a/config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfigurationTests.java b/config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfigurationTests.java index a2f82afe6d..5d0dbaee36 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfigurationTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/method/configuration/PrePostMethodSecurityConfigurationTests.java @@ -33,6 +33,8 @@ import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.springframework.aop.Advisor; import org.springframework.aop.support.DefaultPointcutAdvisor; @@ -78,6 +80,7 @@ import org.springframework.security.config.test.SpringTestContext; import org.springframework.security.config.test.SpringTestContextExtension; import org.springframework.security.config.test.SpringTestParentApplicationContextExecutionListener; import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults; import org.springframework.security.core.context.SecurityContextHolderStrategy; import org.springframework.security.test.context.support.WithAnonymousUser; import org.springframework.security.test.context.support.WithMockUser; @@ -607,69 +610,77 @@ public class PrePostMethodSecurityConfigurationTests { assertThat(filtered).containsExactly("DoNotDrop"); } - @Test + @ParameterizedTest + @ValueSource(classes = { LegacyMetaAnnotationPlaceholderConfig.class, MetaAnnotationPlaceholderConfig.class }) @WithMockUser - public void methodeWhenParameterizedPreAuthorizeMetaAnnotationThenPasses() { - this.spring.register(MetaAnnotationPlaceholderConfig.class).autowire(); + public void methodeWhenParameterizedPreAuthorizeMetaAnnotationThenPasses(Class config) { + this.spring.register(config).autowire(); MetaAnnotationService service = this.spring.getContext().getBean(MetaAnnotationService.class); assertThat(service.hasRole("USER")).isTrue(); } - @Test + @ParameterizedTest + @ValueSource(classes = { LegacyMetaAnnotationPlaceholderConfig.class, MetaAnnotationPlaceholderConfig.class }) @WithMockUser - public void methodRoleWhenPreAuthorizeMetaAnnotationHardcodedParameterThenPasses() { - this.spring.register(MetaAnnotationPlaceholderConfig.class).autowire(); + public void methodRoleWhenPreAuthorizeMetaAnnotationHardcodedParameterThenPasses(Class config) { + this.spring.register(config).autowire(); MetaAnnotationService service = this.spring.getContext().getBean(MetaAnnotationService.class); assertThat(service.hasUserRole()).isTrue(); } - @Test - public void methodWhenParameterizedAnnotationThenFails() { - this.spring.register(MetaAnnotationPlaceholderConfig.class).autowire(); + @ParameterizedTest + @ValueSource(classes = { LegacyMetaAnnotationPlaceholderConfig.class, MetaAnnotationPlaceholderConfig.class }) + public void methodWhenParameterizedAnnotationThenFails(Class config) { + this.spring.register(config).autowire(); MetaAnnotationService service = this.spring.getContext().getBean(MetaAnnotationService.class); assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(service::placeholdersOnlyResolvedByMetaAnnotations); } - @Test + @ParameterizedTest + @ValueSource(classes = { LegacyMetaAnnotationPlaceholderConfig.class, MetaAnnotationPlaceholderConfig.class }) @WithMockUser(authorities = "SCOPE_message:read") - public void methodWhenMultiplePlaceholdersHasAuthorityThenPasses() { - this.spring.register(MetaAnnotationPlaceholderConfig.class).autowire(); + public void methodWhenMultiplePlaceholdersHasAuthorityThenPasses(Class config) { + this.spring.register(config).autowire(); MetaAnnotationService service = this.spring.getContext().getBean(MetaAnnotationService.class); assertThat(service.readMessage()).isEqualTo("message"); } - @Test + @ParameterizedTest + @ValueSource(classes = { LegacyMetaAnnotationPlaceholderConfig.class, MetaAnnotationPlaceholderConfig.class }) @WithMockUser(roles = "ADMIN") - public void methodWhenMultiplePlaceholdersHasRoleThenPasses() { - this.spring.register(MetaAnnotationPlaceholderConfig.class).autowire(); + public void methodWhenMultiplePlaceholdersHasRoleThenPasses(Class config) { + this.spring.register(config).autowire(); MetaAnnotationService service = this.spring.getContext().getBean(MetaAnnotationService.class); assertThat(service.readMessage()).isEqualTo("message"); } - @Test + @ParameterizedTest + @ValueSource(classes = { LegacyMetaAnnotationPlaceholderConfig.class, MetaAnnotationPlaceholderConfig.class }) @WithMockUser - public void methodWhenPostAuthorizeMetaAnnotationThenAuthorizes() { - this.spring.register(MetaAnnotationPlaceholderConfig.class).autowire(); + public void methodWhenPostAuthorizeMetaAnnotationThenAuthorizes(Class config) { + this.spring.register(config).autowire(); MetaAnnotationService service = this.spring.getContext().getBean(MetaAnnotationService.class); service.startsWithDave("daveMatthews"); assertThatExceptionOfType(AccessDeniedException.class) .isThrownBy(() -> service.startsWithDave("jenniferHarper")); } - @Test + @ParameterizedTest + @ValueSource(classes = { LegacyMetaAnnotationPlaceholderConfig.class, MetaAnnotationPlaceholderConfig.class }) @WithMockUser - public void methodWhenPreFilterMetaAnnotationThenFilters() { - this.spring.register(MetaAnnotationPlaceholderConfig.class).autowire(); + public void methodWhenPreFilterMetaAnnotationThenFilters(Class config) { + this.spring.register(config).autowire(); MetaAnnotationService service = this.spring.getContext().getBean(MetaAnnotationService.class); assertThat(service.parametersContainDave(new ArrayList<>(List.of("dave", "carla", "vanessa", "paul")))) .containsExactly("dave"); } - @Test + @ParameterizedTest + @ValueSource(classes = { LegacyMetaAnnotationPlaceholderConfig.class, MetaAnnotationPlaceholderConfig.class }) @WithMockUser - public void methodWhenPostFilterMetaAnnotationThenFilters() { - this.spring.register(MetaAnnotationPlaceholderConfig.class).autowire(); + public void methodWhenPostFilterMetaAnnotationThenFilters(Class config) { + this.spring.register(config).autowire(); MetaAnnotationService service = this.spring.getContext().getBean(MetaAnnotationService.class); assertThat(service.resultsContainDave(new ArrayList<>(List.of("dave", "carla", "vanessa", "paul")))) .containsExactly("dave"); @@ -827,7 +838,7 @@ public class PrePostMethodSecurityConfigurationTests { @WithMockUser void postAuthorizeWhenNullDeniedMetaAnnotationThanWorks() { this.spring - .register(MethodSecurityServiceEnabledConfig.class, MetaAnnotationPlaceholderConfig.class, + .register(MethodSecurityServiceEnabledConfig.class, LegacyMetaAnnotationPlaceholderConfig.class, MethodSecurityService.NullPostProcessor.class) .autowire(); MethodSecurityService service = this.spring.getContext().getBean(MethodSecurityService.class); @@ -1268,7 +1279,7 @@ public class PrePostMethodSecurityConfigurationTests { @Configuration @EnableMethodSecurity - static class MetaAnnotationPlaceholderConfig { + static class LegacyMetaAnnotationPlaceholderConfig { @Bean PrePostTemplateDefaults methodSecurityDefaults() { @@ -1282,6 +1293,22 @@ public class PrePostMethodSecurityConfigurationTests { } + @Configuration + @EnableMethodSecurity + static class MetaAnnotationPlaceholderConfig { + + @Bean + AnnotationTemplateExpressionDefaults methodSecurityDefaults() { + return new AnnotationTemplateExpressionDefaults(); + } + + @Bean + MetaAnnotationService metaAnnotationService() { + return new MetaAnnotationService(); + } + + } + static class MetaAnnotationService { @RequireRole(role = "#role") diff --git a/core/src/main/java/org/springframework/security/authorization/method/AbstractExpressionAttributeRegistry.java b/core/src/main/java/org/springframework/security/authorization/method/AbstractExpressionAttributeRegistry.java index ba87efa9dc..ef6d00ac79 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/AbstractExpressionAttributeRegistry.java +++ b/core/src/main/java/org/springframework/security/authorization/method/AbstractExpressionAttributeRegistry.java @@ -26,6 +26,7 @@ import org.springframework.core.MethodClassKey; import org.springframework.lang.NonNull; import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; +import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults; import org.springframework.util.Assert; /** @@ -76,6 +77,15 @@ abstract class AbstractExpressionAttributeRegistry + * By default, this value is null, which indicates that templates should + * not be resolved. + * @param defaults - whether to resolve pre/post-authorization templates parameters + * @since 6.4 + */ + public void setTemplateDefaults(AnnotationTemplateExpressionDefaults defaults) { + this.registry.setTemplateDefaults(defaults); + } + /** * Invokes * {@link PostAuthorizeExpressionAttributeRegistry#setApplicationContext(ApplicationContext)} diff --git a/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeExpressionAttributeRegistry.java b/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeExpressionAttributeRegistry.java index a42aef345b..05f17ee93d 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeExpressionAttributeRegistry.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeExpressionAttributeRegistry.java @@ -27,6 +27,7 @@ import org.springframework.expression.Expression; import org.springframework.security.access.prepost.PostAuthorize; import org.springframework.security.core.annotation.AnnotationSynthesizer; import org.springframework.security.core.annotation.AnnotationSynthesizers; +import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults; import org.springframework.util.Assert; /** @@ -90,7 +91,7 @@ final class PostAuthorizeExpressionAttributeRegistry extends AbstractExpressionA this.handlerResolver = (clazz) -> resolveHandler(context, clazz); } - void setTemplateDefaults(PrePostTemplateDefaults templateDefaults) { + void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) { this.postAuthorizeSynthesizer = AnnotationSynthesizers.requireUnique(PostAuthorize.class, templateDefaults); } diff --git a/core/src/main/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptor.java b/core/src/main/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptor.java index aa96de670d..5019e8fa47 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptor.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptor.java @@ -28,6 +28,7 @@ import org.springframework.security.access.expression.method.MethodSecurityExpre import org.springframework.security.access.prepost.PostFilter; import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolderStrategy; @@ -73,11 +74,25 @@ public final class PostFilterAuthorizationMethodInterceptor implements Authoriza * not be resolved. * @param defaults - whether to resolve pre/post-authorization templates parameters * @since 6.3 + * @deprecated Please use {@link AnnotationTemplateExpressionDefaults} instead */ + @Deprecated public void setTemplateDefaults(PrePostTemplateDefaults defaults) { this.registry.setTemplateDefaults(defaults); } + /** + * Configure pre/post-authorization template resolution + *

+ * By default, this value is null, which indicates that templates should + * not be resolved. + * @param defaults - whether to resolve pre/post-authorization templates parameters + * @since 6.4 + */ + public void setTemplateDefaults(AnnotationTemplateExpressionDefaults defaults) { + this.registry.setTemplateDefaults(defaults); + } + /** * {@inheritDoc} */ diff --git a/core/src/main/java/org/springframework/security/authorization/method/PostFilterExpressionAttributeRegistry.java b/core/src/main/java/org/springframework/security/authorization/method/PostFilterExpressionAttributeRegistry.java index 2d8e316e71..b9d678c749 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PostFilterExpressionAttributeRegistry.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PostFilterExpressionAttributeRegistry.java @@ -23,6 +23,7 @@ import org.springframework.lang.NonNull; import org.springframework.security.access.prepost.PostFilter; import org.springframework.security.core.annotation.AnnotationSynthesizer; import org.springframework.security.core.annotation.AnnotationSynthesizers; +import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults; /** * For internal use only, as this contract is likely to change. @@ -47,7 +48,7 @@ final class PostFilterExpressionAttributeRegistry extends AbstractExpressionAttr return new ExpressionAttribute(postFilterExpression); } - void setTemplateDefaults(PrePostTemplateDefaults defaults) { + void setTemplateDefaults(AnnotationTemplateExpressionDefaults defaults) { this.synthesizer = AnnotationSynthesizers.requireUnique(PostFilter.class, defaults); } diff --git a/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java index 02c26ebf34..0960c7a2db 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java @@ -28,6 +28,7 @@ import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.AuthorizationManager; import org.springframework.security.authorization.AuthorizationResult; import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults; /** * An {@link AuthorizationManager} which can determine if an {@link Authentication} may @@ -57,11 +58,26 @@ public final class PreAuthorizeAuthorizationManager * not be resolved. * @param defaults - whether to resolve pre/post-authorization templates parameters * @since 6.3 + * @deprecated Please use + * {@link #setTemplateDefaults(AnnotationTemplateExpressionDefaults)} instead */ + @Deprecated public void setTemplateDefaults(PrePostTemplateDefaults defaults) { this.registry.setTemplateDefaults(defaults); } + /** + * Configure pre/post-authorization template resolution + *

+ * By default, this value is null, which indicates that templates should + * not be resolved. + * @param defaults - whether to resolve pre/post-authorization templates parameters + * @since 6.4 + */ + public void setTemplateDefaults(AnnotationTemplateExpressionDefaults defaults) { + this.registry.setTemplateDefaults(defaults); + } + public void setApplicationContext(ApplicationContext context) { this.registry.setApplicationContext(context); } diff --git a/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeExpressionAttributeRegistry.java b/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeExpressionAttributeRegistry.java index 8e02071c7f..d514674941 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeExpressionAttributeRegistry.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeExpressionAttributeRegistry.java @@ -27,6 +27,7 @@ import org.springframework.expression.Expression; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.annotation.AnnotationSynthesizer; import org.springframework.security.core.annotation.AnnotationSynthesizers; +import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults; import org.springframework.util.Assert; /** @@ -90,7 +91,7 @@ final class PreAuthorizeExpressionAttributeRegistry extends AbstractExpressionAt this.handlerResolver = (clazz) -> resolveHandler(context, clazz); } - void setTemplateDefaults(PrePostTemplateDefaults defaults) { + void setTemplateDefaults(AnnotationTemplateExpressionDefaults defaults) { this.preAuthorizeSynthesizer = AnnotationSynthesizers.requireUnique(PreAuthorize.class, defaults); } diff --git a/core/src/main/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptor.java b/core/src/main/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptor.java index a00e22f253..28d4344ba9 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptor.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptor.java @@ -28,6 +28,7 @@ import org.springframework.security.access.expression.method.MethodSecurityExpre import org.springframework.security.access.prepost.PreFilter; import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; import org.springframework.security.core.Authentication; +import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolderStrategy; import org.springframework.util.Assert; @@ -74,11 +75,26 @@ public final class PreFilterAuthorizationMethodInterceptor implements Authorizat * not be resolved. * @param defaults - whether to resolve pre/post-authorization templates parameters * @since 6.3 + * @deprecated Please use + * {@link #setTemplateDefaults(AnnotationTemplateExpressionDefaults)} instead */ + @Deprecated public void setTemplateDefaults(PrePostTemplateDefaults defaults) { this.registry.setTemplateDefaults(defaults); } + /** + * Configure pre/post-authorization template resolution + *

+ * By default, this value is null, which indicates that templates should + * not be resolved. + * @param defaults - whether to resolve pre/post-authorization templates parameters + * @since 6.4 + */ + public void setTemplateDefaults(AnnotationTemplateExpressionDefaults defaults) { + this.registry.setTemplateDefaults(defaults); + } + /** * {@inheritDoc} */ diff --git a/core/src/main/java/org/springframework/security/authorization/method/PreFilterExpressionAttributeRegistry.java b/core/src/main/java/org/springframework/security/authorization/method/PreFilterExpressionAttributeRegistry.java index eda0374486..6d52698850 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PreFilterExpressionAttributeRegistry.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PreFilterExpressionAttributeRegistry.java @@ -23,6 +23,7 @@ import org.springframework.lang.NonNull; import org.springframework.security.access.prepost.PreFilter; import org.springframework.security.core.annotation.AnnotationSynthesizer; import org.springframework.security.core.annotation.AnnotationSynthesizers; +import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults; /** * For internal use only, as this contract is likely to change. @@ -48,7 +49,7 @@ final class PreFilterExpressionAttributeRegistry return new PreFilterExpressionAttribute(preFilterExpression, preFilter.filterTarget()); } - void setTemplateDefaults(PrePostTemplateDefaults defaults) { + void setTemplateDefaults(AnnotationTemplateExpressionDefaults defaults) { this.synthesizer = AnnotationSynthesizers.requireUnique(PreFilter.class, defaults); } diff --git a/core/src/main/java/org/springframework/security/authorization/method/PrePostTemplateDefaults.java b/core/src/main/java/org/springframework/security/authorization/method/PrePostTemplateDefaults.java index e31ac4aca9..4ffef54834 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PrePostTemplateDefaults.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PrePostTemplateDefaults.java @@ -27,7 +27,32 @@ import org.springframework.security.core.annotation.AnnotationTemplateExpression * @see org.springframework.security.access.prepost.PostAuthorize * @see org.springframework.security.access.prepost.PreFilter * @see org.springframework.security.access.prepost.PostFilter + * @deprecated Please use {@link AnnotationTemplateExpressionDefaults} instead */ -public final class PrePostTemplateDefaults extends AnnotationTemplateExpressionDefaults { +@Deprecated +public final class PrePostTemplateDefaults { + + private boolean ignoreUnknown = true; + + /** + * Whether template resolution should ignore placeholders it doesn't recognize. + *

+ * By default, this value is true. + */ + public boolean isIgnoreUnknown() { + return this.ignoreUnknown; + } + + /** + * Configure template resolution to ignore unknown placeholders. When set to + * false, template resolution will throw an exception for unknown + * placeholders. + *

+ * By default, this value is true. + * @param ignoreUnknown - whether to ignore unknown placeholders parameters + */ + public void setIgnoreUnknown(boolean ignoreUnknown) { + this.ignoreUnknown = ignoreUnknown; + } } diff --git a/docs/modules/ROOT/pages/servlet/authorization/method-security.adoc b/docs/modules/ROOT/pages/servlet/authorization/method-security.adoc index 2af4db987b..8eeddf5efc 100644 --- a/docs/modules/ROOT/pages/servlet/authorization/method-security.adoc +++ b/docs/modules/ROOT/pages/servlet/authorization/method-security.adoc @@ -1012,8 +1012,8 @@ Java:: [source,java,role="primary"] ---- @Bean -static PrePostTemplateDefaults prePostTemplateDefaults() { - return new PrePostTemplateDefaults(); +static AnnotationTemplateExpressionDefaults templateExpressionDefaults() { + return new AnnotationTemplateExpressionDefaults(); } ---- @@ -1023,8 +1023,8 @@ Kotlin:: ---- companion object { @Bean - fun prePostTemplateDefaults(): PrePostTemplateDefaults { - return PrePostTemplateDefaults() + fun templateExpressionDefaults(): AnnotationTemplateExpressionDefaults { + return AnnotationTemplateExpressionDefaults() } } ----