diff --git a/access/spring-security-access.gradle b/access/spring-security-access.gradle
new file mode 100644
index 0000000000..f5747c6686
--- /dev/null
+++ b/access/spring-security-access.gradle
@@ -0,0 +1,49 @@
+apply plugin: 'io.spring.convention.spring-module'
+
+dependencies {
+ management platform(project(":spring-security-dependencies"))
+ api project(':spring-security-crypto')
+ api project(':spring-security-core')
+ api 'org.springframework:spring-aop'
+ api 'org.springframework:spring-beans'
+ api 'org.springframework:spring-context'
+ api 'org.springframework:spring-core'
+ api 'org.springframework:spring-expression'
+ api 'io.micrometer:micrometer-observation'
+
+ optional project(':spring-security-acl')
+ optional project(':spring-security-messaging')
+ optional project(':spring-security-web')
+ optional 'org.springframework:spring-websocket'
+ optional 'com.fasterxml.jackson.core:jackson-databind'
+ optional 'io.micrometer:context-propagation'
+ optional 'io.projectreactor:reactor-core'
+ optional 'jakarta.annotation:jakarta.annotation-api'
+ optional 'org.aspectj:aspectjrt'
+ optional 'org.springframework:spring-jdbc'
+ optional 'org.springframework:spring-tx'
+ optional 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor'
+
+ provided 'jakarta.servlet:jakarta.servlet-api'
+
+ testImplementation project(path : ':spring-security-web', configuration : 'tests')
+ testImplementation 'commons-collections:commons-collections'
+ testImplementation 'io.projectreactor:reactor-test'
+ testImplementation "org.assertj:assertj-core"
+ testImplementation "org.junit.jupiter:junit-jupiter-api"
+ testImplementation "org.junit.jupiter:junit-jupiter-params"
+ testImplementation "org.junit.jupiter:junit-jupiter-engine"
+ testImplementation "org.mockito:mockito-core"
+ testImplementation "org.mockito:mockito-junit-jupiter"
+ testImplementation "org.springframework:spring-core-test"
+ testImplementation "org.springframework:spring-test"
+ testImplementation 'org.skyscreamer:jsonassert'
+ testImplementation 'org.springframework:spring-test'
+ testImplementation 'org.jetbrains.kotlin:kotlin-reflect'
+ testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
+ testImplementation 'io.mockk:mockk'
+
+ testRuntimeOnly 'org.hsqldb:hsqldb'
+ testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
+}
+
diff --git a/core/src/main/java/org/springframework/security/access/AccessDecisionManager.java b/access/src/main/java/org/springframework/security/access/AccessDecisionManager.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/AccessDecisionManager.java
rename to access/src/main/java/org/springframework/security/access/AccessDecisionManager.java
diff --git a/core/src/main/java/org/springframework/security/access/AccessDecisionVoter.java b/access/src/main/java/org/springframework/security/access/AccessDecisionVoter.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/AccessDecisionVoter.java
rename to access/src/main/java/org/springframework/security/access/AccessDecisionVoter.java
diff --git a/core/src/main/java/org/springframework/security/access/AfterInvocationProvider.java b/access/src/main/java/org/springframework/security/access/AfterInvocationProvider.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/AfterInvocationProvider.java
rename to access/src/main/java/org/springframework/security/access/AfterInvocationProvider.java
diff --git a/core/src/main/java/org/springframework/security/access/ConfigAttribute.java b/access/src/main/java/org/springframework/security/access/ConfigAttribute.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/ConfigAttribute.java
rename to access/src/main/java/org/springframework/security/access/ConfigAttribute.java
diff --git a/core/src/main/java/org/springframework/security/access/SecurityConfig.java b/access/src/main/java/org/springframework/security/access/SecurityConfig.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/SecurityConfig.java
rename to access/src/main/java/org/springframework/security/access/SecurityConfig.java
diff --git a/core/src/main/java/org/springframework/security/access/SecurityMetadataSource.java b/access/src/main/java/org/springframework/security/access/SecurityMetadataSource.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/SecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/access/SecurityMetadataSource.java
diff --git a/core/src/main/java/org/springframework/security/access/annotation/AnnotationMetadataExtractor.java b/access/src/main/java/org/springframework/security/access/annotation/AnnotationMetadataExtractor.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/annotation/AnnotationMetadataExtractor.java
rename to access/src/main/java/org/springframework/security/access/annotation/AnnotationMetadataExtractor.java
diff --git a/core/src/main/java/org/springframework/security/access/annotation/Jsr250MethodSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/access/annotation/Jsr250MethodSecurityMetadataSource.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/annotation/Jsr250MethodSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/access/annotation/Jsr250MethodSecurityMetadataSource.java
diff --git a/core/src/main/java/org/springframework/security/access/annotation/Jsr250SecurityConfig.java b/access/src/main/java/org/springframework/security/access/annotation/Jsr250SecurityConfig.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/annotation/Jsr250SecurityConfig.java
rename to access/src/main/java/org/springframework/security/access/annotation/Jsr250SecurityConfig.java
diff --git a/core/src/main/java/org/springframework/security/access/annotation/Jsr250Voter.java b/access/src/main/java/org/springframework/security/access/annotation/Jsr250Voter.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/annotation/Jsr250Voter.java
rename to access/src/main/java/org/springframework/security/access/annotation/Jsr250Voter.java
diff --git a/core/src/main/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSource.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSource.java
diff --git a/access/src/main/java/org/springframework/security/access/annotation/package-info.java b/access/src/main/java/org/springframework/security/access/annotation/package-info.java
new file mode 100644
index 0000000000..937a0b1c56
--- /dev/null
+++ b/access/src/main/java/org/springframework/security/access/annotation/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2004-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Support for JSR-250 and Spring Security {@code @Secured} annotations.
+ */
+@NullMarked
+package org.springframework.security.access.annotation;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/core/src/main/java/org/springframework/security/access/event/AbstractAuthorizationEvent.java b/access/src/main/java/org/springframework/security/access/event/AbstractAuthorizationEvent.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/event/AbstractAuthorizationEvent.java
rename to access/src/main/java/org/springframework/security/access/event/AbstractAuthorizationEvent.java
diff --git a/core/src/main/java/org/springframework/security/access/event/AuthenticationCredentialsNotFoundEvent.java b/access/src/main/java/org/springframework/security/access/event/AuthenticationCredentialsNotFoundEvent.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/event/AuthenticationCredentialsNotFoundEvent.java
rename to access/src/main/java/org/springframework/security/access/event/AuthenticationCredentialsNotFoundEvent.java
diff --git a/core/src/main/java/org/springframework/security/access/event/AuthorizationFailureEvent.java b/access/src/main/java/org/springframework/security/access/event/AuthorizationFailureEvent.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/event/AuthorizationFailureEvent.java
rename to access/src/main/java/org/springframework/security/access/event/AuthorizationFailureEvent.java
diff --git a/core/src/main/java/org/springframework/security/access/event/AuthorizedEvent.java b/access/src/main/java/org/springframework/security/access/event/AuthorizedEvent.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/event/AuthorizedEvent.java
rename to access/src/main/java/org/springframework/security/access/event/AuthorizedEvent.java
diff --git a/core/src/main/java/org/springframework/security/access/event/LoggerListener.java b/access/src/main/java/org/springframework/security/access/event/LoggerListener.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/event/LoggerListener.java
rename to access/src/main/java/org/springframework/security/access/event/LoggerListener.java
diff --git a/core/src/main/java/org/springframework/security/access/event/PublicInvocationEvent.java b/access/src/main/java/org/springframework/security/access/event/PublicInvocationEvent.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/event/PublicInvocationEvent.java
rename to access/src/main/java/org/springframework/security/access/event/PublicInvocationEvent.java
diff --git a/core/src/main/java/org/springframework/security/access/event/package-info.java b/access/src/main/java/org/springframework/security/access/event/package-info.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/event/package-info.java
rename to access/src/main/java/org/springframework/security/access/event/package-info.java
diff --git a/core/src/main/java/org/springframework/security/access/expression/method/AbstractExpressionBasedMethodConfigAttribute.java b/access/src/main/java/org/springframework/security/access/expression/method/AbstractExpressionBasedMethodConfigAttribute.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/expression/method/AbstractExpressionBasedMethodConfigAttribute.java
rename to access/src/main/java/org/springframework/security/access/expression/method/AbstractExpressionBasedMethodConfigAttribute.java
diff --git a/core/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedAnnotationAttributeFactory.java b/access/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedAnnotationAttributeFactory.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedAnnotationAttributeFactory.java
rename to access/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedAnnotationAttributeFactory.java
diff --git a/core/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPostInvocationAdvice.java b/access/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPostInvocationAdvice.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPostInvocationAdvice.java
rename to access/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPostInvocationAdvice.java
diff --git a/core/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdvice.java b/access/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdvice.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdvice.java
rename to access/src/main/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdvice.java
diff --git a/core/src/main/java/org/springframework/security/access/expression/method/PostInvocationExpressionAttribute.java b/access/src/main/java/org/springframework/security/access/expression/method/PostInvocationExpressionAttribute.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/expression/method/PostInvocationExpressionAttribute.java
rename to access/src/main/java/org/springframework/security/access/expression/method/PostInvocationExpressionAttribute.java
diff --git a/core/src/main/java/org/springframework/security/access/expression/method/PreInvocationExpressionAttribute.java b/access/src/main/java/org/springframework/security/access/expression/method/PreInvocationExpressionAttribute.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/expression/method/PreInvocationExpressionAttribute.java
rename to access/src/main/java/org/springframework/security/access/expression/method/PreInvocationExpressionAttribute.java
diff --git a/access/src/main/java/org/springframework/security/access/expression/method/package-info.java b/access/src/main/java/org/springframework/security/access/expression/method/package-info.java
new file mode 100644
index 0000000000..0923fe65a6
--- /dev/null
+++ b/access/src/main/java/org/springframework/security/access/expression/method/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2004-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Implementation of expression-based method security.
+ *
+ * @since 3.0
+ */
+@NullMarked
+package org.springframework.security.access.expression.method;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/core/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java b/access/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java
rename to access/src/main/java/org/springframework/security/access/intercept/AbstractSecurityInterceptor.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/AfterInvocationManager.java b/access/src/main/java/org/springframework/security/access/intercept/AfterInvocationManager.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/AfterInvocationManager.java
rename to access/src/main/java/org/springframework/security/access/intercept/AfterInvocationManager.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/AfterInvocationProviderManager.java b/access/src/main/java/org/springframework/security/access/intercept/AfterInvocationProviderManager.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/AfterInvocationProviderManager.java
rename to access/src/main/java/org/springframework/security/access/intercept/AfterInvocationProviderManager.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/InterceptorStatusToken.java b/access/src/main/java/org/springframework/security/access/intercept/InterceptorStatusToken.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/InterceptorStatusToken.java
rename to access/src/main/java/org/springframework/security/access/intercept/InterceptorStatusToken.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/MethodInvocationPrivilegeEvaluator.java b/access/src/main/java/org/springframework/security/access/intercept/MethodInvocationPrivilegeEvaluator.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/MethodInvocationPrivilegeEvaluator.java
rename to access/src/main/java/org/springframework/security/access/intercept/MethodInvocationPrivilegeEvaluator.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/NullRunAsManager.java b/access/src/main/java/org/springframework/security/access/intercept/NullRunAsManager.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/NullRunAsManager.java
rename to access/src/main/java/org/springframework/security/access/intercept/NullRunAsManager.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/RunAsImplAuthenticationProvider.java b/access/src/main/java/org/springframework/security/access/intercept/RunAsImplAuthenticationProvider.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/RunAsImplAuthenticationProvider.java
rename to access/src/main/java/org/springframework/security/access/intercept/RunAsImplAuthenticationProvider.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/RunAsManager.java b/access/src/main/java/org/springframework/security/access/intercept/RunAsManager.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/RunAsManager.java
rename to access/src/main/java/org/springframework/security/access/intercept/RunAsManager.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/RunAsManagerImpl.java b/access/src/main/java/org/springframework/security/access/intercept/RunAsManagerImpl.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/RunAsManagerImpl.java
rename to access/src/main/java/org/springframework/security/access/intercept/RunAsManagerImpl.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/RunAsUserToken.java b/access/src/main/java/org/springframework/security/access/intercept/RunAsUserToken.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/RunAsUserToken.java
rename to access/src/main/java/org/springframework/security/access/intercept/RunAsUserToken.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptor.java b/access/src/main/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptor.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptor.java
rename to access/src/main/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptor.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityMetadataSourceAdvisor.java b/access/src/main/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityMetadataSourceAdvisor.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityMetadataSourceAdvisor.java
rename to access/src/main/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityMetadataSourceAdvisor.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/aopalliance/package-info.java b/access/src/main/java/org/springframework/security/access/intercept/aopalliance/package-info.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/aopalliance/package-info.java
rename to access/src/main/java/org/springframework/security/access/intercept/aopalliance/package-info.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJCallback.java b/access/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJCallback.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJCallback.java
rename to access/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJCallback.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptor.java b/access/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptor.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptor.java
rename to access/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptor.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/aspectj/MethodInvocationAdapter.java b/access/src/main/java/org/springframework/security/access/intercept/aspectj/MethodInvocationAdapter.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/aspectj/MethodInvocationAdapter.java
rename to access/src/main/java/org/springframework/security/access/intercept/aspectj/MethodInvocationAdapter.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/aspectj/package-info.java b/access/src/main/java/org/springframework/security/access/intercept/aspectj/package-info.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/aspectj/package-info.java
rename to access/src/main/java/org/springframework/security/access/intercept/aspectj/package-info.java
diff --git a/core/src/main/java/org/springframework/security/access/intercept/package-info.java b/access/src/main/java/org/springframework/security/access/intercept/package-info.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/intercept/package-info.java
rename to access/src/main/java/org/springframework/security/access/intercept/package-info.java
diff --git a/core/src/main/java/org/springframework/security/access/method/AbstractFallbackMethodSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/access/method/AbstractFallbackMethodSecurityMetadataSource.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/method/AbstractFallbackMethodSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/access/method/AbstractFallbackMethodSecurityMetadataSource.java
diff --git a/core/src/main/java/org/springframework/security/access/method/AbstractMethodSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/access/method/AbstractMethodSecurityMetadataSource.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/method/AbstractMethodSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/access/method/AbstractMethodSecurityMetadataSource.java
diff --git a/core/src/main/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSource.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSource.java
diff --git a/core/src/main/java/org/springframework/security/access/method/MapBasedMethodSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/access/method/MapBasedMethodSecurityMetadataSource.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/method/MapBasedMethodSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/access/method/MapBasedMethodSecurityMetadataSource.java
diff --git a/core/src/main/java/org/springframework/security/access/method/MethodSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/access/method/MethodSecurityMetadataSource.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/method/MethodSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/access/method/MethodSecurityMetadataSource.java
diff --git a/core/src/main/java/org/springframework/security/access/method/P.java b/access/src/main/java/org/springframework/security/access/method/P.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/method/P.java
rename to access/src/main/java/org/springframework/security/access/method/P.java
diff --git a/core/src/main/java/org/springframework/security/access/method/package-info.java b/access/src/main/java/org/springframework/security/access/method/package-info.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/method/package-info.java
rename to access/src/main/java/org/springframework/security/access/method/package-info.java
diff --git a/access/src/main/java/org/springframework/security/access/package-info.java b/access/src/main/java/org/springframework/security/access/package-info.java
new file mode 100644
index 0000000000..01ac014fe7
--- /dev/null
+++ b/access/src/main/java/org/springframework/security/access/package-info.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2004-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Core access-control related code, including security metadata related classes,
+ * interception code, access control annotations, EL support and voter-based
+ * implementations of the central
+ * {@link org.springframework.security.access.AccessDecisionManager AccessDecisionManager}
+ * interface.
+ */
+@NullMarked
+package org.springframework.security.access;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/core/src/main/java/org/springframework/security/access/prepost/PostInvocationAdviceProvider.java b/access/src/main/java/org/springframework/security/access/prepost/PostInvocationAdviceProvider.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/prepost/PostInvocationAdviceProvider.java
rename to access/src/main/java/org/springframework/security/access/prepost/PostInvocationAdviceProvider.java
diff --git a/core/src/main/java/org/springframework/security/access/prepost/PostInvocationAttribute.java b/access/src/main/java/org/springframework/security/access/prepost/PostInvocationAttribute.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/prepost/PostInvocationAttribute.java
rename to access/src/main/java/org/springframework/security/access/prepost/PostInvocationAttribute.java
diff --git a/core/src/main/java/org/springframework/security/access/prepost/PostInvocationAuthorizationAdvice.java b/access/src/main/java/org/springframework/security/access/prepost/PostInvocationAuthorizationAdvice.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/prepost/PostInvocationAuthorizationAdvice.java
rename to access/src/main/java/org/springframework/security/access/prepost/PostInvocationAuthorizationAdvice.java
diff --git a/core/src/main/java/org/springframework/security/access/prepost/PreInvocationAttribute.java b/access/src/main/java/org/springframework/security/access/prepost/PreInvocationAttribute.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/prepost/PreInvocationAttribute.java
rename to access/src/main/java/org/springframework/security/access/prepost/PreInvocationAttribute.java
diff --git a/core/src/main/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdvice.java b/access/src/main/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdvice.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdvice.java
rename to access/src/main/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdvice.java
diff --git a/core/src/main/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdviceVoter.java b/access/src/main/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdviceVoter.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdviceVoter.java
rename to access/src/main/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdviceVoter.java
diff --git a/core/src/main/java/org/springframework/security/access/prepost/PrePostAdviceReactiveMethodInterceptor.java b/access/src/main/java/org/springframework/security/access/prepost/PrePostAdviceReactiveMethodInterceptor.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/prepost/PrePostAdviceReactiveMethodInterceptor.java
rename to access/src/main/java/org/springframework/security/access/prepost/PrePostAdviceReactiveMethodInterceptor.java
diff --git a/core/src/main/java/org/springframework/security/access/prepost/PrePostAnnotationSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/access/prepost/PrePostAnnotationSecurityMetadataSource.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/prepost/PrePostAnnotationSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/access/prepost/PrePostAnnotationSecurityMetadataSource.java
diff --git a/core/src/main/java/org/springframework/security/access/prepost/PrePostInvocationAttributeFactory.java b/access/src/main/java/org/springframework/security/access/prepost/PrePostInvocationAttributeFactory.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/prepost/PrePostInvocationAttributeFactory.java
rename to access/src/main/java/org/springframework/security/access/prepost/PrePostInvocationAttributeFactory.java
diff --git a/access/src/main/java/org/springframework/security/access/prepost/package-info.java b/access/src/main/java/org/springframework/security/access/prepost/package-info.java
new file mode 100644
index 0000000000..d4322df1a4
--- /dev/null
+++ b/access/src/main/java/org/springframework/security/access/prepost/package-info.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2004-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Contains the infrastructure classes for handling the {@code @PreAuthorize},
+ * {@code @PreFilter}, {@code @PostAuthorize} and {@code @PostFilter} annotations.
+ *
+ * Other than the annotations themselves, the classes should be regarded as for internal
+ * framework use and are liable to change without notice.
+ */
+@NullMarked
+package org.springframework.security.access.prepost;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/core/src/main/java/org/springframework/security/access/vote/AbstractAccessDecisionManager.java b/access/src/main/java/org/springframework/security/access/vote/AbstractAccessDecisionManager.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/vote/AbstractAccessDecisionManager.java
rename to access/src/main/java/org/springframework/security/access/vote/AbstractAccessDecisionManager.java
diff --git a/core/src/main/java/org/springframework/security/access/vote/AbstractAclVoter.java b/access/src/main/java/org/springframework/security/access/vote/AbstractAclVoter.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/vote/AbstractAclVoter.java
rename to access/src/main/java/org/springframework/security/access/vote/AbstractAclVoter.java
diff --git a/core/src/main/java/org/springframework/security/access/vote/AffirmativeBased.java b/access/src/main/java/org/springframework/security/access/vote/AffirmativeBased.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/vote/AffirmativeBased.java
rename to access/src/main/java/org/springframework/security/access/vote/AffirmativeBased.java
diff --git a/core/src/main/java/org/springframework/security/access/vote/AuthenticatedVoter.java b/access/src/main/java/org/springframework/security/access/vote/AuthenticatedVoter.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/vote/AuthenticatedVoter.java
rename to access/src/main/java/org/springframework/security/access/vote/AuthenticatedVoter.java
diff --git a/core/src/main/java/org/springframework/security/access/vote/ConsensusBased.java b/access/src/main/java/org/springframework/security/access/vote/ConsensusBased.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/vote/ConsensusBased.java
rename to access/src/main/java/org/springframework/security/access/vote/ConsensusBased.java
diff --git a/core/src/main/java/org/springframework/security/access/vote/RoleHierarchyVoter.java b/access/src/main/java/org/springframework/security/access/vote/RoleHierarchyVoter.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/vote/RoleHierarchyVoter.java
rename to access/src/main/java/org/springframework/security/access/vote/RoleHierarchyVoter.java
diff --git a/core/src/main/java/org/springframework/security/access/vote/RoleVoter.java b/access/src/main/java/org/springframework/security/access/vote/RoleVoter.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/vote/RoleVoter.java
rename to access/src/main/java/org/springframework/security/access/vote/RoleVoter.java
diff --git a/core/src/main/java/org/springframework/security/access/vote/UnanimousBased.java b/access/src/main/java/org/springframework/security/access/vote/UnanimousBased.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/vote/UnanimousBased.java
rename to access/src/main/java/org/springframework/security/access/vote/UnanimousBased.java
diff --git a/core/src/main/java/org/springframework/security/access/vote/package-info.java b/access/src/main/java/org/springframework/security/access/vote/package-info.java
similarity index 100%
rename from core/src/main/java/org/springframework/security/access/vote/package-info.java
rename to access/src/main/java/org/springframework/security/access/vote/package-info.java
diff --git a/acl/src/main/java/org/springframework/security/acls/AclEntryVoter.java b/access/src/main/java/org/springframework/security/acls/AclEntryVoter.java
similarity index 100%
rename from acl/src/main/java/org/springframework/security/acls/AclEntryVoter.java
rename to access/src/main/java/org/springframework/security/acls/AclEntryVoter.java
diff --git a/acl/src/main/java/org/springframework/security/acls/afterinvocation/AbstractAclProvider.java b/access/src/main/java/org/springframework/security/acls/afterinvocation/AbstractAclProvider.java
similarity index 100%
rename from acl/src/main/java/org/springframework/security/acls/afterinvocation/AbstractAclProvider.java
rename to access/src/main/java/org/springframework/security/acls/afterinvocation/AbstractAclProvider.java
diff --git a/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java b/access/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java
similarity index 100%
rename from acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java
rename to access/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProvider.java
diff --git a/acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProvider.java b/access/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProvider.java
similarity index 100%
rename from acl/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProvider.java
rename to access/src/main/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProvider.java
diff --git a/acl/src/main/java/org/springframework/security/acls/afterinvocation/ArrayFilterer.java b/access/src/main/java/org/springframework/security/acls/afterinvocation/ArrayFilterer.java
similarity index 100%
rename from acl/src/main/java/org/springframework/security/acls/afterinvocation/ArrayFilterer.java
rename to access/src/main/java/org/springframework/security/acls/afterinvocation/ArrayFilterer.java
diff --git a/acl/src/main/java/org/springframework/security/acls/afterinvocation/CollectionFilterer.java b/access/src/main/java/org/springframework/security/acls/afterinvocation/CollectionFilterer.java
similarity index 100%
rename from acl/src/main/java/org/springframework/security/acls/afterinvocation/CollectionFilterer.java
rename to access/src/main/java/org/springframework/security/acls/afterinvocation/CollectionFilterer.java
diff --git a/acl/src/main/java/org/springframework/security/acls/afterinvocation/Filterer.java b/access/src/main/java/org/springframework/security/acls/afterinvocation/Filterer.java
similarity index 100%
rename from acl/src/main/java/org/springframework/security/acls/afterinvocation/Filterer.java
rename to access/src/main/java/org/springframework/security/acls/afterinvocation/Filterer.java
diff --git a/acl/src/main/java/org/springframework/security/acls/afterinvocation/package-info.java b/access/src/main/java/org/springframework/security/acls/afterinvocation/package-info.java
similarity index 100%
rename from acl/src/main/java/org/springframework/security/acls/afterinvocation/package-info.java
rename to access/src/main/java/org/springframework/security/acls/afterinvocation/package-info.java
diff --git a/messaging/src/main/java/org/springframework/security/messaging/access/expression/EvaluationContextPostProcessor.java b/access/src/main/java/org/springframework/security/messaging/access/expression/EvaluationContextPostProcessor.java
similarity index 100%
rename from messaging/src/main/java/org/springframework/security/messaging/access/expression/EvaluationContextPostProcessor.java
rename to access/src/main/java/org/springframework/security/messaging/access/expression/EvaluationContextPostProcessor.java
diff --git a/messaging/src/main/java/org/springframework/security/messaging/access/expression/ExpressionBasedMessageSecurityMetadataSourceFactory.java b/access/src/main/java/org/springframework/security/messaging/access/expression/ExpressionBasedMessageSecurityMetadataSourceFactory.java
similarity index 100%
rename from messaging/src/main/java/org/springframework/security/messaging/access/expression/ExpressionBasedMessageSecurityMetadataSourceFactory.java
rename to access/src/main/java/org/springframework/security/messaging/access/expression/ExpressionBasedMessageSecurityMetadataSourceFactory.java
diff --git a/messaging/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionConfigAttribute.java b/access/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionConfigAttribute.java
similarity index 100%
rename from messaging/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionConfigAttribute.java
rename to access/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionConfigAttribute.java
diff --git a/messaging/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionVoter.java b/access/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionVoter.java
similarity index 100%
rename from messaging/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionVoter.java
rename to access/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionVoter.java
diff --git a/messaging/src/main/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptor.java b/access/src/main/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptor.java
similarity index 98%
rename from messaging/src/main/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptor.java
rename to access/src/main/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptor.java
index d4863b6919..9e6fc2aae6 100644
--- a/messaging/src/main/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptor.java
+++ b/access/src/main/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptor.java
@@ -38,7 +38,7 @@ import org.springframework.util.Assert;
*
* @author Rob Winch
* @since 4.0
- * @deprecated Use {@link AuthorizationChannelInterceptor} instead
+ * @deprecated Use {@code AuthorizationChannelInterceptor} instead
*/
@Deprecated
public final class ChannelSecurityInterceptor extends AbstractSecurityInterceptor implements ChannelInterceptor {
diff --git a/messaging/src/main/java/org/springframework/security/messaging/access/intercept/DefaultMessageSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/messaging/access/intercept/DefaultMessageSecurityMetadataSource.java
similarity index 100%
rename from messaging/src/main/java/org/springframework/security/messaging/access/intercept/DefaultMessageSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/messaging/access/intercept/DefaultMessageSecurityMetadataSource.java
diff --git a/messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource.java
similarity index 100%
rename from messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource.java
diff --git a/web/src/main/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluator.java b/access/src/main/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluator.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluator.java
rename to access/src/main/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluator.java
diff --git a/web/src/main/java/org/springframework/security/web/access/channel/AbstractRetryEntryPoint.java b/access/src/main/java/org/springframework/security/web/access/channel/AbstractRetryEntryPoint.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/channel/AbstractRetryEntryPoint.java
rename to access/src/main/java/org/springframework/security/web/access/channel/AbstractRetryEntryPoint.java
diff --git a/web/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManager.java b/access/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManager.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManager.java
rename to access/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManager.java
diff --git a/web/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImpl.java b/access/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImpl.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImpl.java
rename to access/src/main/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImpl.java
diff --git a/web/src/main/java/org/springframework/security/web/access/channel/ChannelEntryPoint.java b/access/src/main/java/org/springframework/security/web/access/channel/ChannelEntryPoint.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/channel/ChannelEntryPoint.java
rename to access/src/main/java/org/springframework/security/web/access/channel/ChannelEntryPoint.java
diff --git a/web/src/main/java/org/springframework/security/web/access/channel/ChannelProcessingFilter.java b/access/src/main/java/org/springframework/security/web/access/channel/ChannelProcessingFilter.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/channel/ChannelProcessingFilter.java
rename to access/src/main/java/org/springframework/security/web/access/channel/ChannelProcessingFilter.java
diff --git a/web/src/main/java/org/springframework/security/web/access/channel/ChannelProcessor.java b/access/src/main/java/org/springframework/security/web/access/channel/ChannelProcessor.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/channel/ChannelProcessor.java
rename to access/src/main/java/org/springframework/security/web/access/channel/ChannelProcessor.java
diff --git a/web/src/main/java/org/springframework/security/web/access/channel/InsecureChannelProcessor.java b/access/src/main/java/org/springframework/security/web/access/channel/InsecureChannelProcessor.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/channel/InsecureChannelProcessor.java
rename to access/src/main/java/org/springframework/security/web/access/channel/InsecureChannelProcessor.java
diff --git a/web/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPoint.java b/access/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPoint.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPoint.java
rename to access/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPoint.java
diff --git a/web/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPoint.java b/access/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPoint.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPoint.java
rename to access/src/main/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPoint.java
diff --git a/web/src/main/java/org/springframework/security/web/access/channel/SecureChannelProcessor.java b/access/src/main/java/org/springframework/security/web/access/channel/SecureChannelProcessor.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/channel/SecureChannelProcessor.java
rename to access/src/main/java/org/springframework/security/web/access/channel/SecureChannelProcessor.java
diff --git a/web/src/main/java/org/springframework/security/web/access/channel/package-info.java b/access/src/main/java/org/springframework/security/web/access/channel/package-info.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/channel/package-info.java
rename to access/src/main/java/org/springframework/security/web/access/channel/package-info.java
diff --git a/web/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java b/access/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java
rename to access/src/main/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandler.java
diff --git a/web/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSource.java
diff --git a/web/src/main/java/org/springframework/security/web/access/expression/WebExpressionConfigAttribute.java b/access/src/main/java/org/springframework/security/web/access/expression/WebExpressionConfigAttribute.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/expression/WebExpressionConfigAttribute.java
rename to access/src/main/java/org/springframework/security/web/access/expression/WebExpressionConfigAttribute.java
diff --git a/web/src/main/java/org/springframework/security/web/access/expression/WebExpressionVoter.java b/access/src/main/java/org/springframework/security/web/access/expression/WebExpressionVoter.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/expression/WebExpressionVoter.java
rename to access/src/main/java/org/springframework/security/web/access/expression/WebExpressionVoter.java
diff --git a/web/src/main/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSource.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSource.java
diff --git a/web/src/main/java/org/springframework/security/web/access/intercept/FilterInvocationSecurityMetadataSource.java b/access/src/main/java/org/springframework/security/web/access/intercept/FilterInvocationSecurityMetadataSource.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/intercept/FilterInvocationSecurityMetadataSource.java
rename to access/src/main/java/org/springframework/security/web/access/intercept/FilterInvocationSecurityMetadataSource.java
diff --git a/web/src/main/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptor.java b/access/src/main/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptor.java
similarity index 100%
rename from web/src/main/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptor.java
rename to access/src/main/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptor.java
diff --git a/core/src/test/java/org/springframework/security/access/AuthenticationCredentialsNotFoundEventTests.java b/access/src/test/java/org/springframework/security/access/AuthenticationCredentialsNotFoundEventTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/AuthenticationCredentialsNotFoundEventTests.java
rename to access/src/test/java/org/springframework/security/access/AuthenticationCredentialsNotFoundEventTests.java
diff --git a/core/src/test/java/org/springframework/security/access/AuthorizationFailureEventTests.java b/access/src/test/java/org/springframework/security/access/AuthorizationFailureEventTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/AuthorizationFailureEventTests.java
rename to access/src/test/java/org/springframework/security/access/AuthorizationFailureEventTests.java
diff --git a/core/src/test/java/org/springframework/security/access/AuthorizedEventTests.java b/access/src/test/java/org/springframework/security/access/AuthorizedEventTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/AuthorizedEventTests.java
rename to access/src/test/java/org/springframework/security/access/AuthorizedEventTests.java
diff --git a/access/src/test/java/org/springframework/security/access/ITargetObject.java b/access/src/test/java/org/springframework/security/access/ITargetObject.java
new file mode 100644
index 0000000000..9929eb53ba
--- /dev/null
+++ b/access/src/test/java/org/springframework/security/access/ITargetObject.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.access;
+
+/**
+ * Represents the interface of a secured object.
+ *
+ * @author Ben Alex
+ */
+public interface ITargetObject {
+
+ Integer computeHashCode(String input);
+
+ int countLength(String input);
+
+ String makeLowerCase(String input);
+
+ String makeUpperCase(String input);
+
+ String publicMakeLowerCase(String input);
+
+}
diff --git a/access/src/test/java/org/springframework/security/access/OtherTargetObject.java b/access/src/test/java/org/springframework/security/access/OtherTargetObject.java
new file mode 100644
index 0000000000..c4ea9a2fb3
--- /dev/null
+++ b/access/src/test/java/org/springframework/security/access/OtherTargetObject.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.access;
+
+/**
+ * Simply extends {@link TargetObject} so we have a different object to put configuration
+ * attributes against.
+ *
+ * There is no different behaviour. We have to define each method so that
+ * Class.getMethod(methodName, args) returns a Method
+ * referencing this class rather than the parent class.
+ *
+ *
+ * We need to implement ITargetObject again because the
+ * MethodDefinitionAttributes only locates attributes on interfaces
+ * explicitly defined by the intercepted class (not the interfaces defined by its parent
+ * class or classes).
+ *
+ *
+ * @author Ben Alex
+ */
+public class OtherTargetObject extends TargetObject implements ITargetObject {
+
+ @Override
+ public String makeLowerCase(String input) {
+ return super.makeLowerCase(input);
+ }
+
+ @Override
+ public String makeUpperCase(String input) {
+ return super.makeUpperCase(input);
+ }
+
+ @Override
+ public String publicMakeLowerCase(String input) {
+ return super.publicMakeLowerCase(input);
+ }
+
+}
diff --git a/core/src/test/java/org/springframework/security/access/SecurityConfigTests.java b/access/src/test/java/org/springframework/security/access/SecurityConfigTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/SecurityConfigTests.java
rename to access/src/test/java/org/springframework/security/access/SecurityConfigTests.java
diff --git a/access/src/test/java/org/springframework/security/access/TargetObject.java b/access/src/test/java/org/springframework/security/access/TargetObject.java
new file mode 100644
index 0000000000..7af0aff10d
--- /dev/null
+++ b/access/src/test/java/org/springframework/security/access/TargetObject.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.access;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+/**
+ * Represents a secured object.
+ *
+ * @author Ben Alex
+ */
+public class TargetObject implements ITargetObject {
+
+ @Override
+ public Integer computeHashCode(String input) {
+ return input.hashCode();
+ }
+
+ @Override
+ public int countLength(String input) {
+ return input.length();
+ }
+
+ /**
+ * Returns the lowercase string, followed by security environment information.
+ * @param input the message to make lowercase
+ * @return the lowercase message, a space, the Authentication class that
+ * was on the SecurityContext at the time of method invocation, and a
+ * boolean indicating if the Authentication object is authenticated or
+ * not
+ */
+ @Override
+ public String makeLowerCase(String input) {
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+ if (auth == null) {
+ return input.toLowerCase() + " Authentication empty";
+ }
+ else {
+ return input.toLowerCase() + " " + auth.getClass().getName() + " " + auth.isAuthenticated();
+ }
+ }
+
+ /**
+ * Returns the uppercase string, followed by security environment information.
+ * @param input the message to make uppercase
+ * @return the uppercase message, a space, the Authentication class that
+ * was on the SecurityContext at the time of method invocation, and a
+ * boolean indicating if the Authentication object is authenticated or
+ * not
+ */
+ @Override
+ public String makeUpperCase(String input) {
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+ return input.toUpperCase() + " " + auth.getClass().getName() + " " + auth.isAuthenticated();
+ }
+
+ /**
+ * Delegates through to the {@link #makeLowerCase(String)} method.
+ * @param input the message to be made lower-case
+ */
+ @Override
+ public String publicMakeLowerCase(String input) {
+ return this.makeLowerCase(input);
+ }
+
+}
diff --git a/core/src/test/java/org/springframework/security/access/annotation/BusinessService.java b/access/src/test/java/org/springframework/security/access/annotation/BusinessService.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/BusinessService.java
rename to access/src/test/java/org/springframework/security/access/annotation/BusinessService.java
diff --git a/core/src/test/java/org/springframework/security/access/annotation/BusinessServiceImpl.java b/access/src/test/java/org/springframework/security/access/annotation/BusinessServiceImpl.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/BusinessServiceImpl.java
rename to access/src/test/java/org/springframework/security/access/annotation/BusinessServiceImpl.java
diff --git a/core/src/test/java/org/springframework/security/access/annotation/Entity.java b/access/src/test/java/org/springframework/security/access/annotation/Entity.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/Entity.java
rename to access/src/test/java/org/springframework/security/access/annotation/Entity.java
diff --git a/core/src/test/java/org/springframework/security/access/annotation/ExpressionProtectedBusinessServiceImpl.java b/access/src/test/java/org/springframework/security/access/annotation/ExpressionProtectedBusinessServiceImpl.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/ExpressionProtectedBusinessServiceImpl.java
rename to access/src/test/java/org/springframework/security/access/annotation/ExpressionProtectedBusinessServiceImpl.java
diff --git a/core/src/test/java/org/springframework/security/access/annotation/Jsr250BusinessServiceImpl.java b/access/src/test/java/org/springframework/security/access/annotation/Jsr250BusinessServiceImpl.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/Jsr250BusinessServiceImpl.java
rename to access/src/test/java/org/springframework/security/access/annotation/Jsr250BusinessServiceImpl.java
diff --git a/core/src/test/java/org/springframework/security/access/annotation/Jsr250MethodSecurityMetadataSourceTests.java b/access/src/test/java/org/springframework/security/access/annotation/Jsr250MethodSecurityMetadataSourceTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/Jsr250MethodSecurityMetadataSourceTests.java
rename to access/src/test/java/org/springframework/security/access/annotation/Jsr250MethodSecurityMetadataSourceTests.java
diff --git a/core/src/test/java/org/springframework/security/access/annotation/Jsr250VoterTests.java b/access/src/test/java/org/springframework/security/access/annotation/Jsr250VoterTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/Jsr250VoterTests.java
rename to access/src/test/java/org/springframework/security/access/annotation/Jsr250VoterTests.java
diff --git a/core/src/test/java/org/springframework/security/access/annotation/RequireAdminRole.java b/access/src/test/java/org/springframework/security/access/annotation/RequireAdminRole.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/RequireAdminRole.java
rename to access/src/test/java/org/springframework/security/access/annotation/RequireAdminRole.java
diff --git a/core/src/test/java/org/springframework/security/access/annotation/RequireUserRole.java b/access/src/test/java/org/springframework/security/access/annotation/RequireUserRole.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/RequireUserRole.java
rename to access/src/test/java/org/springframework/security/access/annotation/RequireUserRole.java
diff --git a/core/src/test/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSourceTests.java b/access/src/test/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSourceTests.java
similarity index 98%
rename from core/src/test/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSourceTests.java
rename to access/src/test/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSourceTests.java
index 71d96ed75a..e4b5235f16 100644
--- a/core/src/test/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSourceTests.java
+++ b/access/src/test/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSourceTests.java
@@ -39,8 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
/**
- * Tests for
- * {@link org.springframework.security.access.annotation.SecuredAnnotationSecurityMetadataSource}
+ * Tests for {@link SecuredAnnotationSecurityMetadataSource}
*
* @author Mark St.Godard
* @author Joe Scalise
diff --git a/core/src/test/java/org/springframework/security/access/annotation/sec2150/CrudRepository.java b/access/src/test/java/org/springframework/security/access/annotation/sec2150/CrudRepository.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/sec2150/CrudRepository.java
rename to access/src/test/java/org/springframework/security/access/annotation/sec2150/CrudRepository.java
diff --git a/core/src/test/java/org/springframework/security/access/annotation/sec2150/MethodInvocationFactory.java b/access/src/test/java/org/springframework/security/access/annotation/sec2150/MethodInvocationFactory.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/sec2150/MethodInvocationFactory.java
rename to access/src/test/java/org/springframework/security/access/annotation/sec2150/MethodInvocationFactory.java
diff --git a/core/src/test/java/org/springframework/security/access/annotation/sec2150/PersonRepository.java b/access/src/test/java/org/springframework/security/access/annotation/sec2150/PersonRepository.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/annotation/sec2150/PersonRepository.java
rename to access/src/test/java/org/springframework/security/access/annotation/sec2150/PersonRepository.java
diff --git a/core/src/test/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandlerTests.java b/access/src/test/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandlerTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandlerTests.java
rename to access/src/test/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandlerTests.java
diff --git a/core/src/test/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdviceTests.java b/access/src/test/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdviceTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdviceTests.java
rename to access/src/test/java/org/springframework/security/access/expression/method/ExpressionBasedPreInvocationAdviceTests.java
diff --git a/core/src/test/java/org/springframework/security/access/expression/method/MethodExpressionVoterTests.java b/access/src/test/java/org/springframework/security/access/expression/method/MethodExpressionVoterTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/expression/method/MethodExpressionVoterTests.java
rename to access/src/test/java/org/springframework/security/access/expression/method/MethodExpressionVoterTests.java
diff --git a/core/src/test/java/org/springframework/security/access/expression/method/MethodSecurityEvaluationContextTests.java b/access/src/test/java/org/springframework/security/access/expression/method/MethodSecurityEvaluationContextTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/expression/method/MethodSecurityEvaluationContextTests.java
rename to access/src/test/java/org/springframework/security/access/expression/method/MethodSecurityEvaluationContextTests.java
diff --git a/core/src/test/java/org/springframework/security/access/expression/method/MethodSecurityExpressionRootTests.java b/access/src/test/java/org/springframework/security/access/expression/method/MethodSecurityExpressionRootTests.java
similarity index 84%
rename from core/src/test/java/org/springframework/security/access/expression/method/MethodSecurityExpressionRootTests.java
rename to access/src/test/java/org/springframework/security/access/expression/method/MethodSecurityExpressionRootTests.java
index 6f65547e91..a908236c99 100644
--- a/core/src/test/java/org/springframework/security/access/expression/method/MethodSecurityExpressionRootTests.java
+++ b/access/src/test/java/org/springframework/security/access/expression/method/MethodSecurityExpressionRootTests.java
@@ -17,6 +17,7 @@
package org.springframework.security.access.expression.method;
import org.aopalliance.intercept.MethodInvocation;
+import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -28,7 +29,6 @@ import org.springframework.security.access.expression.ExpressionUtils;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.core.Authentication;
-import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
@@ -65,19 +65,19 @@ public class MethodSecurityExpressionRootTests {
public void canCallMethodsOnVariables() {
this.ctx.setVariable("var", "somestring");
Expression e = this.parser.parseExpression("#var.length() == 10");
- assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
+ Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
}
@Test
public void isAnonymousReturnsTrueIfTrustResolverReportsAnonymous() {
given(this.trustResolver.isAnonymous(this.user)).willReturn(true);
- assertThat(this.root.isAnonymous()).isTrue();
+ Assertions.assertThat(this.root.isAnonymous()).isTrue();
}
@Test
public void isAnonymousReturnsFalseIfTrustResolverReportsNonAnonymous() {
given(this.trustResolver.isAnonymous(this.user)).willReturn(false);
- assertThat(this.root.isAnonymous()).isFalse();
+ Assertions.assertThat(this.root.isAnonymous()).isFalse();
}
@Test
@@ -87,7 +87,7 @@ public class MethodSecurityExpressionRootTests {
this.ctx.setVariable("domainObject", dummyDomainObject);
this.root.setPermissionEvaluator(pe);
given(pe.hasPermission(this.user, dummyDomainObject, "ignored")).willReturn(false);
- assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isFalse();
+ Assertions.assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isFalse();
}
@Test
@@ -97,7 +97,7 @@ public class MethodSecurityExpressionRootTests {
this.ctx.setVariable("domainObject", dummyDomainObject);
this.root.setPermissionEvaluator(pe);
given(pe.hasPermission(this.user, dummyDomainObject, "ignored")).willReturn(true);
- assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isTrue();
+ Assertions.assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isTrue();
}
@Test
@@ -109,13 +109,13 @@ public class MethodSecurityExpressionRootTests {
given(pe.hasPermission(eq(this.user), eq(dummyDomainObject), any(Integer.class))).willReturn(true, true, false);
Expression e = this.parser.parseExpression("hasPermission(#domainObject, 0xA)");
// evaluator returns true
- assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
+ Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
e = this.parser.parseExpression("hasPermission(#domainObject, 10)");
// evaluator returns true
- assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
+ Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
e = this.parser.parseExpression("hasPermission(#domainObject, 0xFF)");
// evaluator returns false, make sure return value matches
- assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
+ Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
}
@Test
@@ -132,11 +132,11 @@ public class MethodSecurityExpressionRootTests {
given(pe.hasPermission(this.user, targetObject, i)).willReturn(true, false);
given(pe.hasPermission(this.user, "x", i)).willReturn(true);
Expression e = this.parser.parseExpression("hasPermission(this, 2)");
- assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
+ Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
e = this.parser.parseExpression("hasPermission(this, 2)");
- assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
+ Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
e = this.parser.parseExpression("hasPermission(this.x, 2)");
- assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
+ Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
}
}
diff --git a/core/src/test/java/org/springframework/security/access/expression/method/PrePostAnnotationSecurityMetadataSourceTests.java b/access/src/test/java/org/springframework/security/access/expression/method/PrePostAnnotationSecurityMetadataSourceTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/expression/method/PrePostAnnotationSecurityMetadataSourceTests.java
rename to access/src/test/java/org/springframework/security/access/expression/method/PrePostAnnotationSecurityMetadataSourceTests.java
diff --git a/core/src/test/java/org/springframework/security/access/expression/method/SecurityRules.java b/access/src/test/java/org/springframework/security/access/expression/method/SecurityRules.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/expression/method/SecurityRules.java
rename to access/src/test/java/org/springframework/security/access/expression/method/SecurityRules.java
diff --git a/core/src/test/java/org/springframework/security/access/intercept/AbstractSecurityInterceptorTests.java b/access/src/test/java/org/springframework/security/access/intercept/AbstractSecurityInterceptorTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/intercept/AbstractSecurityInterceptorTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/AbstractSecurityInterceptorTests.java
diff --git a/core/src/test/java/org/springframework/security/access/intercept/AfterInvocationProviderManagerTests.java b/access/src/test/java/org/springframework/security/access/intercept/AfterInvocationProviderManagerTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/intercept/AfterInvocationProviderManagerTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/AfterInvocationProviderManagerTests.java
diff --git a/core/src/test/java/org/springframework/security/access/intercept/InterceptorStatusTokenTests.java b/access/src/test/java/org/springframework/security/access/intercept/InterceptorStatusTokenTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/intercept/InterceptorStatusTokenTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/InterceptorStatusTokenTests.java
diff --git a/core/src/test/java/org/springframework/security/access/intercept/NullRunAsManagerTests.java b/access/src/test/java/org/springframework/security/access/intercept/NullRunAsManagerTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/intercept/NullRunAsManagerTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/NullRunAsManagerTests.java
diff --git a/core/src/test/java/org/springframework/security/access/intercept/RunAsImplAuthenticationProviderTests.java b/access/src/test/java/org/springframework/security/access/intercept/RunAsImplAuthenticationProviderTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/intercept/RunAsImplAuthenticationProviderTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/RunAsImplAuthenticationProviderTests.java
diff --git a/core/src/test/java/org/springframework/security/access/intercept/RunAsManagerImplTests.java b/access/src/test/java/org/springframework/security/access/intercept/RunAsManagerImplTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/intercept/RunAsManagerImplTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/RunAsManagerImplTests.java
diff --git a/core/src/test/java/org/springframework/security/access/intercept/RunAsUserTokenTests.java b/access/src/test/java/org/springframework/security/access/intercept/RunAsUserTokenTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/intercept/RunAsUserTokenTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/RunAsUserTokenTests.java
diff --git a/core/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptorTests.java b/access/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptorTests.java
similarity index 99%
rename from core/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptorTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptorTests.java
index a120f7eb63..9b0ca1577d 100644
--- a/core/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptorTests.java
+++ b/access/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityInterceptorTests.java
@@ -25,12 +25,12 @@ import org.junit.jupiter.api.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.security.ITargetObject;
-import org.springframework.security.TargetObject;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
+import org.springframework.security.access.ITargetObject;
import org.springframework.security.access.SecurityConfig;
+import org.springframework.security.access.TargetObject;
import org.springframework.security.access.event.AuthorizationFailureEvent;
import org.springframework.security.access.event.AuthorizedEvent;
import org.springframework.security.access.intercept.AfterInvocationManager;
diff --git a/core/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityMetadataSourceAdvisorTests.java b/access/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityMetadataSourceAdvisorTests.java
similarity index 97%
rename from core/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityMetadataSourceAdvisorTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityMetadataSourceAdvisorTests.java
index 60c95f8cbb..b8e314e423 100644
--- a/core/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityMetadataSourceAdvisorTests.java
+++ b/access/src/test/java/org/springframework/security/access/intercept/aopalliance/MethodSecurityMetadataSourceAdvisorTests.java
@@ -20,8 +20,8 @@ import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;
-import org.springframework.security.TargetObject;
import org.springframework.security.access.SecurityConfig;
+import org.springframework.security.access.TargetObject;
import org.springframework.security.access.method.MethodSecurityMetadataSource;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/core/src/test/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptorTests.java b/access/src/test/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptorTests.java
similarity index 99%
rename from core/src/test/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptorTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptorTests.java
index 4afe87616d..0c80f07e77 100644
--- a/core/src/test/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptorTests.java
+++ b/access/src/test/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptorTests.java
@@ -30,10 +30,10 @@ import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import org.springframework.security.TargetObject;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.SecurityConfig;
+import org.springframework.security.access.TargetObject;
import org.springframework.security.access.intercept.AfterInvocationManager;
import org.springframework.security.access.intercept.RunAsManager;
import org.springframework.security.access.intercept.RunAsUserToken;
diff --git a/core/src/test/java/org/springframework/security/access/intercept/method/MapBasedMethodSecurityMetadataSourceTests.java b/access/src/test/java/org/springframework/security/access/intercept/method/MapBasedMethodSecurityMetadataSourceTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/intercept/method/MapBasedMethodSecurityMetadataSourceTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/method/MapBasedMethodSecurityMetadataSourceTests.java
diff --git a/core/src/test/java/org/springframework/security/access/intercept/method/MethodInvocationPrivilegeEvaluatorTests.java b/access/src/test/java/org/springframework/security/access/intercept/method/MethodInvocationPrivilegeEvaluatorTests.java
similarity index 96%
rename from core/src/test/java/org/springframework/security/access/intercept/method/MethodInvocationPrivilegeEvaluatorTests.java
rename to access/src/test/java/org/springframework/security/access/intercept/method/MethodInvocationPrivilegeEvaluatorTests.java
index 93482a82cb..4780a8cc44 100644
--- a/core/src/test/java/org/springframework/security/access/intercept/method/MethodInvocationPrivilegeEvaluatorTests.java
+++ b/access/src/test/java/org/springframework/security/access/intercept/method/MethodInvocationPrivilegeEvaluatorTests.java
@@ -22,13 +22,13 @@ import org.aopalliance.intercept.MethodInvocation;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.springframework.security.ITargetObject;
-import org.springframework.security.OtherTargetObject;
-import org.springframework.security.TargetObject;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
+import org.springframework.security.access.ITargetObject;
+import org.springframework.security.access.OtherTargetObject;
import org.springframework.security.access.SecurityConfig;
+import org.springframework.security.access.TargetObject;
import org.springframework.security.access.intercept.MethodInvocationPrivilegeEvaluator;
import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor;
import org.springframework.security.access.method.MethodSecurityMetadataSource;
diff --git a/core/src/test/java/org/springframework/security/access/intercept/method/MockMethodInvocation.java b/access/src/test/java/org/springframework/security/access/intercept/method/MockMethodInvocation.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/intercept/method/MockMethodInvocation.java
rename to access/src/test/java/org/springframework/security/access/intercept/method/MockMethodInvocation.java
diff --git a/core/src/test/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSourceTests.java b/access/src/test/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSourceTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSourceTests.java
rename to access/src/test/java/org/springframework/security/access/method/DelegatingMethodSecurityMetadataSourceTests.java
diff --git a/core/src/test/java/org/springframework/security/access/prepost/PostInvocationAdviceProviderTests.java b/access/src/test/java/org/springframework/security/access/prepost/PostInvocationAdviceProviderTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/prepost/PostInvocationAdviceProviderTests.java
rename to access/src/test/java/org/springframework/security/access/prepost/PostInvocationAdviceProviderTests.java
diff --git a/core/src/test/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdviceVoterTests.java b/access/src/test/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdviceVoterTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdviceVoterTests.java
rename to access/src/test/java/org/springframework/security/access/prepost/PreInvocationAuthorizationAdviceVoterTests.java
diff --git a/core/src/test/java/org/springframework/security/access/vote/AbstractAccessDecisionManagerTests.java b/access/src/test/java/org/springframework/security/access/vote/AbstractAccessDecisionManagerTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/vote/AbstractAccessDecisionManagerTests.java
rename to access/src/test/java/org/springframework/security/access/vote/AbstractAccessDecisionManagerTests.java
diff --git a/core/src/test/java/org/springframework/security/access/vote/AbstractAclVoterTests.java b/access/src/test/java/org/springframework/security/access/vote/AbstractAclVoterTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/vote/AbstractAclVoterTests.java
rename to access/src/test/java/org/springframework/security/access/vote/AbstractAclVoterTests.java
diff --git a/core/src/test/java/org/springframework/security/access/vote/AffirmativeBasedTests.java b/access/src/test/java/org/springframework/security/access/vote/AffirmativeBasedTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/vote/AffirmativeBasedTests.java
rename to access/src/test/java/org/springframework/security/access/vote/AffirmativeBasedTests.java
diff --git a/core/src/test/java/org/springframework/security/access/vote/AuthenticatedVoterTests.java b/access/src/test/java/org/springframework/security/access/vote/AuthenticatedVoterTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/vote/AuthenticatedVoterTests.java
rename to access/src/test/java/org/springframework/security/access/vote/AuthenticatedVoterTests.java
diff --git a/core/src/test/java/org/springframework/security/access/vote/ConsensusBasedTests.java b/access/src/test/java/org/springframework/security/access/vote/ConsensusBasedTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/vote/ConsensusBasedTests.java
rename to access/src/test/java/org/springframework/security/access/vote/ConsensusBasedTests.java
diff --git a/core/src/test/java/org/springframework/security/access/vote/DenyAgainVoter.java b/access/src/test/java/org/springframework/security/access/vote/DenyAgainVoter.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/vote/DenyAgainVoter.java
rename to access/src/test/java/org/springframework/security/access/vote/DenyAgainVoter.java
diff --git a/core/src/test/java/org/springframework/security/access/vote/DenyVoter.java b/access/src/test/java/org/springframework/security/access/vote/DenyVoter.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/vote/DenyVoter.java
rename to access/src/test/java/org/springframework/security/access/vote/DenyVoter.java
diff --git a/core/src/test/java/org/springframework/security/access/vote/RoleHierarchyVoterTests.java b/access/src/test/java/org/springframework/security/access/vote/RoleHierarchyVoterTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/vote/RoleHierarchyVoterTests.java
rename to access/src/test/java/org/springframework/security/access/vote/RoleHierarchyVoterTests.java
diff --git a/core/src/test/java/org/springframework/security/access/vote/RoleVoterTests.java b/access/src/test/java/org/springframework/security/access/vote/RoleVoterTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/vote/RoleVoterTests.java
rename to access/src/test/java/org/springframework/security/access/vote/RoleVoterTests.java
diff --git a/core/src/test/java/org/springframework/security/access/vote/UnanimousBasedTests.java b/access/src/test/java/org/springframework/security/access/vote/UnanimousBasedTests.java
similarity index 100%
rename from core/src/test/java/org/springframework/security/access/vote/UnanimousBasedTests.java
rename to access/src/test/java/org/springframework/security/access/vote/UnanimousBasedTests.java
diff --git a/acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProviderTests.java b/access/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProviderTests.java
similarity index 100%
rename from acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProviderTests.java
rename to access/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationCollectionFilteringProviderTests.java
diff --git a/acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProviderTests.java b/access/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProviderTests.java
similarity index 100%
rename from acl/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProviderTests.java
rename to access/src/test/java/org/springframework/security/acls/afterinvocation/AclEntryAfterInvocationProviderTests.java
diff --git a/messaging/src/test/java/org/springframework/security/messaging/access/expression/ExpressionBasedMessageSecurityMetadataSourceFactoryTests.java b/access/src/test/java/org/springframework/security/messaging/access/expression/ExpressionBasedMessageSecurityMetadataSourceFactoryTests.java
similarity index 100%
rename from messaging/src/test/java/org/springframework/security/messaging/access/expression/ExpressionBasedMessageSecurityMetadataSourceFactoryTests.java
rename to access/src/test/java/org/springframework/security/messaging/access/expression/ExpressionBasedMessageSecurityMetadataSourceFactoryTests.java
diff --git a/messaging/src/test/java/org/springframework/security/messaging/access/expression/MessageExpressionConfigAttributeTests.java b/access/src/test/java/org/springframework/security/messaging/access/expression/MessageExpressionConfigAttributeTests.java
similarity index 100%
rename from messaging/src/test/java/org/springframework/security/messaging/access/expression/MessageExpressionConfigAttributeTests.java
rename to access/src/test/java/org/springframework/security/messaging/access/expression/MessageExpressionConfigAttributeTests.java
diff --git a/messaging/src/test/java/org/springframework/security/messaging/access/expression/MessageExpressionVoterTests.java b/access/src/test/java/org/springframework/security/messaging/access/expression/MessageExpressionVoterTests.java
similarity index 100%
rename from messaging/src/test/java/org/springframework/security/messaging/access/expression/MessageExpressionVoterTests.java
rename to access/src/test/java/org/springframework/security/messaging/access/expression/MessageExpressionVoterTests.java
diff --git a/messaging/src/test/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptorTests.java b/access/src/test/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptorTests.java
similarity index 100%
rename from messaging/src/test/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptorTests.java
rename to access/src/test/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptorTests.java
diff --git a/messaging/src/test/java/org/springframework/security/messaging/access/intercept/DefaultMessageSecurityMetadataSourceTests.java b/access/src/test/java/org/springframework/security/messaging/access/intercept/DefaultMessageSecurityMetadataSourceTests.java
similarity index 100%
rename from messaging/src/test/java/org/springframework/security/messaging/access/intercept/DefaultMessageSecurityMetadataSourceTests.java
rename to access/src/test/java/org/springframework/security/messaging/access/intercept/DefaultMessageSecurityMetadataSourceTests.java
diff --git a/web/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java b/access/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java
similarity index 72%
rename from web/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java
rename to access/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java
index 4216da2869..3dd7f12d8e 100644
--- a/web/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java
+++ b/access/src/test/java/org/springframework/security/web/access/DefaultWebInvocationPrivilegeEvaluatorTests.java
@@ -16,9 +16,13 @@
package org.springframework.security.web.access;
+import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
+import org.mockito.BDDMockito;
+import org.mockito.Mockito;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.mock.web.MockServletContext;
@@ -33,15 +37,6 @@ import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyList;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.BDDMockito.willThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
/**
* Tests
* {@link org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator}.
@@ -61,43 +56,45 @@ public class DefaultWebInvocationPrivilegeEvaluatorTests {
@BeforeEach
public final void setUp() {
this.interceptor = new FilterSecurityInterceptor();
- this.ods = mock(FilterInvocationSecurityMetadataSource.class);
- this.adm = mock(AccessDecisionManager.class);
- this.ram = mock(RunAsManager.class);
- this.interceptor.setAuthenticationManager(mock(AuthenticationManager.class));
+ this.ods = Mockito.mock(FilterInvocationSecurityMetadataSource.class);
+ this.adm = Mockito.mock(AccessDecisionManager.class);
+ this.ram = Mockito.mock(RunAsManager.class);
+ this.interceptor.setAuthenticationManager(Mockito.mock(AuthenticationManager.class));
this.interceptor.setSecurityMetadataSource(this.ods);
this.interceptor.setAccessDecisionManager(this.adm);
this.interceptor.setRunAsManager(this.ram);
- this.interceptor.setApplicationEventPublisher(mock(ApplicationEventPublisher.class));
+ this.interceptor.setApplicationEventPublisher(Mockito.mock(ApplicationEventPublisher.class));
SecurityContextHolder.clearContext();
}
@Test
public void permitsAccessIfNoMatchingAttributesAndPublicInvocationsAllowed() {
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
- given(this.ods.getAttributes(any())).willReturn(null);
- assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", mock(Authentication.class))).isTrue();
+ BDDMockito.given(this.ods.getAttributes(ArgumentMatchers.any())).willReturn(null);
+ Assertions.assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", Mockito.mock(Authentication.class)))
+ .isTrue();
}
@Test
public void deniesAccessIfNoMatchingAttributesAndPublicInvocationsNotAllowed() {
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
- given(this.ods.getAttributes(any())).willReturn(null);
+ BDDMockito.given(this.ods.getAttributes(ArgumentMatchers.any())).willReturn(null);
this.interceptor.setRejectPublicInvocations(true);
- assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", mock(Authentication.class))).isFalse();
+ Assertions.assertThat(wipe.isAllowed("/context", "/foo/index.jsp", "GET", Mockito.mock(Authentication.class)))
+ .isFalse();
}
@Test
public void deniesAccessIfAuthenticationIsNull() {
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
- assertThat(wipe.isAllowed("/foo/index.jsp", null)).isFalse();
+ Assertions.assertThat(wipe.isAllowed("/foo/index.jsp", null)).isFalse();
}
@Test
public void allowsAccessIfAccessDecisionManagerDoes() {
Authentication token = new TestingAuthenticationToken("test", "Password", "MOCK_INDEX");
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
- assertThat(wipe.isAllowed("/foo/index.jsp", token)).isTrue();
+ Assertions.assertThat(wipe.isAllowed("/foo/index.jsp", token)).isTrue();
}
@SuppressWarnings("unchecked")
@@ -105,8 +102,10 @@ public class DefaultWebInvocationPrivilegeEvaluatorTests {
public void deniesAccessIfAccessDecisionManagerDoes() {
Authentication token = new TestingAuthenticationToken("test", "Password", "MOCK_INDEX");
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
- willThrow(new AccessDeniedException("")).given(this.adm).decide(any(Authentication.class), any(), anyList());
- assertThat(wipe.isAllowed("/foo/index.jsp", token)).isFalse();
+ BDDMockito.willThrow(new AccessDeniedException(""))
+ .given(this.adm)
+ .decide(ArgumentMatchers.any(Authentication.class), ArgumentMatchers.any(), ArgumentMatchers.anyList());
+ Assertions.assertThat(wipe.isAllowed("/foo/index.jsp", token)).isFalse();
}
@Test
@@ -118,8 +117,9 @@ public class DefaultWebInvocationPrivilegeEvaluatorTests {
DefaultWebInvocationPrivilegeEvaluator wipe = new DefaultWebInvocationPrivilegeEvaluator(this.interceptor);
wipe.setServletContext(servletContext);
wipe.isAllowed("/foo/index.jsp", token);
- verify(this.adm).decide(eq(token), filterInvocationArgumentCaptor.capture(), any());
- assertThat(filterInvocationArgumentCaptor.getValue().getRequest().getServletContext()).isNotNull();
+ Mockito.verify(this.adm)
+ .decide(ArgumentMatchers.eq(token), filterInvocationArgumentCaptor.capture(), ArgumentMatchers.any());
+ Assertions.assertThat(filterInvocationArgumentCaptor.getValue().getRequest().getServletContext()).isNotNull();
}
}
diff --git a/web/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java b/access/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java
similarity index 96%
rename from web/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java
rename to access/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java
index 4ab06ff409..e550801303 100644
--- a/web/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java
+++ b/access/src/test/java/org/springframework/security/web/access/channel/ChannelDecisionManagerImplTests.java
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Vector;
import jakarta.servlet.FilterChain;
+import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
@@ -85,7 +86,7 @@ public class ChannelDecisionManagerImplTests {
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
List cad = SecurityConfig.createList("xyz");
cdm.decide(fi, cad);
- assertThat(fi.getResponse().isCommitted()).isTrue();
+ Assertions.assertThat(fi.getResponse().isCommitted()).isTrue();
}
@Test
@@ -100,7 +101,7 @@ public class ChannelDecisionManagerImplTests {
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
cdm.decide(fi, SecurityConfig.createList(new String[] { "abc", "ANY_CHANNEL" }));
- assertThat(fi.getResponse().isCommitted()).isFalse();
+ Assertions.assertThat(fi.getResponse().isCommitted()).isFalse();
}
@Test
@@ -117,7 +118,7 @@ public class ChannelDecisionManagerImplTests {
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
cdm.decide(fi, SecurityConfig.createList("SOME_ATTRIBUTE_NO_PROCESSORS_SUPPORT"));
- assertThat(fi.getResponse().isCommitted()).isFalse();
+ Assertions.assertThat(fi.getResponse().isCommitted()).isFalse();
}
@Test
diff --git a/web/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java b/access/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java
similarity index 95%
rename from web/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java
rename to access/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java
index ad3f3afa66..d486d36189 100644
--- a/web/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java
+++ b/access/src/test/java/org/springframework/security/web/access/channel/ChannelProcessingFilterTests.java
@@ -28,11 +28,11 @@ import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
+import org.springframework.security.web.servlet.TestMockHttpServletRequests;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.Mockito.mock;
-import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get;
/**
* Tests {@link ChannelProcessingFilter}.
@@ -82,7 +82,7 @@ public class ChannelProcessingFilterTests {
filter.setChannelDecisionManager(new MockChannelDecisionManager(true, "SOME_ATTRIBUTE"));
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
filter.setSecurityMetadataSource(fids);
- MockHttpServletRequest request = get("/path").build();
+ MockHttpServletRequest request = TestMockHttpServletRequests.get("/path").build();
request.setQueryString("info=now");
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, mock(FilterChain.class));
@@ -94,7 +94,7 @@ public class ChannelProcessingFilterTests {
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "SOME_ATTRIBUTE"));
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "SOME_ATTRIBUTE");
filter.setSecurityMetadataSource(fids);
- MockHttpServletRequest request = get("/path").build();
+ MockHttpServletRequest request = TestMockHttpServletRequests.get("/path").build();
request.setQueryString("info=now");
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, mock(FilterChain.class));
@@ -106,7 +106,7 @@ public class ChannelProcessingFilterTests {
filter.setChannelDecisionManager(new MockChannelDecisionManager(false, "NOT_USED"));
MockFilterInvocationDefinitionMap fids = new MockFilterInvocationDefinitionMap("/path", true, "NOT_USED");
filter.setSecurityMetadataSource(fids);
- MockHttpServletRequest request = get("/PATH_NOT_MATCHING_CONFIG_ATTRIBUTE").build();
+ MockHttpServletRequest request = TestMockHttpServletRequests.get("/PATH_NOT_MATCHING_CONFIG_ATTRIBUTE").build();
request.setQueryString("info=now");
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, mock(FilterChain.class));
diff --git a/web/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java b/access/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java
similarity index 88%
rename from web/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java
rename to access/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java
index 1c290cac06..6b4f1d8bae 100644
--- a/web/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java
+++ b/access/src/test/java/org/springframework/security/web/access/channel/InsecureChannelProcessorTests.java
@@ -17,17 +17,18 @@
package org.springframework.security.web.access.channel;
import jakarta.servlet.FilterChain;
+import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
+import org.springframework.security.web.servlet.TestMockHttpServletRequests;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.Mockito.mock;
-import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get;
/**
* Tests {@link InsecureChannelProcessor}.
@@ -38,19 +39,21 @@ public class InsecureChannelProcessorTests {
@Test
public void testDecideDetectsAcceptableChannel() throws Exception {
- MockHttpServletRequest request = get("http://localhost:8080").requestUri("/bigapp", "/servlet", null)
+ MockHttpServletRequest request = TestMockHttpServletRequests.get("http://localhost:8080")
+ .requestUri("/bigapp", "/servlet", null)
.queryString("info=true")
.build();
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
InsecureChannelProcessor processor = new InsecureChannelProcessor();
processor.decide(fi, SecurityConfig.createList("SOME_IGNORED_ATTRIBUTE", "REQUIRES_INSECURE_CHANNEL"));
- assertThat(fi.getResponse().isCommitted()).isFalse();
+ Assertions.assertThat(fi.getResponse().isCommitted()).isFalse();
}
@Test
public void testDecideDetectsUnacceptableChannel() throws Exception {
- MockHttpServletRequest request = get("https://localhost:8443").requestUri("/bigapp", "/servlet", null)
+ MockHttpServletRequest request = TestMockHttpServletRequests.get("https://localhost:8443")
+ .requestUri("/bigapp", "/servlet", null)
.queryString("info=true")
.build();
MockHttpServletResponse response = new MockHttpServletResponse();
@@ -58,7 +61,7 @@ public class InsecureChannelProcessorTests {
InsecureChannelProcessor processor = new InsecureChannelProcessor();
processor.decide(fi,
SecurityConfig.createList(new String[] { "SOME_IGNORED_ATTRIBUTE", "REQUIRES_INSECURE_CHANNEL" }));
- assertThat(fi.getResponse().isCommitted()).isTrue();
+ Assertions.assertThat(fi.getResponse().isCommitted()).isTrue();
}
@Test
diff --git a/web/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPointTests.java b/access/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPointTests.java
similarity index 100%
rename from web/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPointTests.java
rename to access/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpEntryPointTests.java
diff --git a/web/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPointTests.java b/access/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPointTests.java
similarity index 100%
rename from web/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPointTests.java
rename to access/src/test/java/org/springframework/security/web/access/channel/RetryWithHttpsEntryPointTests.java
diff --git a/web/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java b/access/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java
similarity index 88%
rename from web/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java
rename to access/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java
index 4263cec233..f67d0ae7b3 100644
--- a/web/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java
+++ b/access/src/test/java/org/springframework/security/web/access/channel/SecureChannelProcessorTests.java
@@ -17,17 +17,18 @@
package org.springframework.security.web.access.channel;
import jakarta.servlet.FilterChain;
+import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
+import org.springframework.security.web.servlet.TestMockHttpServletRequests;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.Mockito.mock;
-import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get;
/**
* Tests {@link SecureChannelProcessor}.
@@ -38,19 +39,21 @@ public class SecureChannelProcessorTests {
@Test
public void testDecideDetectsAcceptableChannel() throws Exception {
- MockHttpServletRequest request = get("https://localhost:8443").requestUri("/bigapp", "/servlet", null)
+ MockHttpServletRequest request = TestMockHttpServletRequests.get("https://localhost:8443")
+ .requestUri("/bigapp", "/servlet", null)
.queryString("info=true")
.build();
MockHttpServletResponse response = new MockHttpServletResponse();
FilterInvocation fi = new FilterInvocation(request, response, mock(FilterChain.class));
SecureChannelProcessor processor = new SecureChannelProcessor();
processor.decide(fi, SecurityConfig.createList("SOME_IGNORED_ATTRIBUTE", "REQUIRES_SECURE_CHANNEL"));
- assertThat(fi.getResponse().isCommitted()).isFalse();
+ Assertions.assertThat(fi.getResponse().isCommitted()).isFalse();
}
@Test
public void testDecideDetectsUnacceptableChannel() throws Exception {
- MockHttpServletRequest request = get("http://localhost:8080").requestUri("/bigapp", "/servlet", null)
+ MockHttpServletRequest request = TestMockHttpServletRequests.get("http://localhost:8080")
+ .requestUri("/bigapp", "/servlet", null)
.queryString("info=true")
.build();
MockHttpServletResponse response = new MockHttpServletResponse();
@@ -58,7 +61,7 @@ public class SecureChannelProcessorTests {
SecureChannelProcessor processor = new SecureChannelProcessor();
processor.decide(fi,
SecurityConfig.createList(new String[] { "SOME_IGNORED_ATTRIBUTE", "REQUIRES_SECURE_CHANNEL" }));
- assertThat(fi.getResponse().isCommitted()).isTrue();
+ Assertions.assertThat(fi.getResponse().isCommitted()).isTrue();
}
@Test
diff --git a/web/src/test/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandlerTests.java b/access/src/test/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandlerTests.java
similarity index 100%
rename from web/src/test/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandlerTests.java
rename to access/src/test/java/org/springframework/security/web/access/expression/DefaultWebSecurityExpressionHandlerTests.java
diff --git a/web/src/test/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSourceTests.java b/access/src/test/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSourceTests.java
similarity index 100%
rename from web/src/test/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSourceTests.java
rename to access/src/test/java/org/springframework/security/web/access/expression/ExpressionBasedFilterInvocationSecurityMetadataSourceTests.java
diff --git a/web/src/test/java/org/springframework/security/web/access/expression/WebExpressionVoterTests.java b/access/src/test/java/org/springframework/security/web/access/expression/WebExpressionVoterTests.java
similarity index 100%
rename from web/src/test/java/org/springframework/security/web/access/expression/WebExpressionVoterTests.java
rename to access/src/test/java/org/springframework/security/web/access/expression/WebExpressionVoterTests.java
diff --git a/web/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java b/access/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java
similarity index 90%
rename from web/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java
rename to access/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java
index dd746f35a6..3de762fd5e 100644
--- a/web/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java
+++ b/access/src/test/java/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSourceTests.java
@@ -28,12 +28,12 @@ import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
+import org.springframework.security.web.servlet.TestMockHttpServletRequests;
+import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
-import static org.springframework.security.web.servlet.TestMockHttpServletRequests.request;
-import static org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher.pathPattern;
/**
* Tests {@link DefaultFilterInvocationSecurityMetadataSource}.
@@ -48,7 +48,7 @@ public class DefaultFilterInvocationSecurityMetadataSourceTests {
private void createFids(String pattern, HttpMethod method) {
LinkedHashMap> requestMap = new LinkedHashMap<>();
- requestMap.put(pathPattern(method, pattern), this.def);
+ requestMap.put(PathPatternRequestMatcher.pathPattern(method, pattern), this.def);
this.fids = new DefaultFilterInvocationSecurityMetadataSource(requestMap);
}
@@ -117,8 +117,9 @@ public class DefaultFilterInvocationSecurityMetadataSourceTests {
public void mixingPatternsWithAndWithoutHttpMethodsIsSupported() {
LinkedHashMap> requestMap = new LinkedHashMap<>();
Collection userAttrs = SecurityConfig.createList("A");
- requestMap.put(pathPattern("/user/**"), userAttrs);
- requestMap.put(pathPattern(HttpMethod.GET, "/teller/**"), SecurityConfig.createList("B"));
+ requestMap.put(PathPatternRequestMatcher.pathPattern("/user/**"), userAttrs);
+ requestMap.put(PathPatternRequestMatcher.pathPattern(HttpMethod.GET, "/teller/**"),
+ SecurityConfig.createList("B"));
this.fids = new DefaultFilterInvocationSecurityMetadataSource(requestMap);
FilterInvocation fi = createFilterInvocation("/user", null, null, "GET");
Collection attrs = this.fids.getAttributes(fi);
@@ -141,7 +142,8 @@ public class DefaultFilterInvocationSecurityMetadataSourceTests {
private FilterInvocation createFilterInvocation(String servletPath, String pathInfo, String queryString,
String method) {
- MockHttpServletRequest request = request(method).requestUri(null, servletPath, pathInfo)
+ MockHttpServletRequest request = TestMockHttpServletRequests.request(method)
+ .requestUri(null, servletPath, pathInfo)
.queryString(queryString)
.build();
return new FilterInvocation(request, new MockHttpServletResponse(), mock(FilterChain.class));
diff --git a/web/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java b/access/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java
similarity index 97%
rename from web/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java
rename to access/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java
index 77370b0cd7..5194c38325 100644
--- a/web/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java
+++ b/access/src/test/java/org/springframework/security/web/access/intercept/FilterSecurityInterceptorTests.java
@@ -39,6 +39,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.FilterInvocation;
+import org.springframework.security.web.servlet.TestMockHttpServletRequests;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -53,7 +54,6 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.springframework.security.web.servlet.TestMockHttpServletRequests.get;
/**
* Tests {@link FilterSecurityInterceptor}.
@@ -189,7 +189,7 @@ public class FilterSecurityInterceptorTests {
private FilterInvocation createinvocation() {
MockHttpServletResponse response = new MockHttpServletResponse();
- MockHttpServletRequest request = get("/secure/page.html").build();
+ MockHttpServletRequest request = TestMockHttpServletRequests.get("/secure/page.html").build();
FilterChain chain = mock(FilterChain.class);
FilterInvocation fi = new FilterInvocation(request, response, chain);
return fi;
diff --git a/aspects/spring-security-aspects.gradle b/aspects/spring-security-aspects.gradle
index cffa8e5fb1..9df4e61538 100644
--- a/aspects/spring-security-aspects.gradle
+++ b/aspects/spring-security-aspects.gradle
@@ -18,6 +18,8 @@ dependencies {
api 'org.springframework:spring-context'
api 'org.springframework:spring-core'
+ optional project(':spring-security-access')
+
testImplementation 'org.springframework:spring-aop'
testImplementation "org.assertj:assertj-core"
testImplementation "org.junit.jupiter:junit-jupiter-api"
diff --git a/config/spring-security-config.gradle b/config/spring-security-config.gradle
index 502bc446fd..c912dc6cdc 100644
--- a/config/spring-security-config.gradle
+++ b/config/spring-security-config.gradle
@@ -1,4 +1,3 @@
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.springframework.gradle.xsd.CreateVersionlessXsdTask
import trang.RncToXsd
@@ -21,6 +20,7 @@ dependencies {
api 'org.springframework:spring-context'
api 'org.springframework:spring-core'
+ optional project(':spring-security-access')
optional project(':spring-security-data')
optional project(':spring-security-ldap')
optional project(':spring-security-messaging')
@@ -49,6 +49,7 @@ dependencies {
testImplementation project(':spring-security-aspects')
testImplementation project(':spring-security-cas')
testImplementation project(':spring-security-test')
+ testImplementation project(path : ':spring-security-access', configuration : 'tests')
testImplementation project(path : ':spring-security-core', configuration : 'tests')
testImplementation project(path : ':spring-security-ldap', configuration : 'tests')
testImplementation project(path : ':spring-security-oauth2-client', configuration : 'tests')
diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java b/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java
index 89e2fe007e..063ced5e88 100644
--- a/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java
+++ b/config/src/main/java/org/springframework/security/config/annotation/web/builders/FilterOrderRegistration.java
@@ -23,9 +23,7 @@ import java.util.Map;
import jakarta.servlet.Filter;
import org.springframework.security.web.access.ExceptionTranslationFilter;
-import org.springframework.security.web.access.channel.ChannelProcessingFilter;
import org.springframework.security.web.access.intercept.AuthorizationFilter;
-import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
import org.springframework.security.web.authentication.AuthenticationFilter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@@ -78,7 +76,7 @@ final class FilterOrderRegistration {
Step order = new Step(INITIAL_ORDER, ORDER_STEP);
put(DisableEncodeUrlFilter.class, order.next());
put(ForceEagerSessionCreationFilter.class, order.next());
- put(ChannelProcessingFilter.class, order.next());
+ this.filterToOrder.put("org.springframework.security.web.access.channel.ChannelProcessingFilter", order.next());
put(HttpsRedirectFilter.class, order.next());
order.next(); // gh-8105
put(WebAsyncManagerIntegrationFilter.class, order.next());
@@ -126,7 +124,8 @@ final class FilterOrderRegistration {
order.next());
put(SessionManagementFilter.class, order.next());
put(ExceptionTranslationFilter.class, order.next());
- put(FilterSecurityInterceptor.class, order.next());
+ this.filterToOrder.put("org.springframework.security.web.access.intercept.FilterSecurityInterceptor",
+ order.next());
put(AuthorizationFilter.class, order.next());
put(SwitchUserFilter.class, order.next());
}
diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurity.java b/config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurity.java
index 943cfbc802..bce1b3bdf2 100644
--- a/config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurity.java
+++ b/config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurity.java
@@ -18,6 +18,7 @@ package org.springframework.security.config.annotation.web.builders;
import java.util.ArrayList;
import java.util.List;
+import java.util.function.Supplier;
import io.micrometer.observation.ObservationRegistry;
import jakarta.servlet.Filter;
@@ -25,6 +26,8 @@ import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
@@ -32,8 +35,11 @@ import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.ResolvableType;
+import org.springframework.expression.EvaluationContext;
import org.springframework.security.access.PermissionEvaluator;
+import org.springframework.security.access.expression.AbstractSecurityExpressionHandler;
import org.springframework.security.access.expression.SecurityExpressionHandler;
+import org.springframework.security.access.expression.SecurityExpressionOperations;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
@@ -46,6 +52,7 @@ import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
+import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.FilterChainProxy;
@@ -58,7 +65,7 @@ import org.springframework.security.web.access.DefaultWebInvocationPrivilegeEval
import org.springframework.security.web.access.PathPatternRequestTransformer;
import org.springframework.security.web.access.RequestMatcherDelegatingWebInvocationPrivilegeEvaluator;
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
-import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
+import org.springframework.security.web.access.expression.DefaultHttpSecurityExpressionHandler;
import org.springframework.security.web.access.intercept.AuthorizationFilter;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
@@ -74,6 +81,7 @@ import org.springframework.security.web.util.matcher.AnyRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcherEntry;
import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.filter.DelegatingFilterProxy;
@@ -99,6 +107,9 @@ import org.springframework.web.filter.DelegatingFilterProxy;
public final class WebSecurity extends AbstractConfiguredSecurityBuilder
implements SecurityBuilder, ApplicationContextAware, ServletContextAware {
+ private static final boolean USING_ACCESS = ClassUtils
+ .isPresent("org.springframework.security.access.SecurityConfig", null);
+
private final Log logger = LogFactory.getLog(getClass());
private final List ignoredRequests = new ArrayList<>();
@@ -122,9 +133,10 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder expressionHandler = this.defaultWebSecurityExpressionHandler;
+ private SecurityExpressionHandler expressionHandler = new SecurityExpressionHandlerAdapter(
+ this.defaultExpressionHandler);
private Runnable postBuildAction = () -> {
};
@@ -240,7 +252,7 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder authorizationManager = (authentication, context) -> {
- HttpServletRequest request = context.getRequest();
- boolean result = privilegeEvaluator.isAllowed(request.getContextPath(), request.getRequestURI(),
- request.getMethod(), authentication.get());
- return new AuthorizationDecision(result);
- };
- builder.add(securityFilterChain::matches, authorizationManager);
- mappings = true;
- continue;
+ if (USING_ACCESS) {
+ mappings = AccessComponents.addAuthorizationManager(filter, this.servletContext, builder,
+ securityFilterChain);
}
if (filter instanceof AuthorizationFilter authorization) {
AuthorizationManager authorizationManager = authorization.getAuthorizationManager();
@@ -388,15 +390,14 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder {
+
+ private final AbstractSecurityExpressionHandler delegate;
+
+ private SecurityExpressionHandlerAdapter(
+ AbstractSecurityExpressionHandler delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public EvaluationContext createEvaluationContext(Supplier extends @Nullable Authentication> authentication,
+ FilterInvocation invocation) {
+ RequestAuthorizationContext context = new RequestAuthorizationContext(invocation.getRequest());
+ return this.delegate.createEvaluationContext(authentication, context);
+ }
+
+ @Override
+ protected SecurityExpressionOperations createSecurityExpressionRoot(@Nullable Authentication authentication,
+ FilterInvocation invocation) {
+ RequestAuthorizationContext context = new RequestAuthorizationContext(invocation.getRequest());
+ Object operations = this.delegate.createEvaluationContext(authentication, context)
+ .getRootObject()
+ .getValue();
+ Assert.isInstanceOf(SecurityExpressionOperations.class, operations,
+ "createEvaluationContext must have a SecurityExpressionOperations instance as its root");
+ return (SecurityExpressionOperations) operations;
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext context) {
+ this.delegate.setApplicationContext(context);
+ super.setApplicationContext(context);
+ }
+
+ @Override
+ public void setPermissionEvaluator(PermissionEvaluator permissionEvaluator) {
+ this.delegate.setPermissionEvaluator(permissionEvaluator);
+ super.setPermissionEvaluator(permissionEvaluator);
+ }
+
+ @Override
+ public void setRoleHierarchy(@Nullable RoleHierarchy roleHierarchy) {
+ this.delegate.setRoleHierarchy(roleHierarchy);
+ super.setRoleHierarchy(roleHierarchy);
+ }
+
+ }
+
+ private static final class AccessComponents {
+
+ private static boolean addAuthorizationManager(Filter filter, ServletContext servletContext,
+ RequestMatcherDelegatingAuthorizationManager.Builder builder, SecurityFilterChain securityFilterChain) {
+ if (filter instanceof FilterSecurityInterceptor securityInterceptor) {
+ DefaultWebInvocationPrivilegeEvaluator privilegeEvaluator = new DefaultWebInvocationPrivilegeEvaluator(
+ securityInterceptor);
+ privilegeEvaluator.setServletContext(servletContext);
+ AuthorizationManager authorizationManager = (authentication, context) -> {
+ HttpServletRequest request = context.getRequest();
+ boolean result = privilegeEvaluator.isAllowed(request.getContextPath(), request.getRequestURI(),
+ request.getMethod(), authentication.get());
+ return new AuthorizationDecision(result);
+ };
+ builder.add(securityFilterChain::matches, authorizationManager);
+ return true;
+ }
+ return false;
+ }
+
+ }
+
}
diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurityFilterChainValidator.java b/config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurityFilterChainValidator.java
index 971b2cf810..fa97043fb6 100644
--- a/config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurityFilterChainValidator.java
+++ b/config/src/main/java/org/springframework/security/config/annotation/web/builders/WebSecurityFilterChainValidator.java
@@ -29,6 +29,7 @@ import org.springframework.security.web.UnreachableFilterChainException;
import org.springframework.security.web.access.intercept.AuthorizationFilter;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
+import org.springframework.util.ClassUtils;
/**
* A filter chain validator for filter chains built by {@link WebSecurity}
@@ -39,6 +40,9 @@ import org.springframework.security.web.util.matcher.AnyRequestMatcher;
*/
final class WebSecurityFilterChainValidator implements FilterChainProxy.FilterChainValidator {
+ private static final boolean USING_ACCESS = ClassUtils
+ .isPresent("org.springframework.security.access.SecurityConfig", null);
+
private final Log logger = LogFactory.getLog(getClass());
@Override
@@ -93,7 +97,7 @@ final class WebSecurityFilterChainValidator implements FilterChainProxy.FilterCh
if (filter instanceof AuthorizationFilter) {
authorizationFilter = filter;
}
- if (filter instanceof FilterSecurityInterceptor) {
+ if (USING_ACCESS && AccessComponents.isFilterSecurityInterceptor(filter)) {
filterSecurityInterceptor = filter;
}
}
@@ -110,4 +114,12 @@ final class WebSecurityFilterChainValidator implements FilterChainProxy.FilterCh
}
}
+ private static final class AccessComponents {
+
+ private static boolean isFilterSecurityInterceptor(Filter filter) {
+ return filter instanceof FilterSecurityInterceptor;
+ }
+
+ }
+
}
diff --git a/config/src/main/java/org/springframework/security/config/http/DefaultFilterChainValidator.java b/config/src/main/java/org/springframework/security/config/http/DefaultFilterChainValidator.java
index a7dcbbdd98..fb88f14b3a 100644
--- a/config/src/main/java/org/springframework/security/config/http/DefaultFilterChainValidator.java
+++ b/config/src/main/java/org/springframework/security/config/http/DefaultFilterChainValidator.java
@@ -56,9 +56,13 @@ import org.springframework.security.web.jaasapi.JaasApiIntegrationFilter;
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
import org.springframework.security.web.session.SessionManagementFilter;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
+import org.springframework.util.ClassUtils;
public class DefaultFilterChainValidator implements FilterChainProxy.FilterChainValidator {
+ private static final boolean USING_ACCESS = ClassUtils
+ .isPresent("org.springframework.security.access.SecurityConfig", null);
+
private static final Authentication TEST = new TestingAuthenticationToken("", "", Collections.emptyList());
private final Log logger = LogFactory.getLog(getClass());
@@ -120,7 +124,7 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
if (filter instanceof AuthorizationFilter) {
authorizationFilter = filter;
}
- if (filter instanceof FilterSecurityInterceptor) {
+ if (USING_ACCESS && AccessComponents.isFilterSecurityInterceptor(filter)) {
filterSecurityInterceptor = filter;
}
}
@@ -138,7 +142,7 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
}
@SuppressWarnings({ "unchecked" })
- private F getFilter(Class type, List filters) {
+ private static F getFilter(Class type, List filters) {
for (Filter f : filters) {
if (type.isAssignableFrom(f.getClass())) {
return (F) f;
@@ -158,7 +162,9 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
checkForDuplicates(SecurityContextHolderAwareRequestFilter.class, filters);
checkForDuplicates(JaasApiIntegrationFilter.class, filters);
checkForDuplicates(ExceptionTranslationFilter.class, filters);
- checkForDuplicates(FilterSecurityInterceptor.class, filters);
+ if (USING_ACCESS) {
+ checkForDuplicates(AccessComponents.getFilterSecurityInterceptorClass(), filters);
+ }
checkForDuplicates(AuthorizationFilter.class, filters);
}
@@ -243,19 +249,11 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
}
private boolean checkLoginPageIsPublic(List filters, HttpServletRequest loginRequest) {
- FilterSecurityInterceptor authorizationInterceptor = getFilter(FilterSecurityInterceptor.class, filters);
- if (authorizationInterceptor != null) {
- FilterInvocationSecurityMetadataSource fids = authorizationInterceptor.getSecurityMetadataSource();
- Collection attributes = fids.getAttributes(loginRequest);
- if (attributes == null) {
- this.logger.debug("No access attributes defined for login page URL");
- if (authorizationInterceptor.isRejectPublicInvocations()) {
- this.logger.warn("FilterSecurityInterceptor is configured to reject public invocations."
- + " Your login page may not be accessible.");
- }
- return true;
+ if (USING_ACCESS) {
+ Boolean isPublic = AccessComponents.checkLoginPageIsPublic(filters, loginRequest);
+ if (isPublic != null) {
+ return isPublic;
}
- return false;
}
AuthorizationFilter authorizationFilter = getFilter(AuthorizationFilter.class, filters);
if (authorizationFilter != null) {
@@ -274,19 +272,11 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
private Supplier deriveAnonymousCheck(List filters, HttpServletRequest loginRequest,
AnonymousAuthenticationToken token) {
- FilterSecurityInterceptor authorizationInterceptor = getFilter(FilterSecurityInterceptor.class, filters);
- if (authorizationInterceptor != null) {
- return () -> {
- FilterInvocationSecurityMetadataSource source = authorizationInterceptor.getSecurityMetadataSource();
- Collection attributes = source.getAttributes(loginRequest);
- try {
- authorizationInterceptor.getAccessDecisionManager().decide(token, loginRequest, attributes);
- return true;
- }
- catch (AccessDeniedException ex) {
- return false;
- }
- };
+ if (USING_ACCESS) {
+ Supplier check = AccessComponents.getAnonymousCheck(filters, loginRequest, token);
+ if (check != null) {
+ return check;
+ }
}
AuthorizationFilter authorizationFilter = getFilter(AuthorizationFilter.class, filters);
if (authorizationFilter != null) {
@@ -300,4 +290,55 @@ public class DefaultFilterChainValidator implements FilterChainProxy.FilterChain
return () -> true;
}
+ private static final class AccessComponents {
+
+ private static final Log logger = LogFactory.getLog(DefaultFilterChainValidator.class);
+
+ private static boolean isFilterSecurityInterceptor(Filter filter) {
+ return filter instanceof FilterSecurityInterceptor;
+ }
+
+ private static Class getFilterSecurityInterceptorClass() {
+ return FilterSecurityInterceptor.class;
+ }
+
+ private static Boolean checkLoginPageIsPublic(List filters, HttpServletRequest loginRequest) {
+ FilterSecurityInterceptor authorizationInterceptor = getFilter(FilterSecurityInterceptor.class, filters);
+ if (authorizationInterceptor == null) {
+ return null;
+ }
+ FilterInvocationSecurityMetadataSource fids = authorizationInterceptor.getSecurityMetadataSource();
+ Collection attributes = fids.getAttributes(loginRequest);
+ if (attributes == null) {
+ logger.debug("No access attributes defined for login page URL");
+ if (authorizationInterceptor.isRejectPublicInvocations()) {
+ logger.warn("FilterSecurityInterceptor is configured to reject public invocations."
+ + " Your login page may not be accessible.");
+ }
+ return true;
+ }
+ return false;
+ }
+
+ private static Supplier getAnonymousCheck(List filters, HttpServletRequest loginRequest,
+ AnonymousAuthenticationToken token) {
+ FilterSecurityInterceptor authorizationInterceptor = getFilter(FilterSecurityInterceptor.class, filters);
+ if (authorizationInterceptor == null) {
+ return null;
+ }
+ return () -> {
+ FilterInvocationSecurityMetadataSource source = authorizationInterceptor.getSecurityMetadataSource();
+ Collection attributes = source.getAttributes(loginRequest);
+ try {
+ authorizationInterceptor.getAccessDecisionManager().decide(token, loginRequest, attributes);
+ return true;
+ }
+ catch (AccessDeniedException ex) {
+ return false;
+ }
+ };
+ }
+
+ }
+
}
diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurationTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurationTests.java
index 2063563122..922a336e62 100644
--- a/config/src/test/java/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurationTests.java
+++ b/config/src/test/java/org/springframework/security/config/annotation/web/configuration/WebSecurityConfigurationTests.java
@@ -60,7 +60,6 @@ import org.springframework.security.web.access.AuthorizationManagerWebInvocation
import org.springframework.security.web.access.PathPatternRequestTransformer;
import org.springframework.security.web.access.RequestMatcherDelegatingWebInvocationPrivilegeEvaluator;
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator;
-import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler;
import org.springframework.security.web.access.expression.WebExpressionAuthorizationManager;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.ClassUtils;
@@ -153,7 +152,7 @@ public class WebSecurityConfigurationTests {
public void loadConfigWhenDefaultSecurityExpressionHandlerThenDefaultIsRegistered() {
this.spring.register(WebSecurityExpressionHandlerDefaultsConfig.class).autowire();
assertThat(this.spring.getContext().getBean(SecurityExpressionHandler.class))
- .isInstanceOf(DefaultWebSecurityExpressionHandler.class);
+ .isInstanceOf(AbstractSecurityExpressionHandler.class);
}
@Test
diff --git a/core/src/main/java/org/springframework/security/core/parameters/AnnotationParameterNameDiscoverer.java b/core/src/main/java/org/springframework/security/core/parameters/AnnotationParameterNameDiscoverer.java
index fca66904bd..6426fcc01a 100644
--- a/core/src/main/java/org/springframework/security/core/parameters/AnnotationParameterNameDiscoverer.java
+++ b/core/src/main/java/org/springframework/security/core/parameters/AnnotationParameterNameDiscoverer.java
@@ -30,7 +30,6 @@ import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.PrioritizedParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.security.access.method.P;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/AuthorizationManagerAfterReactiveMethodInterceptorTests.java b/core/src/test/java/org/springframework/security/authorization/method/AuthorizationManagerAfterReactiveMethodInterceptorTests.java
index bbc363ca18..3c2358964d 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/AuthorizationManagerAfterReactiveMethodInterceptorTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/AuthorizationManagerAfterReactiveMethodInterceptorTests.java
@@ -25,7 +25,6 @@ import reactor.core.publisher.Mono;
import org.springframework.aop.Pointcut;
import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationDeniedException;
import org.springframework.security.authorization.AuthorizationResult;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/AuthorizationManagerBeforeReactiveMethodInterceptorTests.java b/core/src/test/java/org/springframework/security/authorization/method/AuthorizationManagerBeforeReactiveMethodInterceptorTests.java
index fbdf5c09ed..09b069302a 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/AuthorizationManagerBeforeReactiveMethodInterceptorTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/AuthorizationManagerBeforeReactiveMethodInterceptorTests.java
@@ -24,7 +24,6 @@ import reactor.core.publisher.Mono;
import org.springframework.aop.Pointcut;
import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationDeniedException;
import org.springframework.security.authorization.AuthorizationResult;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/BusinessService.java b/core/src/test/java/org/springframework/security/authorization/method/BusinessService.java
new file mode 100644
index 0000000000..aa90b2c22c
--- /dev/null
+++ b/core/src/test/java/org/springframework/security/authorization/method/BusinessService.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.authorization.method;
+
+import java.io.Serializable;
+import java.util.List;
+
+import jakarta.annotation.security.PermitAll;
+import jakarta.annotation.security.RolesAllowed;
+
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.access.prepost.PreAuthorize;
+
+/**
+ */
+@Secured({ "ROLE_USER" })
+@PermitAll
+public interface BusinessService extends Serializable {
+
+ @Secured({ "ROLE_ADMIN" })
+ @RolesAllowed({ "ROLE_ADMIN" })
+ @PreAuthorize("hasRole('ROLE_ADMIN')")
+ void someAdminMethod();
+
+ @Secured({ "ROLE_USER", "ROLE_ADMIN" })
+ @RolesAllowed({ "ROLE_USER", "ROLE_ADMIN" })
+ void someUserAndAdminMethod();
+
+ @Secured({ "ROLE_USER" })
+ @RolesAllowed({ "ROLE_USER" })
+ void someUserMethod1();
+
+ @Secured({ "ROLE_USER" })
+ @RolesAllowed({ "ROLE_USER" })
+ void someUserMethod2();
+
+ @RolesAllowed({ "USER" })
+ void rolesAllowedUser();
+
+ int someOther(String s);
+
+ int someOther(int input);
+
+ List> methodReturningAList(List> someList);
+
+ Object[] methodReturningAnArray(Object[] someArray);
+
+ List> methodReturningAList(String userName, String extraParam);
+
+ @RequireAdminRole
+ @RequireUserRole
+ default void repeatedAnnotations() {
+
+ }
+
+}
diff --git a/core/src/test/java/org/springframework/security/authorization/method/Jsr250AuthorizationManagerTests.java b/core/src/test/java/org/springframework/security/authorization/method/Jsr250AuthorizationManagerTests.java
index d5174a2232..d9534a7df0 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/Jsr250AuthorizationManagerTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/Jsr250AuthorizationManagerTests.java
@@ -28,7 +28,6 @@ import jakarta.annotation.security.RolesAllowed;
import org.junit.jupiter.api.Test;
import org.springframework.core.annotation.AnnotationConfigurationException;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authorization.AuthorizationManager;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/MethodExpressionAuthorizationManagerTests.java b/core/src/test/java/org/springframework/security/authorization/method/MethodExpressionAuthorizationManagerTests.java
index c3357a20f0..3aea48707e 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/MethodExpressionAuthorizationManagerTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/MethodExpressionAuthorizationManagerTests.java
@@ -21,7 +21,6 @@ import org.junit.platform.commons.util.ReflectionUtils;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
-import org.springframework.security.access.annotation.BusinessService;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authorization.AuthorizationResult;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/MockMethodInvocation.java b/core/src/test/java/org/springframework/security/authorization/method/MockMethodInvocation.java
new file mode 100644
index 0000000000..ee5b35cfff
--- /dev/null
+++ b/core/src/test/java/org/springframework/security/authorization/method/MockMethodInvocation.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2004-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.authorization.method;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Method;
+
+import org.aopalliance.intercept.MethodInvocation;
+
+@SuppressWarnings("unchecked")
+public class MockMethodInvocation implements MethodInvocation {
+
+ private Method method;
+
+ private Object targetObject;
+
+ private Object[] arguments = new Object[0];
+
+ public MockMethodInvocation(Object targetObject, Class clazz, String methodName, Class[] parameterTypes,
+ Object[] arguments) throws NoSuchMethodException {
+ this(targetObject, clazz, methodName, parameterTypes);
+ this.arguments = arguments;
+ }
+
+ public MockMethodInvocation(Object targetObject, Class clazz, String methodName, Class... parameterTypes)
+ throws NoSuchMethodException {
+ this(targetObject, clazz.getMethod(methodName, parameterTypes));
+ this.targetObject = targetObject;
+ }
+
+ public MockMethodInvocation(Object targetObject, Method method) {
+ this.targetObject = targetObject;
+ this.method = method;
+ }
+
+ @Override
+ public Object[] getArguments() {
+ return this.arguments;
+ }
+
+ @Override
+ public Method getMethod() {
+ return this.method;
+ }
+
+ @Override
+ public AccessibleObject getStaticPart() {
+ return null;
+ }
+
+ @Override
+ public Object getThis() {
+ return this.targetObject;
+ }
+
+ @Override
+ public Object proceed() {
+ return null;
+ }
+
+}
diff --git a/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManagerTests.java b/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManagerTests.java
index dd1a4a8359..9e418096f9 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManagerTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManagerTests.java
@@ -30,7 +30,6 @@ import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationConfigurationException;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authentication.TestingAuthenticationToken;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeReactiveAuthorizationManagerTests.java b/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeReactiveAuthorizationManagerTests.java
index f5e51d4efc..5c10366bd2 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeReactiveAuthorizationManagerTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeReactiveAuthorizationManagerTests.java
@@ -28,7 +28,6 @@ import reactor.core.publisher.Mono;
import org.springframework.core.annotation.AnnotationConfigurationException;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authorization.AuthorizationResult;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptorTests.java b/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptorTests.java
index b837b20cf6..31fee409f9 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptorTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptorTests.java
@@ -28,7 +28,6 @@ import org.springframework.aop.MethodMatcher;
import org.springframework.core.annotation.AnnotationConfigurationException;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authentication.TestingAuthenticationToken;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationReactiveMethodInterceptorTests.java b/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationReactiveMethodInterceptorTests.java
index f4b1dbcf19..aed760b585 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationReactiveMethodInterceptorTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationReactiveMethodInterceptorTests.java
@@ -27,7 +27,6 @@ import reactor.core.publisher.Mono;
import org.springframework.core.annotation.AnnotationConfigurationException;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.access.prepost.PostFilter;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManagerTests.java b/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManagerTests.java
index 980f640750..b9439ca3d6 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManagerTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManagerTests.java
@@ -28,7 +28,6 @@ import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationConfigurationException;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authentication.TestingAuthenticationToken;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeReactiveAuthorizationManagerTests.java b/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeReactiveAuthorizationManagerTests.java
index f62fe7459c..bb0d003e3d 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeReactiveAuthorizationManagerTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeReactiveAuthorizationManagerTests.java
@@ -25,7 +25,6 @@ import reactor.core.publisher.Mono;
import org.springframework.core.annotation.AnnotationConfigurationException;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authorization.AuthorizationResult;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptorTests.java b/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptorTests.java
index d13bce3c4d..e28c570644 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptorTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptorTests.java
@@ -29,7 +29,6 @@ import org.springframework.aop.MethodMatcher;
import org.springframework.core.annotation.AnnotationConfigurationException;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.access.prepost.PreFilter;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authentication.TestingAuthenticationToken;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationReactiveMethodInterceptorTests.java b/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationReactiveMethodInterceptorTests.java
index e45c6054ae..309321e607 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationReactiveMethodInterceptorTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationReactiveMethodInterceptorTests.java
@@ -28,7 +28,6 @@ import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationConfigurationException;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.access.prepost.PreFilter;
import org.springframework.security.core.parameters.DefaultSecurityParameterNameDiscoverer;
diff --git a/core/src/test/java/org/springframework/security/authorization/method/RequireAdminRole.java b/core/src/test/java/org/springframework/security/authorization/method/RequireAdminRole.java
new file mode 100644
index 0000000000..c9d2101d5a
--- /dev/null
+++ b/core/src/test/java/org/springframework/security/authorization/method/RequireAdminRole.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2004-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.authorization.method;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import jakarta.annotation.security.RolesAllowed;
+
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.access.prepost.PreAuthorize;
+
+@Retention(RetentionPolicy.RUNTIME)
+@PreAuthorize("hasRole('ADMIN')")
+@RolesAllowed("ADMIN")
+@Secured("ADMIN")
+public @interface RequireAdminRole {
+
+}
diff --git a/core/src/test/java/org/springframework/security/authorization/method/RequireUserRole.java b/core/src/test/java/org/springframework/security/authorization/method/RequireUserRole.java
new file mode 100644
index 0000000000..b918926b3e
--- /dev/null
+++ b/core/src/test/java/org/springframework/security/authorization/method/RequireUserRole.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2004-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.authorization.method;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import jakarta.annotation.security.RolesAllowed;
+
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.access.prepost.PreAuthorize;
+
+@Retention(RetentionPolicy.RUNTIME)
+@PreAuthorize("hasRole('USER')")
+@RolesAllowed("USER")
+@Secured("USER")
+public @interface RequireUserRole {
+
+}
diff --git a/core/src/test/java/org/springframework/security/authorization/method/SecuredAuthorizationManagerTests.java b/core/src/test/java/org/springframework/security/authorization/method/SecuredAuthorizationManagerTests.java
index 172d9be8b6..27993c2fd0 100644
--- a/core/src/test/java/org/springframework/security/authorization/method/SecuredAuthorizationManagerTests.java
+++ b/core/src/test/java/org/springframework/security/authorization/method/SecuredAuthorizationManagerTests.java
@@ -27,7 +27,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.aop.TargetClassAware;
import org.springframework.core.annotation.AnnotationConfigurationException;
import org.springframework.security.access.annotation.Secured;
-import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authorization.AuthorizationManager;
diff --git a/core/src/test/java/org/springframework/security/core/parameters/AnnotationParameterNameDiscovererTests.java b/core/src/test/java/org/springframework/security/core/parameters/AnnotationParameterNameDiscovererTests.java
index 13dee89fe5..de52d16246 100644
--- a/core/src/test/java/org/springframework/security/core/parameters/AnnotationParameterNameDiscovererTests.java
+++ b/core/src/test/java/org/springframework/security/core/parameters/AnnotationParameterNameDiscovererTests.java
@@ -19,7 +19,6 @@ package org.springframework.security.core.parameters;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.springframework.security.access.method.P;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/core/src/test/java/org/springframework/security/util/BusinessService.java b/core/src/test/java/org/springframework/security/util/BusinessService.java
new file mode 100644
index 0000000000..d863bb55e8
--- /dev/null
+++ b/core/src/test/java/org/springframework/security/util/BusinessService.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.util;
+
+import java.io.Serializable;
+import java.util.List;
+
+import jakarta.annotation.security.PermitAll;
+import jakarta.annotation.security.RolesAllowed;
+
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.access.prepost.PreAuthorize;
+
+/**
+ */
+@Secured({ "ROLE_USER" })
+@PermitAll
+public interface BusinessService extends Serializable {
+
+ @Secured({ "ROLE_ADMIN" })
+ @RolesAllowed({ "ROLE_ADMIN" })
+ @PreAuthorize("hasRole('ROLE_ADMIN')")
+ void someAdminMethod();
+
+ @Secured({ "ROLE_USER", "ROLE_ADMIN" })
+ @RolesAllowed({ "ROLE_USER", "ROLE_ADMIN" })
+ void someUserAndAdminMethod();
+
+ @Secured({ "ROLE_USER" })
+ @RolesAllowed({ "ROLE_USER" })
+ void someUserMethod1();
+
+ @Secured({ "ROLE_USER" })
+ @RolesAllowed({ "ROLE_USER" })
+ void someUserMethod2();
+
+ @RolesAllowed({ "USER" })
+ void rolesAllowedUser();
+
+ int someOther(String s);
+
+ int someOther(int input);
+
+ List> methodReturningAList(List> someList);
+
+ Object[] methodReturningAnArray(Object[] someArray);
+
+ List> methodReturningAList(String userName, String extraParam);
+
+ @RequireAdminRole
+ @RequireUserRole
+ default void repeatedAnnotations() {
+
+ }
+
+}
diff --git a/core/src/test/java/org/springframework/security/util/BusinessServiceImpl.java b/core/src/test/java/org/springframework/security/util/BusinessServiceImpl.java
new file mode 100644
index 0000000000..60b1997d37
--- /dev/null
+++ b/core/src/test/java/org/springframework/security/util/BusinessServiceImpl.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2004-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.security.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.authorization.method.BusinessService;
+
+/**
+ * @author Joe Scalise
+ */
+@SuppressWarnings("serial")
+public class BusinessServiceImpl implements BusinessService {
+
+ @Override
+ @Secured({ "ROLE_USER" })
+ public void someUserMethod1() {
+ }
+
+ @Override
+ @Secured({ "ROLE_USER" })
+ public void someUserMethod2() {
+ }
+
+ @Override
+ @Secured({ "ROLE_USER", "ROLE_ADMIN" })
+ public void someUserAndAdminMethod() {
+ }
+
+ @Override
+ @Secured({ "ROLE_ADMIN" })
+ public void someAdminMethod() {
+ }
+
+ public E someUserMethod3(final E entity) {
+ return entity;
+ }
+
+ @Override
+ public int someOther(String s) {
+ return 0;
+ }
+
+ @Override
+ public int someOther(int input) {
+ return input;
+ }
+
+ @Override
+ public List> methodReturningAList(List> someList) {
+ return someList;
+ }
+
+ @Override
+ public List