diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0dbdae2e1..97670006c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -77,6 +77,7 @@ spring-context-core = { module = 'org.springframework:spring-context', version.r spring-context-support = { module = 'org.springframework:spring-context-support', version.ref = 'spring' } spring-expression = { module = 'org.springframework:spring-expression', version.ref = 'spring' } spring-security-core = { module = 'org.springframework.security:spring-security-core', version.ref = 'spring-security' } +spring-security-config = { module = 'org.springframework.security:spring-security-config', version.ref = 'spring-security' } spring-security-crypto = { module = 'org.springframework.security:spring-security-crypto', version.ref = 'spring-security' } spring-security-web = { module = 'org.springframework.security:spring-security-web', version.ref = 'spring-security' } spring-test = { module = 'org.springframework:spring-test', version.ref = 'spring' } diff --git a/plugin/build.gradle b/plugin/build.gradle index f03a62481..ceaecf0fa 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -44,6 +44,7 @@ dependencies { testImplementation libs.bundles.grails.testing.support testImplementation libs.spock.core testImplementation libs.spring.test + testImplementation libs.spring.security.config testRuntimeOnly libs.slf4j.nop // Prevents warnings about missing slf4j implementation during tests } diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/SecurityFilterPosition.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/SecurityFilterPosition.java similarity index 57% rename from plugin/src/main/groovy/grails/plugin/springsecurity/SecurityFilterPosition.groovy rename to plugin/src/main/groovy/grails/plugin/springsecurity/SecurityFilterPosition.java index 543770d25..06f1a1879 100644 --- a/plugin/src/main/groovy/grails/plugin/springsecurity/SecurityFilterPosition.groovy +++ b/plugin/src/main/groovy/grails/plugin/springsecurity/SecurityFilterPosition.java @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package grails.plugin.springsecurity +package grails.plugin.springsecurity; /** * Stores the default order numbers of all Spring Security filters for use in configuration. @@ -23,63 +23,101 @@ * @author Burt Beckwith */ enum SecurityFilterPosition { - /** First */ + FIRST(Integer.MIN_VALUE), - /** HTTP/HTTPS channel filter */ + + DISABLE_ENCODE_URL_FILTER, + + FORCE_EAGER_SESSION_FILTER, + CHANNEL_FILTER, - /** Concurrent Sessions */ - CONCURRENT_SESSION_FILTER, - /** Populates the SecurityContextHolder */ + SECURITY_CONTEXT_FILTER, - /** Logout */ + + CONCURRENT_SESSION_FILTER, + + WEB_ASYNC_MANAGER_FILTER, + + HEADERS_FILTER, + + CORS_FILTER, + + SAML2_LOGOUT_REQUEST_FILTER, + + SAML2_LOGOUT_RESPONSE_FILTER, + + CSRF_FILTER, + + SAML2_LOGOUT_FILTER, + LOGOUT_FILTER, - /** x509 certs */ + + OAUTH2_AUTHORIZATION_REQUEST_FILTER, + + SAML2_AUTHENTICATION_REQUEST_FILTER, + X509_FILTER, - /** Pre-auth */ + PRE_AUTH_FILTER, - /** CAS */ + CAS_FILTER, - /** UsernamePasswordAuthenticationFilter */ + + OAUTH2_LOGIN_FILTER, + + SAML2_AUTHENTICATION_FILTER, + FORM_LOGIN_FILTER, - /** OpenID */ + OPENID_FILTER, - /** Not used, generates a dynamic login form */ + LOGIN_PAGE_FILTER, - /** Digest auth */ + + LOGOUT_PAGE_FILTER, + DIGEST_AUTH_FILTER, - /** Basic Auth */ + + BEARER_TOKEN_AUTH_FILTER, + BASIC_AUTH_FILTER, - /** saved request filter */ + REQUEST_CACHE_FILTER, - /** SecurityContextHolderAwareRequestFilter */ + SERVLET_API_SUPPORT_FILTER, - /** Remember-me cookie */ + + JAAS_API_SUPPORT_FILTER, + REMEMBER_ME_FILTER, - /** Anonymous auth */ + ANONYMOUS_FILTER, - /** SessionManagementFilter */ + + OAUTH2_AUTHORIZATION_CODE_GRANT_FILTER, + + WELL_KNOWN_CHANGE_PASSWORD_REDIRECT_FILTER, + SESSION_MANAGEMENT_FILTER, - /** Spring FormContentFilter allows www-url-form-encoded content-types to provide params in PUT requests */ - FORM_CONTENT_FILTER, - /** ExceptionTranslationFilter */ + EXCEPTION_TRANSLATION_FILTER, - /** FilterSecurityInterceptor */ + FILTER_SECURITY_INTERCEPTOR, - /** Switch user */ + SWITCH_USER_FILTER, - /** Last */ - LAST(Integer.MAX_VALUE) - private static final int INTERVAL = 100 + LAST(Integer.MAX_VALUE); + + private static final int INTERVAL = 100; - /** The position in the chain. */ - final int order + private final int order; - private SecurityFilterPosition() { - order = ordinal() * INTERVAL + SecurityFilterPosition() { + this.order = ordinal() * INTERVAL; } - private SecurityFilterPosition(int filterOrder) { - order = filterOrder + SecurityFilterPosition(int order) { + this.order = order; } + + public int getOrder() { + return this.order; + } + } diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityUtils.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityUtils.groovy index 2a79fc9db..9f1424898 100644 --- a/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityUtils.groovy +++ b/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityUtils.groovy @@ -762,7 +762,7 @@ final class SpringSecurityUtils { orderedNames[SecurityFilterPosition.SWITCH_USER_FILTER.order] = 'switchUserProcessingFilter' } - orderedNames[SecurityFilterPosition.FORM_CONTENT_FILTER.order] = 'formContentFilter' + orderedNames[SecurityFilterPosition.SWITCH_USER_FILTER.order+1] = 'formContentFilter' // add in filters contributed by secondary plugins orderedNames << SpringSecurityUtils.orderedFilters diff --git a/plugin/src/test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsSpec.groovy b/plugin/src/test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsSpec.groovy index e4f9f8ca7..92d10d631 100644 --- a/plugin/src/test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsSpec.groovy +++ b/plugin/src/test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsSpec.groovy @@ -17,6 +17,7 @@ package grails.plugin.springsecurity import grails.plugin.springsecurity.web.GrailsSecurityFilterChain import grails.plugin.springsecurity.web.SecurityRequestHolder import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl +import org.springframework.security.config.http.SecurityFiltersMapper import org.springframework.security.core.GrantedAuthority import org.springframework.security.core.authority.SimpleGrantedAuthority import org.springframework.security.web.FilterChainProxy @@ -340,6 +341,11 @@ class SpringSecurityUtilsSpec extends AbstractUnitSpec { !SpringSecurityUtils.ifAnyGranted('ROLE_4') } + void 'SecurityFilterPosition order should match SecurityFilters'() { + expect: + SecurityFilterPosition.SWITCH_USER_FILTER.order == SecurityFiltersMapper.SWITCH_USER_FILTER.order + } + void 'private constructor'() { expect: SecurityTestUtils.testPrivateConstructor SpringSecurityUtils diff --git a/plugin/src/test/groovy/org/springframework/security/config/http/SecurityFiltersMapper.groovy b/plugin/src/test/groovy/org/springframework/security/config/http/SecurityFiltersMapper.groovy new file mode 100644 index 000000000..0c939e751 --- /dev/null +++ b/plugin/src/test/groovy/org/springframework/security/config/http/SecurityFiltersMapper.groovy @@ -0,0 +1,5 @@ +package org.springframework.security.config.http + +class SecurityFiltersMapper { + static final SWITCH_USER_FILTER = SecurityFilters.SWITCH_USER_FILTER +} \ No newline at end of file