From 5818336b4fa47953340d44064ec01be51753fc17 Mon Sep 17 00:00:00 2001
From: Brian Koehmstedt <1261658+bkoehm@users.noreply.github.com>
Date: Fri, 13 Sep 2024 11:59:07 -0700
Subject: [PATCH 01/30] Grails 7
---
.github/workflows/gradle.yml | 8 +-
README.md | 1 +
buildSrc/build.gradle | 2 +-
examples/functional-test-app/build.gradle | 12 +-
.../grails-app/conf/application.groovy | 12 ++
.../grails-app/views/error.gsp | 4 +-
.../BasicAuthCacheUsersSecuritySpec.groovy | 151 ++++++++++++++++++
.../groovy/specs/RoleSpec.groovy | 1 +
.../groovy/specs/UserSpec.groovy | 1 +
.../com/testapp/MaintenanceModeFilter.groovy | 12 +-
.../TestUserPasswordEncoderListener.groovy | 2 +-
examples/integration-test-app/build.gradle | 2 +-
.../springsecurity/SecurityTagLibSpec.groovy | 4 +-
.../SpringSecurityUtilsIntegrationSpec.groovy | 6 +-
.../com/test/AdditionalLogoutHandler.groovy | 4 +-
gradle/buildsrc.libs.versions.toml | 6 +-
gradle/groovy-config.gradle | 5 +-
gradle/java-config.gradle | 2 +-
gradle/libs.versions.toml | 60 +++----
gradle/wrapper/gradle-wrapper.properties | 2 +-
plugin/build.gradle | 8 +-
.../springsecurity/LoginController.groovy | 2 +-
.../springsecurity/LogoutController.groovy | 2 +-
.../SpringSecurityService.groovy | 2 +-
.../springsecurity/SecurityTagLib.groovy | 2 +-
.../grails-app/views/error.gsp | 4 +-
.../grails-app/views/error.gsp | 4 +-
.../grails-app/views/error.gsp | 4 +-
.../s2-quickstart/grails-app/views/error.gsp | 4 +-
.../SpringSecurityCoreGrailsPlugin.groovy | 22 +--
.../springsecurity/SpringSecurityUtils.groovy | 6 +-
.../cache/SpringUserCacheFactoryBean.groovy | 58 +++++++
.../web/GrailsRedirectStrategy.groovy | 4 +-
.../web/GrailsSecurityFilterChain.groovy | 4 +-
.../web/SecurityRequestHolder.groovy | 4 +-
.../web/SecurityRequestHolderFilter.groovy | 14 +-
...extHolderExceptionTranslationFilter.groovy | 12 +-
.../AjaxAwareAccessDeniedHandler.groovy | 6 +-
.../access/DefaultThrowableAnalyzer.groovy | 2 +-
...ailsWebInvocationPrivilegeEvaluator.groovy | 10 +-
.../AbstractFilterInvocationDefinition.groovy | 8 +-
...nnotationFilterInvocationDefinition.groovy | 10 +-
.../AjaxAwareAuthenticationEntryPoint.groovy | 6 +-
...axAwareAuthenticationFailureHandler.groovy | 6 +-
...axAwareAuthenticationSuccessHandler.groovy | 6 +-
.../FilterProcessUrlRequestMatcher.groovy | 2 +-
...sernamePasswordAuthenticationFilter.groovy | 6 +-
...NullLogoutHandlerRememberMeServices.groovy | 4 +-
.../logout/MutableLogoutFilter.groovy | 12 +-
.../NullAuthenticationFailureHandler.groovy | 6 +-
.../NullAuthenticationSuccessHandler.groovy | 6 +-
.../web/filter/DebugFilter.groovy | 10 +-
...GrailsAnonymousAuthenticationFilter.groovy | 10 +-
...railsRememberMeAuthenticationFilter.groovy | 4 +-
.../filter/HttpMethodOverrideDetector.groovy | 2 +-
.../web/filter/IpAddressFilter.groovy | 12 +-
.../AuthorityGroupAuthority.groovy.template | 2 +-
.../templates/PersonAuthority.groovy.template | 2 +-
.../PersonAuthorityGroup.groovy.template | 2 +-
...ordEncoderListenerWithSalt.groovy.template | 2 +-
.../springsecurity/SecurityTestUtils.groovy | 2 +-
.../SpringSecurityUtilsSpec.groovy | 6 +-
.../SecurityRequestHolderFilterSpec.groovy | 2 +-
.../logout/MutableLogoutFilterSpec.groovy | 2 +-
.../web/filter/IpAddressFilterSpec.groovy | 2 +-
65 files changed, 418 insertions(+), 185 deletions(-)
create mode 100644 examples/functional-test-app/src/integration-test/groovy/specs/BasicAuthCacheUsersSecuritySpec.groovy
create mode 100644 plugin/src/main/groovy/grails/plugin/springsecurity/cache/SpringUserCacheFactoryBean.groovy
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index 3c394a088..b8be082b2 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -21,7 +21,7 @@ jobs:
- uses: actions/checkout@v4
- uses: gradle/wrapper-validation-action@v2
- uses: actions/setup-java@v4
- with: { java-version: 11, distribution: temurin }
+ with: { java-version: 17, distribution: temurin }
- name: Run Tests
uses: gradle/actions/setup-gradle@v3
env:
@@ -36,11 +36,11 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- test-config: [ 'static', 'annotation', 'requestmap', 'basic', 'misc', 'putWithParams', 'bcrypt', 'issue503' ]
+ test-config: [ 'static', 'annotation', 'requestmap', 'basic', 'basicCacheUsers', 'misc', 'putWithParams', 'bcrypt', 'issue503' ]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- with: { java-version: 11, distribution: temurin }
+ with: { java-version: 17, distribution: temurin }
- name: Run Tests
uses: gradle/actions/setup-gradle@v3
env:
@@ -58,7 +58,7 @@ jobs:
- uses: actions/checkout@v4
- uses: gradle/wrapper-validation-action@v2
- uses: actions/setup-java@v4
- with: { java-version: 11, distribution: temurin }
+ with: { java-version: 17, distribution: temurin }
- name: Run Build
id: build
uses: gradle/actions/setup-gradle@v3
diff --git a/README.md b/README.md
index 6f96b4b3e..2a79f7aef 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,7 @@ See [documentation](https://grails-plugins.github.io/grails-spring-security-core
### Branch structure
+- `7.0.x` compatible with Grails 7
- `6.0.x` compatible with Grails 6
- `5.0.x` compatible with Grails 5
- `4.0.x` compatible with Grails 4
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index f8da12941..f5f4d22ba 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -9,7 +9,7 @@ dependencies {
implementation buildsrcLibs.grails.gradle.plugin, {
// Grails Gradle plugin leaks groovy-xml onto compile classpath
// which is causes a version conflict for Gradle
- exclude group: 'org.codehaus.groovy', module: 'groovy-xml'
+ exclude group: 'org.apache.groovy', module: 'groovy-xml'
}
implementation buildsrcLibs.webdriver.binaries.gradle.plugin
diff --git a/examples/functional-test-app/build.gradle b/examples/functional-test-app/build.gradle
index 9b471fcc7..8185ded74 100644
--- a/examples/functional-test-app/build.gradle
+++ b/examples/functional-test-app/build.gradle
@@ -8,6 +8,12 @@ plugins {
group = 'examples.test'
+configurations {
+ all {
+ exclude group: 'io.micronaut', module:'micronaut-inject-groovy'
+ }
+}
+
dependencies {
implementation project(':spring-security-core')
@@ -23,6 +29,7 @@ dependencies {
implementation libs.spring.security.core
implementation libs.spring.web
+ runtimeOnly libs.micronaut.jackson.databind
runtimeOnly libs.gorm.hibernate5
runtimeOnly libs.grails.asset.pipeline
runtimeOnly libs.grails.i18n
@@ -35,9 +42,8 @@ dependencies {
runtimeOnly libs.h2database
runtimeOnly libs.tomcat.jdbc
- compileOnly libs.micronaut.inject.groovy
- compileOnly libs.javax.annotation.api
- compileOnly libs.javax.servlet.api
+ compileOnly libs.jakarta.annotation.api
+ compileOnly libs.jakarta.servlet.api
compileOnly libs.slf4j.nop // Prevent warnings about missing SLF4j implementation during GSP compilation
}
diff --git a/examples/functional-test-app/grails-app/conf/application.groovy b/examples/functional-test-app/grails-app/conf/application.groovy
index 10fef5123..15f928f2a 100644
--- a/examples/functional-test-app/grails-app/conf/application.groovy
+++ b/examples/functional-test-app/grails-app/conf/application.groovy
@@ -49,6 +49,18 @@ switch (testconfig) {
]
break
+ case 'basicCacheUsers':
+ grails.plugin.springsecurity.securityConfigType = 'Annotation'
+ grails.plugin.springsecurity.useBasicAuth = true
+ grails.plugin.springsecurity.basic.realmName = 'Grails Spring Security Basic Test Realm'
+ grails.plugin.springsecurity.filterChain.chainMap = [
+ [pattern: '/secureclassannotated/**', filters: 'JOINED_FILTERS,-exceptionTranslationFilter'],
+ [pattern: '/**', filters: 'JOINED_FILTERS,-basicAuthenticationFilter,-basicExceptionTranslationFilter']
+ ]
+ grails.plugin.springsecurity.cacheUsers = true
+ grails.plugin.springsecurity.providerManager.eraseCredentialsAfterAuthentication = false
+ break
+
case 'bcrypt':
grails.plugin.springsecurity.securityConfigType = 'Annotation'
grails.plugin.springsecurity.password.algorithm = 'bcrypt'
diff --git a/examples/functional-test-app/grails-app/views/error.gsp b/examples/functional-test-app/grails-app/views/error.gsp
index 419d66668..06820cf89 100644
--- a/examples/functional-test-app/grails-app/views/error.gsp
+++ b/examples/functional-test-app/grails-app/views/error.gsp
@@ -6,8 +6,8 @@
-
-
+
+
diff --git a/examples/functional-test-app/src/integration-test/groovy/specs/BasicAuthCacheUsersSecuritySpec.groovy b/examples/functional-test-app/src/integration-test/groovy/specs/BasicAuthCacheUsersSecuritySpec.groovy
new file mode 100644
index 000000000..2be33d916
--- /dev/null
+++ b/examples/functional-test-app/src/integration-test/groovy/specs/BasicAuthCacheUsersSecuritySpec.groovy
@@ -0,0 +1,151 @@
+package specs
+
+import org.springframework.security.core.userdetails.UserCache
+import pages.LoginPage
+import pages.role.CreateRolePage
+import pages.role.ListRolePage
+import pages.role.ShowRolePage
+import pages.user.CreateUserPage
+import pages.user.ListUserPage
+import pages.user.ShowUserPage
+import spock.lang.IgnoreIf
+
+@IgnoreIf({ System.getProperty('TESTCONFIG') != 'basicCacheUsers' })
+class BasicAuthCacheUsersSecuritySpec extends AbstractSecuritySpec {
+
+ private HttpURLConnection connection
+ UserCache userCache
+
+ void 'create roles'() {
+ when:
+ to ListRolePage
+
+ then:
+ roleRows.size() == 0
+
+ when:
+ newRoleButton.click()
+
+ then:
+ at CreateRolePage
+
+ when:
+ authority = 'ROLE_ADMIN'
+ createButton.click()
+
+ then:
+ at ShowRolePage
+
+ when:
+ to ListRolePage
+
+ then:
+ roleRows.size() == 1
+
+ when:
+ newRoleButton.click()
+
+ then:
+ at CreateRolePage
+
+ when:
+ authority = 'ROLE_ADMIN2'
+ createButton.click()
+
+ then:
+ at ShowRolePage
+
+ when:
+ to ListRolePage
+
+ then:
+ roleRows.size() == 2
+ }
+
+ void 'create users'() {
+ when:
+ to ListUserPage
+
+ then:
+ userRows.size() == 0
+
+ when:
+ newUserButton.click()
+
+ then:
+ at CreateUserPage
+
+ when:
+ username = 'admin1'
+ password = 'password1'
+ $('#enabled').click()
+ $('#ROLE_ADMIN').click()
+ createButton.click()
+
+ then:
+ at ShowUserPage
+
+ when:
+ to ListUserPage
+
+ then:
+ userRows.size() == 1
+
+ when:
+ newUserButton.click()
+
+ then:
+ at CreateUserPage
+
+ when:
+ username = 'admin2'
+ password = 'password2'
+ $('#enabled').click()
+ $('#ROLE_ADMIN').click()
+ $('#ROLE_ADMIN2').click()
+ createButton.click()
+
+ then:
+ at ShowUserPage
+
+ when:
+ to ListUserPage
+
+ then:
+ userRows.size() == 2
+ }
+
+ @IgnoreIf({ !System.getProperty('geb.env') })
+ void 'check userDetails caching'() {
+
+ when:
+ go 'secureAnnotated'
+
+ then:
+ at LoginPage
+
+ when:
+ login 'admin1', 'password1'
+
+ then:
+ assertContentContains 'you have ROLE_ADMIN'
+
+ and:
+ userCache.getUserFromCache('admin1')
+
+ cleanup:
+ logout()
+ }
+
+ protected void logout() {
+ super.logout()
+ // cheesy, but the 'Authentication' header from basic auth
+ // isn't cleared, so this forces an invalid header
+ getWithAuth '', 'not_a_valid_username', ''
+ }
+
+ private void getWithAuth(String path, String username, String password) {
+ String uri = new URI(baseUrlRequired).resolve(new URI(path))
+ go uri.replace('http://', 'http://' + username + ':' + password + '@')
+ }
+}
diff --git a/examples/functional-test-app/src/integration-test/groovy/specs/RoleSpec.groovy b/examples/functional-test-app/src/integration-test/groovy/specs/RoleSpec.groovy
index 1a23ab9a4..950c13855 100644
--- a/examples/functional-test-app/src/integration-test/groovy/specs/RoleSpec.groovy
+++ b/examples/functional-test-app/src/integration-test/groovy/specs/RoleSpec.groovy
@@ -9,6 +9,7 @@ import spock.lang.IgnoreIf
@IgnoreIf({ !(
System.getProperty('TESTCONFIG') == 'annotation' ||
System.getProperty('TESTCONFIG') == 'basic' ||
+ System.getProperty('TESTCONFIG') == 'basicCacheUsers' ||
System.getProperty('TESTCONFIG') == 'requestmap' ||
System.getProperty('TESTCONFIG') == 'static')
})
diff --git a/examples/functional-test-app/src/integration-test/groovy/specs/UserSpec.groovy b/examples/functional-test-app/src/integration-test/groovy/specs/UserSpec.groovy
index b8415c099..77729618f 100644
--- a/examples/functional-test-app/src/integration-test/groovy/specs/UserSpec.groovy
+++ b/examples/functional-test-app/src/integration-test/groovy/specs/UserSpec.groovy
@@ -9,6 +9,7 @@ import spock.lang.IgnoreIf
@IgnoreIf({ !(
System.getProperty('TESTCONFIG') == 'annotation' ||
System.getProperty('TESTCONFIG') == 'basic' ||
+ System.getProperty('TESTCONFIG') == 'basicCacheUsers' ||
System.getProperty('TESTCONFIG') == 'requestmap' ||
System.getProperty('TESTCONFIG') == 'static')
})
diff --git a/examples/functional-test-app/src/main/groovy/com/testapp/MaintenanceModeFilter.groovy b/examples/functional-test-app/src/main/groovy/com/testapp/MaintenanceModeFilter.groovy
index 570d910b3..1eb8a71ab 100644
--- a/examples/functional-test-app/src/main/groovy/com/testapp/MaintenanceModeFilter.groovy
+++ b/examples/functional-test-app/src/main/groovy/com/testapp/MaintenanceModeFilter.groovy
@@ -3,12 +3,12 @@ package com.testapp
import groovy.util.logging.Slf4j
import org.springframework.web.filter.GenericFilterBean
-import javax.servlet.FilterChain
-import javax.servlet.ServletException
-import javax.servlet.ServletRequest
-import javax.servlet.ServletResponse
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.FilterChain
+import jakarta.servlet.ServletException
+import jakarta.servlet.ServletRequest
+import jakarta.servlet.ServletResponse
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
/**
* If registered, this filter results in an HttpStatus of 500 being returned to the client
diff --git a/examples/functional-test-app/src/main/groovy/com/testapp/TestUserPasswordEncoderListener.groovy b/examples/functional-test-app/src/main/groovy/com/testapp/TestUserPasswordEncoderListener.groovy
index f7551f43c..2e8fbd9f5 100644
--- a/examples/functional-test-app/src/main/groovy/com/testapp/TestUserPasswordEncoderListener.groovy
+++ b/examples/functional-test-app/src/main/groovy/com/testapp/TestUserPasswordEncoderListener.groovy
@@ -7,7 +7,7 @@ import org.grails.datastore.mapping.engine.event.PreUpdateEvent
import org.springframework.beans.factory.annotation.Autowired
import grails.events.annotation.gorm.Listener
import groovy.transform.CompileStatic
-import javax.annotation.PostConstruct
+import jakarta.annotation.PostConstruct
@CompileStatic
class TestUserPasswordEncoderListener {
diff --git a/examples/integration-test-app/build.gradle b/examples/integration-test-app/build.gradle
index 1432dfa39..4c7dac804 100644
--- a/examples/integration-test-app/build.gradle
+++ b/examples/integration-test-app/build.gradle
@@ -33,7 +33,7 @@ dependencies {
runtimeOnly libs.tomcat.jdbc
compileOnly libs.micronaut.inject.groovy
- compileOnly libs.javax.servlet.api
+ compileOnly libs.jakarta.servlet.api
compileOnly libs.slf4j.nop
testImplementation libs.spock.core
diff --git a/examples/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/SecurityTagLibSpec.groovy b/examples/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/SecurityTagLibSpec.groovy
index 893bf58cf..477da685b 100644
--- a/examples/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/SecurityTagLibSpec.groovy
+++ b/examples/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/SecurityTagLibSpec.groovy
@@ -34,8 +34,8 @@ import org.springframework.web.context.request.RequestContextHolder
import spock.lang.Ignore
import spock.lang.Shared
-import javax.servlet.FilterChain
-import javax.servlet.ServletContext
+import jakarta.servlet.FilterChain
+import jakarta.servlet.ServletContext
import java.security.Principal
/**
diff --git a/examples/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsIntegrationSpec.groovy b/examples/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsIntegrationSpec.groovy
index 81fa0d968..d120cf660 100644
--- a/examples/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsIntegrationSpec.groovy
+++ b/examples/integration-test-app/src/integration-test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsIntegrationSpec.groovy
@@ -36,9 +36,9 @@ import test.TestRole
import test.TestUser
import test.TestUserRole
-import javax.servlet.FilterChain
-import javax.servlet.ServletRequest
-import javax.servlet.ServletResponse
+import jakarta.servlet.FilterChain
+import jakarta.servlet.ServletRequest
+import jakarta.servlet.ServletResponse
/**
* Integration tests for SpringSecurityUtils
.
diff --git a/examples/integration-test-app/src/main/groovy/com/test/AdditionalLogoutHandler.groovy b/examples/integration-test-app/src/main/groovy/com/test/AdditionalLogoutHandler.groovy
index 59da3b1bd..9a9c5ffea 100644
--- a/examples/integration-test-app/src/main/groovy/com/test/AdditionalLogoutHandler.groovy
+++ b/examples/integration-test-app/src/main/groovy/com/test/AdditionalLogoutHandler.groovy
@@ -1,7 +1,7 @@
package com.test
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
import org.springframework.security.core.Authentication
import org.springframework.security.web.authentication.logout.LogoutHandler
diff --git a/gradle/buildsrc.libs.versions.toml b/gradle/buildsrc.libs.versions.toml
index 3177c3c6e..71c3ce95e 100644
--- a/gradle/buildsrc.libs.versions.toml
+++ b/gradle/buildsrc.libs.versions.toml
@@ -1,7 +1,7 @@
[versions]
-asciidoctorj = '4.0.2'
-asset-pipeline-gradle = '4.4.0'
-grails-gradle-plugin = '6.1.2'
+asciidoctorj = '4.0.3'
+asset-pipeline-gradle = '5.0.1'
+grails-gradle-plugin = '7.0.0-SNAPSHOT'
webdriver-binaries = '3.2'
spock = '2.3-groovy-3.0'
diff --git a/gradle/groovy-config.gradle b/gradle/groovy-config.gradle
index e40f8102f..362a10c4b 100644
--- a/gradle/groovy-config.gradle
+++ b/gradle/groovy-config.gradle
@@ -1,8 +1,9 @@
configurations.configureEach {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
- if (details.requested.group == 'org.codehaus.groovy') {
+ if ((details.requested.group == 'org.codehaus.groovy' || details.requested.group == 'org.apache.groovy') && details.requested.name != 'groovy-bom') {
String groovyVersion = findProperty('groovyVersion') ?: libs.versions.groovy.get()
- details.useVersion(groovyVersion)
+ details.useTarget(group: 'org.apache.groovy', name: details.requested.name, version: groovyVersion)
+ details.because "The dependency coordinates are changed in Apache Groovy 4, plus ensure version"
}
}
}
diff --git a/gradle/java-config.gradle b/gradle/java-config.gradle
index 0bad9f3ac..3132d5647 100644
--- a/gradle/java-config.gradle
+++ b/gradle/java-config.gradle
@@ -1,5 +1,5 @@
java {
- sourceCompatibility = JavaVersion.VERSION_11
+ sourceCompatibility = JavaVersion.VERSION_17
withJavadocJar()
withSourcesJar()
}
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 0dbdae2e1..c98dcfd02 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,32 +1,32 @@
[versions]
-asset-pipeline = '4.3.0'
+asset-pipeline = '5.0.1'
commons-lang = '2.6'
-ehcache = '2.10.9.2'
-geb = '6.0'
-gorm-hibernate5 = '8.0.3'
-grails = '6.1.2'
-grails-async-and-events = '5.0.2'
-grails-datamapping = '8.0.3'
-grails-gsp = '6.2.0'
-grails-converters = '4.0.1'
-grails-testing-support = '3.1.2'
-groovy = '3.0.21'
-h2database = '2.2.224'
-javax-annotation-api = '1.3.2'
-javax-servlet-api = '4.0.1'
-micronaut = '3.10.4'
-selenium = '4.18.1'
-selenium-safari = '4.18.1'
-slf4j = '1.7.36'
-spock = '2.0-groovy-3.0'
-spring = '5.3.33'
-springboot = '2.7.18'
-spring-security = '5.8.11'
-tomcat = '9.0.87'
+ehcache = '3.10.8'
+geb = '7.0'
+gorm-hibernate5 = '9.0.0-SNAPSHOT'
+grails = '7.0.0-SNAPSHOT'
+grails-async-and-events = '7.0.0-SNAPSHOT'
+grails-datamapping = '9.0.0-SNAPSHOT'
+grails-gsp = '7.0.0-SNAPSHOT'
+grails-converters = '6.0.0-SNAPSHOT'
+grails-testing-support = '4.0.0-SNAPSHOT'
+groovy = '4.0.22'
+h2database = '2.3.232'
+jakarta-annotation-api = '3.0.0'
+jakarta-servlet-api = '6.0.0'
+micronaut = '4.5.3'
+selenium = '4.19.1'
+selenium-safari = '4.19.1'
+slf4j = '2.0.16'
+spock = '2.3-groovy-4.0'
+spring = '6.1.12'
+springboot = '3.3.3'
+spring-security = '6.3.3'
+tomcat = '10.1.29'
[libraries]
commons-lang = { module = 'commons-lang:commons-lang', version.ref = 'commons-lang' }
-ehcache = { module = 'net.sf.ehcache:ehcache', version.ref = 'ehcache' }
+ehcache = { module = 'org.ehcache:ehcache', version.ref = 'ehcache' }
geb-core = { module = 'org.gebish:geb-core', version.ref = 'geb' }
geb-spock = { module = 'org.gebish:geb-spock', version.ref = 'geb' }
gorm-hibernate5 = { module = 'org.grails.plugins:hibernate5', version.ref = 'gorm-hibernate5' }
@@ -39,7 +39,6 @@ grails-datastore-gorm = { module = 'org.grails:grails-datastore-gorm', version.r
grails-domain = { module = 'org.grails:grails-plugin-domain-class', version.ref = 'grails' }
grails-events-transform = { module = 'org.grails:grails-events-transform', version.ref = 'grails-async-and-events' }
grails-gsp = { module = 'org.grails.plugins:gsp', version.ref = 'grails-gsp' }
-grails-gorm-testing-support = { module = 'org.grails:grails-gorm-testing-support', version.ref = 'grails-testing-support' }
grails-i18n = { module = 'org.grails:grails-plugin-i18n', version.ref = 'grails' }
grails-interceptors = { module = 'org.grails:grails-plugin-interceptors', version.ref = 'grails' }
grails-mimetypes = { module = 'org.grails:grails-plugin-mimetypes', version.ref = 'grails' }
@@ -51,14 +50,14 @@ grails-testing-support-web = { module = 'org.grails:grails-web-testing-support',
grails-urlmappings = { module = 'org.grails:grails-plugin-url-mappings', version.ref = 'grails' }
grails-validation = { module = 'org.grails:grails-plugin-validation', version.ref = 'grails' }
grails-web-common = { module = 'org.grails:grails-web-common', version.ref = 'grails' }
-grails-web-testing-support = { module = 'org.grails:grails-web-testing-support', version.ref = 'grails-testing-support' }
grails-web-urlmappings = { module = 'org.grails:grails-web-url-mappings', version.ref = 'grails' }
-groovy-core = { module = 'org.codehaus.groovy:groovy', version.ref = 'groovy' }
-javax-annotation-api = { module = 'javax.annotation:javax.annotation-api', version.ref = 'javax-annotation-api' }
-javax-servlet-api = { module = 'javax.servlet:javax.servlet-api', version.ref = 'javax-servlet-api' }
+groovy-core = { module = 'org.apache.groovy:groovy', version.ref = 'groovy' }
+jakarta-annotation-api = { module = 'jakarta.annotation:jakarta.annotation-api', version.ref = 'jakarta-annotation-api' }
+jakarta-servlet-api = { module = 'jakarta.servlet:jakarta.servlet-api', version.ref = 'jakarta-servlet-api' }
h2database = { module = 'com.h2database:h2', version.ref = 'h2database' }
micronaut-httpclient = { module = 'io.micronaut:micronaut-http-client', version.ref = 'micronaut' }
micronaut-inject-groovy = { module = 'io.micronaut:micronaut-inject-groovy', version.ref = 'micronaut' }
+micronaut-jackson-databind = { module = 'io.micronaut:micronaut-jackson-databind', version.ref = 'micronaut' }
selenium-api = { module = 'org.seleniumhq.selenium:selenium-api', version.ref = 'selenium' }
selenium-chrome-driver = { module = 'org.seleniumhq.selenium:selenium-chrome-driver', version.ref = 'selenium' }
selenium-chromium-driver = { module = 'org.seleniumhq.selenium:selenium-chromium-driver', version.ref = 'selenium' }
@@ -85,10 +84,11 @@ spring-web = { module = 'org.springframework:spring-web', version.ref = 'spring'
springboot-autoconfigure = { module = 'org.springframework.boot:spring-boot-autoconfigure', version.ref = 'springboot' }
springboot-core = { module = 'org.springframework.boot:spring-boot', version.ref = 'springboot' }
springboot-starter-logging = { module = 'org.springframework.boot:spring-boot-starter-logging', version.ref = 'springboot' }
+springboot-starter-test = { module = 'org.springframework.boot:spring-boot-starter-test', version.ref = 'springboot' }
springboot-starter-tomcat = { module = 'org.springframework.boot:spring-boot-starter-tomcat', version.ref = 'springboot' }
tomcat-jdbc = { module = 'org.apache.tomcat:tomcat-jdbc', version.ref = 'tomcat' }
[bundles]
geb = ['geb-core', 'geb-spock']
-grails-testing-support = ['grails-testing-support-gorm', 'grails-testing-support-web']
+grails-testing-support = ['grails-testing-support-gorm', 'grails-testing-support-web', 'springboot-starter-test']
selenium = ['selenium-api', 'selenium-chrome-driver', 'selenium-chromium-driver', 'selenium-devtools-v85', 'selenium-firefox-driver', 'selenium-http', 'selenium-json', 'selenium-remote-driver', 'selenium-safari-driver', 'selenium-support']
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index c7d437bbb..c44c2304c 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/plugin/build.gradle b/plugin/build.gradle
index f03a62481..a2c3246d1 100644
--- a/plugin/build.gradle
+++ b/plugin/build.gradle
@@ -9,6 +9,12 @@ plugins {
group = 'org.grails.plugins'
+configurations {
+ all {
+ exclude group: 'javax.servlet'
+ }
+}
+
dependencies {
api libs.grails.core
@@ -38,7 +44,7 @@ dependencies {
implementation libs.spring.tx
compileOnly libs.groovy.core // Compile-time annotations
- compileOnly libs.javax.servlet.api // Provided
+ compileOnly libs.jakarta.servlet.api // Provided
compileOnly libs.slf4j.nop // Prevents warnings about missing slf4j implementation during compilation
testImplementation libs.bundles.grails.testing.support
diff --git a/plugin/grails-app/controllers/grails/plugin/springsecurity/LoginController.groovy b/plugin/grails-app/controllers/grails/plugin/springsecurity/LoginController.groovy
index 1be4bdc64..bb503ec78 100644
--- a/plugin/grails-app/controllers/grails/plugin/springsecurity/LoginController.groovy
+++ b/plugin/grails-app/controllers/grails/plugin/springsecurity/LoginController.groovy
@@ -27,7 +27,7 @@ import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.web.WebAttributes
import org.springframework.security.web.authentication.session.SessionAuthenticationException
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.http.HttpServletResponse
@Secured('permitAll')
class LoginController {
diff --git a/plugin/grails-app/controllers/grails/plugin/springsecurity/LogoutController.groovy b/plugin/grails-app/controllers/grails/plugin/springsecurity/LogoutController.groovy
index 7540a20cc..864062bbe 100644
--- a/plugin/grails-app/controllers/grails/plugin/springsecurity/LogoutController.groovy
+++ b/plugin/grails-app/controllers/grails/plugin/springsecurity/LogoutController.groovy
@@ -17,7 +17,7 @@ package grails.plugin.springsecurity
import org.springframework.security.access.annotation.Secured
import org.springframework.security.web.RedirectStrategy
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.http.HttpServletResponse
@Secured('permitAll')
class LogoutController {
diff --git a/plugin/grails-app/services/grails/plugin/springsecurity/SpringSecurityService.groovy b/plugin/grails-app/services/grails/plugin/springsecurity/SpringSecurityService.groovy
index c66111007..1f2f8bc00 100644
--- a/plugin/grails-app/services/grails/plugin/springsecurity/SpringSecurityService.groovy
+++ b/plugin/grails-app/services/grails/plugin/springsecurity/SpringSecurityService.groovy
@@ -22,7 +22,7 @@ import org.springframework.security.authentication.AuthenticationTrustResolver
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.SecurityContextHolder as SCH
-import javax.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletRequest
/**
* Utility methods.
diff --git a/plugin/grails-app/taglib/grails/plugin/springsecurity/SecurityTagLib.groovy b/plugin/grails-app/taglib/grails/plugin/springsecurity/SecurityTagLib.groovy
index 923635c12..f0042a43b 100644
--- a/plugin/grails-app/taglib/grails/plugin/springsecurity/SecurityTagLib.groovy
+++ b/plugin/grails-app/taglib/grails/plugin/springsecurity/SecurityTagLib.groovy
@@ -25,7 +25,7 @@ import org.springframework.security.core.Authentication
import org.springframework.security.web.FilterInvocation
import org.springframework.security.web.access.WebInvocationPrivilegeEvaluator
-import javax.servlet.FilterChain
+import jakarta.servlet.FilterChain
/**
* Security tags.
diff --git a/plugin/src/docs/code/s2-quickstart-old/grails-app/views/error.gsp b/plugin/src/docs/code/s2-quickstart-old/grails-app/views/error.gsp
index 9a3bb8aa3..a2c4235ab 100644
--- a/plugin/src/docs/code/s2-quickstart-old/grails-app/views/error.gsp
+++ b/plugin/src/docs/code/s2-quickstart-old/grails-app/views/error.gsp
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/plugin/src/docs/code/s2-quickstart-requestmap/grails-app/views/error.gsp b/plugin/src/docs/code/s2-quickstart-requestmap/grails-app/views/error.gsp
index 9a3bb8aa3..a2c4235ab 100644
--- a/plugin/src/docs/code/s2-quickstart-requestmap/grails-app/views/error.gsp
+++ b/plugin/src/docs/code/s2-quickstart-requestmap/grails-app/views/error.gsp
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/plugin/src/docs/code/s2-quickstart-rolegroup/grails-app/views/error.gsp b/plugin/src/docs/code/s2-quickstart-rolegroup/grails-app/views/error.gsp
index 9a3bb8aa3..a2c4235ab 100644
--- a/plugin/src/docs/code/s2-quickstart-rolegroup/grails-app/views/error.gsp
+++ b/plugin/src/docs/code/s2-quickstart-rolegroup/grails-app/views/error.gsp
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/plugin/src/docs/code/s2-quickstart/grails-app/views/error.gsp b/plugin/src/docs/code/s2-quickstart/grails-app/views/error.gsp
index 9a3bb8aa3..a2c4235ab 100644
--- a/plugin/src/docs/code/s2-quickstart/grails-app/views/error.gsp
+++ b/plugin/src/docs/code/s2-quickstart/grails-app/views/error.gsp
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityCoreGrailsPlugin.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityCoreGrailsPlugin.groovy
index 1d32096de..fe6698786 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityCoreGrailsPlugin.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityCoreGrailsPlugin.groovy
@@ -20,6 +20,7 @@ import grails.plugin.springsecurity.access.vote.AuthenticatedVetoableDecisionMan
import grails.plugin.springsecurity.access.vote.ClosureVoter
import grails.plugin.springsecurity.authentication.GrailsAnonymousAuthenticationProvider
import grails.plugin.springsecurity.authentication.NullAuthenticationEventPublisher
+import grails.plugin.springsecurity.cache.SpringUserCacheFactoryBean
import grails.plugin.springsecurity.userdetails.DefaultPostAuthenticationChecks
import grails.plugin.springsecurity.userdetails.DefaultPreAuthenticationChecks
import grails.plugin.springsecurity.userdetails.GormUserDetailsService
@@ -58,8 +59,7 @@ import groovy.util.logging.Slf4j
import org.grails.web.mime.HttpServletResponseExtension
import org.springframework.boot.web.servlet.FilterRegistrationBean
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean
-import org.springframework.cache.ehcache.EhCacheFactoryBean
-import org.springframework.cache.ehcache.EhCacheManagerFactoryBean
+import org.springframework.cache.jcache.JCacheCacheManager
import org.springframework.core.Ordered
import org.springframework.expression.spel.standard.SpelExpressionParser
import org.springframework.security.access.event.LoggerListener
@@ -79,7 +79,6 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent
import org.springframework.security.core.context.SecurityContextHolder as SCH
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper
-import org.springframework.security.core.userdetails.cache.EhCacheBasedUserCache
import org.springframework.security.core.userdetails.cache.NullUserCache
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
@@ -131,7 +130,7 @@ import org.springframework.security.web.session.HttpSessionEventPublisher
import org.springframework.security.web.util.matcher.AnyRequestMatcher
import org.springframework.web.filter.FormContentFilter
-import javax.servlet.DispatcherType
+import jakarta.servlet.DispatcherType
/**
* @author Burt Beckwith
@@ -600,16 +599,11 @@ to default to 'Annotation'; setting value to 'Annotation'
// user details cache
if (conf.cacheUsers) {
log.trace 'Configuring user cache'
- userCache(classFor('userCache', EhCacheBasedUserCache)) {
- cache = ref('securityUserCache')
- }
- securityUserCache(classFor('securityUserCache', EhCacheFactoryBean)) {
+ userCache(classFor('userCache', SpringUserCacheFactoryBean)) {
cacheManager = ref('cacheManager')
cacheName = 'userCache'
}
- cacheManager(classFor('cacheManager', EhCacheManagerFactoryBean)) {
- cacheManagerName = 'spring-security-core-user-cache-' + UUID.randomUUID()
- }
+ cacheManager(classFor('cacheManager', JCacheCacheManager))
}
else {
userCache(classFor('userCache', NullUserCache))
@@ -1122,9 +1116,9 @@ to default to 'Annotation'; setting value to 'Annotation'
(ENCODING_ID_MD4): new Md4PasswordEncoder(),
(ENCODING_ID_MD5): messageDigestPasswordEncoderMD5,
(ENCODING_ID_NOOP): NoOpPasswordEncoder.getInstance(),
- (ENCODING_ID_PBKDF2): new Pbkdf2PasswordEncoder(),
- (ENCODING_ID_SCRYPT): new SCryptPasswordEncoder(),
- (ENCODING_ID_ARGON2): new Argon2PasswordEncoder(),
+ (ENCODING_ID_PBKDF2): Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8(),
+ (ENCODING_ID_SCRYPT): SCryptPasswordEncoder.defaultsForSpringSecurity_v5_8(),
+ (ENCODING_ID_ARGON2): Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8(),
(ENCODING_ID_SHA1): messageDigestPasswordEncoderSHA1,
(ENCODING_IDSHA256): messageDigestPasswordEncoderSHA256,
"sha256": new StandardPasswordEncoder()]
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityUtils.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityUtils.groovy
index 116b18408..ac31b19d1 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityUtils.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/SpringSecurityUtils.groovy
@@ -40,9 +40,9 @@ import org.springframework.security.web.savedrequest.SavedRequest
import org.springframework.util.StringUtils
import org.springframework.web.multipart.MultipartHttpServletRequest
-import javax.servlet.Filter
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpSession
+import jakarta.servlet.Filter
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpSession
import static org.springframework.security.web.context.HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/cache/SpringUserCacheFactoryBean.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/cache/SpringUserCacheFactoryBean.groovy
new file mode 100644
index 000000000..5f2a51e26
--- /dev/null
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/cache/SpringUserCacheFactoryBean.groovy
@@ -0,0 +1,58 @@
+/* Copyright 2024 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
+ *
+ * http://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 grails.plugin.springsecurity.cache
+
+import groovy.transform.CompileStatic
+import org.springframework.beans.factory.FactoryBean
+import org.springframework.beans.factory.InitializingBean
+import org.springframework.cache.jcache.JCacheCache
+import org.springframework.cache.jcache.JCacheCacheManager
+import org.springframework.security.core.userdetails.User
+import org.springframework.security.core.userdetails.cache.SpringCacheBasedUserCache
+import org.springframework.util.Assert
+
+import javax.cache.configuration.Configuration
+import javax.cache.configuration.MutableConfiguration
+
+@CompileStatic
+class SpringUserCacheFactoryBean implements FactoryBean, InitializingBean {
+
+ JCacheCacheManager cacheManager
+ String cacheName
+ Configuration cacheConfig
+ private SpringCacheBasedUserCache springUserCache
+
+ @Override
+ SpringCacheBasedUserCache getObject() throws Exception {
+ springUserCache
+ }
+
+ @Override
+ Class> getObjectType() {
+ SpringCacheBasedUserCache
+ }
+
+ @Override
+ void afterPropertiesSet() throws Exception {
+ Assert.notNull(cacheManager, "cacheManager mandatory")
+ Assert.notNull(cacheName, "cacheName mandatory")
+ if (!cacheConfig) {
+ cacheConfig = new MutableConfiguration()
+ .setTypes(String, User)
+ .setStoreByValue(false)
+ }
+ springUserCache = new SpringCacheBasedUserCache(new JCacheCache(cacheManager.cacheManager.createCache(cacheName, cacheConfig)))
+ }
+}
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/GrailsRedirectStrategy.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/GrailsRedirectStrategy.groovy
index d04bc050d..ba5569ee8 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/GrailsRedirectStrategy.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/GrailsRedirectStrategy.groovy
@@ -20,8 +20,8 @@ import org.springframework.security.web.PortResolver
import org.springframework.security.web.RedirectStrategy
import org.springframework.security.web.util.UrlUtils
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
/**
* Builds absolute urls when using header check channel security to prevent the
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/GrailsSecurityFilterChain.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/GrailsSecurityFilterChain.groovy
index 461fb095e..bb463ec82 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/GrailsSecurityFilterChain.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/GrailsSecurityFilterChain.groovy
@@ -20,8 +20,8 @@ import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.util.matcher.AntPathRequestMatcher
import org.springframework.security.web.util.matcher.RequestMatcher
-import javax.servlet.Filter
-import javax.servlet.http.HttpServletRequest
+import jakarta.servlet.Filter
+import jakarta.servlet.http.HttpServletRequest
/**
* Based on org.springframework.security.web.DefaultSecurityFilterChain which is final.
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/SecurityRequestHolder.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/SecurityRequestHolder.groovy
index 41d9e308d..5db996234 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/SecurityRequestHolder.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/SecurityRequestHolder.groovy
@@ -14,8 +14,8 @@
*/
package grails.plugin.springsecurity.web
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
import groovy.transform.CompileStatic
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/SecurityRequestHolderFilter.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/SecurityRequestHolderFilter.groovy
index fa207e969..7450f69ad 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/SecurityRequestHolderFilter.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/SecurityRequestHolderFilter.groovy
@@ -20,13 +20,13 @@ import org.springframework.security.web.PortMapper
import org.springframework.security.web.PortResolver
import org.springframework.web.filter.GenericFilterBean
-import javax.servlet.FilterChain
-import javax.servlet.ServletException
-import javax.servlet.ServletRequest
-import javax.servlet.ServletResponse
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletRequestWrapper
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.FilterChain
+import jakarta.servlet.ServletException
+import jakarta.servlet.ServletRequest
+import jakarta.servlet.ServletResponse
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletRequestWrapper
+import jakarta.servlet.http.HttpServletResponse
/**
* Stores the request and response in the {@link SecurityRequestHolder}. Also wraps the request in a
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/UpdateRequestContextHolderExceptionTranslationFilter.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/UpdateRequestContextHolderExceptionTranslationFilter.groovy
index f5c3e0c1e..72e8c9396 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/UpdateRequestContextHolderExceptionTranslationFilter.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/UpdateRequestContextHolderExceptionTranslationFilter.groovy
@@ -23,12 +23,12 @@ import org.springframework.security.web.access.ExceptionTranslationFilter
import org.springframework.security.web.savedrequest.RequestCache
import org.springframework.web.context.request.RequestContextHolder
-import javax.servlet.FilterChain
-import javax.servlet.ServletException
-import javax.servlet.ServletRequest
-import javax.servlet.ServletResponse
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.FilterChain
+import jakarta.servlet.ServletException
+import jakarta.servlet.ServletRequest
+import jakarta.servlet.ServletResponse
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
/**
* Replaces the current GrailsWebRequest with one that delegates to the real current instance but uses the request and
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/AjaxAwareAccessDeniedHandler.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/AjaxAwareAccessDeniedHandler.groovy
index f2269d711..a9f94403b 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/AjaxAwareAccessDeniedHandler.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/AjaxAwareAccessDeniedHandler.groovy
@@ -14,9 +14,9 @@
*/
package grails.plugin.springsecurity.web.access
-import javax.servlet.ServletException
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.ServletException
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
import org.springframework.beans.factory.InitializingBean
import org.springframework.security.access.AccessDeniedException
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/DefaultThrowableAnalyzer.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/DefaultThrowableAnalyzer.groovy
index 89107f397..59cae7008 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/DefaultThrowableAnalyzer.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/DefaultThrowableAnalyzer.groovy
@@ -14,7 +14,7 @@
*/
package grails.plugin.springsecurity.web.access
-import javax.servlet.ServletException
+import jakarta.servlet.ServletException
import org.springframework.security.web.util.ThrowableAnalyzer
import org.springframework.security.web.util.ThrowableCauseExtractor
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/GrailsWebInvocationPrivilegeEvaluator.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/GrailsWebInvocationPrivilegeEvaluator.groovy
index 266b9fac4..659e9c2b2 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/GrailsWebInvocationPrivilegeEvaluator.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/GrailsWebInvocationPrivilegeEvaluator.groovy
@@ -20,11 +20,11 @@ import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.Proxy
-import javax.servlet.FilterChain
-import javax.servlet.ServletRequest
-import javax.servlet.ServletResponse
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.FilterChain
+import jakarta.servlet.ServletRequest
+import jakarta.servlet.ServletResponse
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
import org.springframework.security.access.AccessDeniedException
import org.springframework.security.access.ConfigAttribute
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/intercept/AbstractFilterInvocationDefinition.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/intercept/AbstractFilterInvocationDefinition.groovy
index 7a4dc7e72..1651549a2 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/intercept/AbstractFilterInvocationDefinition.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/intercept/AbstractFilterInvocationDefinition.groovy
@@ -19,7 +19,7 @@ import org.springframework.web.util.UrlPathHelper
import java.util.concurrent.CopyOnWriteArrayList
-import javax.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletRequest
import org.springframework.context.support.MessageSourceAccessor
import org.springframework.http.HttpMethod
@@ -175,11 +175,11 @@ abstract class AbstractFilterInvocationDefinition implements FilterInvocationSec
}
/**
- * Resolve the URI from {@link javax.servlet.http.HttpServletRequest}
- * @param request The {@link javax.servlet.http.HttpServletRequest}
+ * Resolve the URI from {@link jakarta.servlet.http.HttpServletRequest}
+ * @param request The {@link jakarta.servlet.http.HttpServletRequest}
*
* @return The resolved URI string
- * @deprecated Use {@link org.springframework.web.util.UrlPathHelper#getRequestUri(javax.servlet.http.HttpServletRequest request)} and {@link #stripContextPath} instead
+ * @deprecated Use {@link org.springframework.web.util.UrlPathHelper#getRequestUri(jakarta.servlet.http.HttpServletRequest request)} and {@link #stripContextPath} instead
*/
@Deprecated
protected String calculateUri(HttpServletRequest request) {
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/intercept/AnnotationFilterInvocationDefinition.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/intercept/AnnotationFilterInvocationDefinition.groovy
index e66478712..02e0795f9 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/intercept/AnnotationFilterInvocationDefinition.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/intercept/AnnotationFilterInvocationDefinition.groovy
@@ -44,9 +44,11 @@ import org.springframework.util.ReflectionUtils
import org.springframework.util.StringUtils
import org.springframework.web.context.ServletContextAware
-import javax.servlet.ServletContext
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.RequestDispatcher
+import jakarta.servlet.ServletContext
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
+
import java.lang.annotation.Annotation
import java.lang.reflect.AccessibleObject
import java.lang.reflect.Constructor
@@ -93,7 +95,7 @@ class AnnotationFilterInvocationDefinition extends AbstractFilterInvocationDefin
existingRequest = WebUtils.retrieveGrailsWebRequest()
}
catch (IllegalStateException e) {
- if (request.getAttribute('javax.servlet.error.status_code') == 404) {
+ if (request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE) == 404) {
ERROR404
}
else {
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationEntryPoint.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationEntryPoint.groovy
index 4cbadcdf9..b02f3fe2c 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationEntryPoint.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationEntryPoint.groovy
@@ -14,9 +14,9 @@
*/
package grails.plugin.springsecurity.web.authentication
-import javax.servlet.ServletException
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.ServletException
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
import org.springframework.security.core.AuthenticationException
import org.springframework.security.web.RedirectStrategy
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationFailureHandler.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationFailureHandler.groovy
index c21483549..65e83c0c7 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationFailureHandler.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationFailureHandler.groovy
@@ -14,9 +14,9 @@
*/
package grails.plugin.springsecurity.web.authentication
-import javax.servlet.ServletException
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.ServletException
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
import org.springframework.beans.factory.InitializingBean
import org.springframework.security.core.AuthenticationException
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationSuccessHandler.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationSuccessHandler.groovy
index 90ac41ec6..06beb6ff3 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationSuccessHandler.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/AjaxAwareAuthenticationSuccessHandler.groovy
@@ -14,9 +14,9 @@
*/
package grails.plugin.springsecurity.web.authentication
-import javax.servlet.ServletException
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.ServletException
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
import org.springframework.security.core.Authentication
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/FilterProcessUrlRequestMatcher.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/FilterProcessUrlRequestMatcher.groovy
index ca6fe7b91..15072c8c2 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/FilterProcessUrlRequestMatcher.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/FilterProcessUrlRequestMatcher.groovy
@@ -14,7 +14,7 @@
*/
package grails.plugin.springsecurity.web.authentication
-import javax.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletRequest
import org.springframework.security.web.util.UrlUtils
import org.springframework.security.web.util.matcher.RequestMatcher
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/GrailsUsernamePasswordAuthenticationFilter.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/GrailsUsernamePasswordAuthenticationFilter.groovy
index ae135ecac..071af5284 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/GrailsUsernamePasswordAuthenticationFilter.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/GrailsUsernamePasswordAuthenticationFilter.groovy
@@ -20,9 +20,9 @@ import org.springframework.security.core.Authentication
import org.springframework.security.core.AuthenticationException
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-import javax.servlet.http.HttpSession
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
+import jakarta.servlet.http.HttpSession
/**
* Extends the default {@link UsernamePasswordAuthenticationFilter} to store the
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/NullLogoutHandlerRememberMeServices.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/NullLogoutHandlerRememberMeServices.groovy
index 0a41a67e6..02ed25e66 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/NullLogoutHandlerRememberMeServices.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/NullLogoutHandlerRememberMeServices.groovy
@@ -14,8 +14,8 @@
*/
package grails.plugin.springsecurity.web.authentication
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
import org.springframework.security.core.Authentication
import org.springframework.security.web.authentication.NullRememberMeServices
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/logout/MutableLogoutFilter.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/logout/MutableLogoutFilter.groovy
index 7accbd451..7a6f5cbb2 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/logout/MutableLogoutFilter.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/logout/MutableLogoutFilter.groovy
@@ -16,12 +16,12 @@ package grails.plugin.springsecurity.web.authentication.logout
import groovy.util.logging.Slf4j
-import javax.servlet.FilterChain
-import javax.servlet.ServletException
-import javax.servlet.ServletRequest
-import javax.servlet.ServletResponse
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.FilterChain
+import jakarta.servlet.ServletException
+import jakarta.servlet.ServletRequest
+import jakarta.servlet.ServletResponse
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.SecurityContextHolder
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/preauth/x509/NullAuthenticationFailureHandler.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/preauth/x509/NullAuthenticationFailureHandler.groovy
index 9d1955b3f..2f4ae2f15 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/preauth/x509/NullAuthenticationFailureHandler.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/preauth/x509/NullAuthenticationFailureHandler.groovy
@@ -18,9 +18,9 @@ import groovy.transform.CompileStatic
import org.springframework.security.core.AuthenticationException
import org.springframework.security.web.authentication.AuthenticationFailureHandler
-import javax.servlet.ServletException
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.ServletException
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
/**
* @author Burt Beckwith
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/preauth/x509/NullAuthenticationSuccessHandler.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/preauth/x509/NullAuthenticationSuccessHandler.groovy
index e738bada7..59367f9fd 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/preauth/x509/NullAuthenticationSuccessHandler.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/authentication/preauth/x509/NullAuthenticationSuccessHandler.groovy
@@ -18,9 +18,9 @@ import groovy.transform.CompileStatic
import org.springframework.security.core.Authentication
import org.springframework.security.web.authentication.AuthenticationSuccessHandler
-import javax.servlet.ServletException
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.ServletException
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
/**
* @author Burt Beckwith
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/DebugFilter.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/DebugFilter.groovy
index 587254938..7dc65a2a0 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/DebugFilter.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/DebugFilter.groovy
@@ -22,11 +22,11 @@ import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.util.UrlUtils
import org.springframework.web.filter.GenericFilterBean
-import javax.servlet.*
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletRequestWrapper
-import javax.servlet.http.HttpServletResponse
-import javax.servlet.http.HttpSession
+import jakarta.servlet.*
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletRequestWrapper
+import jakarta.servlet.http.HttpServletResponse
+import jakarta.servlet.http.HttpSession
/**
* Based on the package-scope org.springframework.security.config.debug.DebugFilter.
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/GrailsAnonymousAuthenticationFilter.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/GrailsAnonymousAuthenticationFilter.groovy
index cb58c892f..01590d1e2 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/GrailsAnonymousAuthenticationFilter.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/GrailsAnonymousAuthenticationFilter.groovy
@@ -16,11 +16,11 @@ package grails.plugin.springsecurity.web.filter
import groovy.util.logging.Slf4j
-import javax.servlet.FilterChain
-import javax.servlet.ServletException
-import javax.servlet.ServletRequest
-import javax.servlet.ServletResponse
-import javax.servlet.http.HttpServletRequest
+import jakarta.servlet.FilterChain
+import jakarta.servlet.ServletException
+import jakarta.servlet.ServletRequest
+import jakarta.servlet.ServletResponse
+import jakarta.servlet.http.HttpServletRequest
import org.springframework.security.authentication.AuthenticationDetailsSource
import org.springframework.security.core.Authentication
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/GrailsRememberMeAuthenticationFilter.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/GrailsRememberMeAuthenticationFilter.groovy
index 84f4ff66b..789933522 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/GrailsRememberMeAuthenticationFilter.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/GrailsRememberMeAuthenticationFilter.groovy
@@ -14,8 +14,8 @@
*/
package grails.plugin.springsecurity.web.filter
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.core.Authentication
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/HttpMethodOverrideDetector.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/HttpMethodOverrideDetector.groovy
index 7dc6cc1e5..8938d76f9 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/HttpMethodOverrideDetector.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/HttpMethodOverrideDetector.groovy
@@ -3,7 +3,7 @@ package grails.plugin.springsecurity.web.filter
import groovy.transform.CompileStatic
import org.springframework.util.Assert
-import javax.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletRequest
@CompileStatic
class HttpMethodOverrideDetector {
diff --git a/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/IpAddressFilter.groovy b/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/IpAddressFilter.groovy
index e63d1680e..63aa8f81d 100644
--- a/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/IpAddressFilter.groovy
+++ b/plugin/src/main/groovy/grails/plugin/springsecurity/web/filter/IpAddressFilter.groovy
@@ -24,12 +24,12 @@ import org.springframework.security.web.util.matcher.IpAddressMatcher
import org.springframework.util.AntPathMatcher
import org.springframework.web.filter.GenericFilterBean
-import javax.servlet.FilterChain
-import javax.servlet.ServletException
-import javax.servlet.ServletRequest
-import javax.servlet.ServletResponse
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.FilterChain
+import jakarta.servlet.ServletException
+import jakarta.servlet.ServletRequest
+import jakarta.servlet.ServletResponse
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
/**
* Blocks access to protected resources based on IP address. Sends 404 rather than
diff --git a/plugin/src/main/templates/AuthorityGroupAuthority.groovy.template b/plugin/src/main/templates/AuthorityGroupAuthority.groovy.template
index 48ef0234c..11c32c142 100644
--- a/plugin/src/main/templates/AuthorityGroupAuthority.groovy.template
+++ b/plugin/src/main/templates/AuthorityGroupAuthority.groovy.template
@@ -2,7 +2,7 @@ package ${packageName}
import grails.gorm.DetachedCriteria
import groovy.transform.ToString
-import org.codehaus.groovy.util.HashCodeHelper
+import org.apache.groovy.util.HashCodeHelper
import grails.compiler.GrailsCompileStatic
@GrailsCompileStatic
diff --git a/plugin/src/main/templates/PersonAuthority.groovy.template b/plugin/src/main/templates/PersonAuthority.groovy.template
index 940b9fba7..a96855cc3 100644
--- a/plugin/src/main/templates/PersonAuthority.groovy.template
+++ b/plugin/src/main/templates/PersonAuthority.groovy.template
@@ -3,7 +3,7 @@ package ${packageName}
import grails.gorm.DetachedCriteria
import grails.compiler.GrailsCompileStatic
import groovy.transform.ToString
-import org.codehaus.groovy.util.HashCodeHelper
+import org.apache.groovy.util.HashCodeHelper
@GrailsCompileStatic
@ToString(cache=true, includeNames=true, includePackage=false)
diff --git a/plugin/src/main/templates/PersonAuthorityGroup.groovy.template b/plugin/src/main/templates/PersonAuthorityGroup.groovy.template
index f79fba658..63ca66da0 100644
--- a/plugin/src/main/templates/PersonAuthorityGroup.groovy.template
+++ b/plugin/src/main/templates/PersonAuthorityGroup.groovy.template
@@ -2,7 +2,7 @@ package ${packageName}
import grails.gorm.DetachedCriteria
import groovy.transform.ToString
-import org.codehaus.groovy.util.HashCodeHelper
+import org.apache.groovy.util.HashCodeHelper
import grails.compiler.GrailsCompileStatic
@GrailsCompileStatic
diff --git a/plugin/src/main/templates/PersonPasswordEncoderListenerWithSalt.groovy.template b/plugin/src/main/templates/PersonPasswordEncoderListenerWithSalt.groovy.template
index c8da3caf1..2a0abc342 100644
--- a/plugin/src/main/templates/PersonPasswordEncoderListenerWithSalt.groovy.template
+++ b/plugin/src/main/templates/PersonPasswordEncoderListenerWithSalt.groovy.template
@@ -7,7 +7,7 @@ import org.grails.datastore.mapping.engine.event.PreUpdateEvent
import grails.events.annotation.gorm.Listener
import org.springframework.beans.factory.annotation.Autowired
import groovy.transform.CompileStatic
-import javax.annotation.PostConstruct
+import jakarta.annotation.PostConstruct
@CompileStatic
class ${userClassName}PasswordEncoderListener {
diff --git a/plugin/src/test/groovy/grails/plugin/springsecurity/SecurityTestUtils.groovy b/plugin/src/test/groovy/grails/plugin/springsecurity/SecurityTestUtils.groovy
index 3424f209e..2fda94dbc 100644
--- a/plugin/src/test/groovy/grails/plugin/springsecurity/SecurityTestUtils.groovy
+++ b/plugin/src/test/groovy/grails/plugin/springsecurity/SecurityTestUtils.groovy
@@ -46,7 +46,7 @@ class SecurityTestUtils {
* @return the authentication
*/
static Authentication authenticate(principal, credentials, List authorities) {
- Authentication authentication = new TestingAuthenticationToken(principal, credentials, authorities)
+ Authentication authentication = authorities != null ? new TestingAuthenticationToken(principal, credentials, authorities) : new TestingAuthenticationToken(principal, credentials)
authentication.authenticated = true
SCH.context.authentication = authentication
authentication
diff --git a/plugin/src/test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsSpec.groovy b/plugin/src/test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsSpec.groovy
index e4f9f8ca7..2bafcc75e 100644
--- a/plugin/src/test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsSpec.groovy
+++ b/plugin/src/test/groovy/grails/plugin/springsecurity/SpringSecurityUtilsSpec.groovy
@@ -25,9 +25,9 @@ import org.springframework.security.web.savedrequest.DefaultSavedRequest
import org.springframework.web.filter.GenericFilterBean
import spock.lang.Unroll
-import javax.servlet.FilterChain
-import javax.servlet.ServletRequest
-import javax.servlet.ServletResponse
+import jakarta.servlet.FilterChain
+import jakarta.servlet.ServletRequest
+import jakarta.servlet.ServletResponse
/**
* @author Burt Beckwith
diff --git a/plugin/src/test/groovy/grails/plugin/springsecurity/web/authentication/SecurityRequestHolderFilterSpec.groovy b/plugin/src/test/groovy/grails/plugin/springsecurity/web/authentication/SecurityRequestHolderFilterSpec.groovy
index fc1ce25a4..1f698abe9 100644
--- a/plugin/src/test/groovy/grails/plugin/springsecurity/web/authentication/SecurityRequestHolderFilterSpec.groovy
+++ b/plugin/src/test/groovy/grails/plugin/springsecurity/web/authentication/SecurityRequestHolderFilterSpec.groovy
@@ -18,7 +18,7 @@ import grails.plugin.springsecurity.AbstractUnitSpec
import grails.plugin.springsecurity.web.SecurityRequestHolder
import grails.plugin.springsecurity.web.SecurityRequestHolderFilter
-import javax.servlet.FilterChain
+import jakarta.servlet.FilterChain
/**
* @author Burt Beckwith
diff --git a/plugin/src/test/groovy/grails/plugin/springsecurity/web/authentication/logout/MutableLogoutFilterSpec.groovy b/plugin/src/test/groovy/grails/plugin/springsecurity/web/authentication/logout/MutableLogoutFilterSpec.groovy
index 3c43e233c..d35a2e20d 100644
--- a/plugin/src/test/groovy/grails/plugin/springsecurity/web/authentication/logout/MutableLogoutFilterSpec.groovy
+++ b/plugin/src/test/groovy/grails/plugin/springsecurity/web/authentication/logout/MutableLogoutFilterSpec.groovy
@@ -21,7 +21,7 @@ import org.springframework.mock.web.MockHttpServletResponse
import org.springframework.security.web.authentication.logout.LogoutHandler
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler
-import javax.servlet.FilterChain
+import jakarta.servlet.FilterChain
/**
* Unit tests for MutableLogoutFilter.
diff --git a/plugin/src/test/groovy/grails/plugin/springsecurity/web/filter/IpAddressFilterSpec.groovy b/plugin/src/test/groovy/grails/plugin/springsecurity/web/filter/IpAddressFilterSpec.groovy
index a4445e629..6b302d200 100644
--- a/plugin/src/test/groovy/grails/plugin/springsecurity/web/filter/IpAddressFilterSpec.groovy
+++ b/plugin/src/test/groovy/grails/plugin/springsecurity/web/filter/IpAddressFilterSpec.groovy
@@ -16,7 +16,7 @@ package grails.plugin.springsecurity.web.filter
import grails.plugin.springsecurity.AbstractUnitSpec
-import javax.servlet.FilterChain
+import jakarta.servlet.FilterChain
/**
* Unit tests for IpAddressFilter
.
From fb92b0d0ef122a77a084462f04d17e46b6ad1e23 Mon Sep 17 00:00:00 2001
From: Scott Murphy Heiberg
Date: Mon, 23 Sep 2024 22:00:29 -0500
Subject: [PATCH 02/30] Restore shell scripts
---
.../scripts/s2-create-persistent-token.groovy | 42 +++
.../s2-create-role-hierarchy-entry.groovy | 46 +++
plugin/src/main/scripts/s2-quickstart.groovy | 284 ++++++++++++++++++
3 files changed, 372 insertions(+)
create mode 100644 plugin/src/main/scripts/s2-create-persistent-token.groovy
create mode 100644 plugin/src/main/scripts/s2-create-role-hierarchy-entry.groovy
create mode 100644 plugin/src/main/scripts/s2-quickstart.groovy
diff --git a/plugin/src/main/scripts/s2-create-persistent-token.groovy b/plugin/src/main/scripts/s2-create-persistent-token.groovy
new file mode 100644
index 000000000..3ff7fdc2b
--- /dev/null
+++ b/plugin/src/main/scripts/s2-create-persistent-token.groovy
@@ -0,0 +1,42 @@
+/* Copyright 2006-2016 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
+ *
+ * http://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.
+ */
+
+import grails.codegen.model.Model
+
+description 'Creates a persistent token domain class for the Spring Security Core plugin', {
+ usage '''
+grails s2-create-persistent-token [DOMAIN CLASS NAME]
+
+Example: grails s2-create-persistent-token com.yourapp.PersistentLogin
+'''
+
+ argument name: 'Domain class name', description: 'The domain class full name with package'
+}
+
+String fullClassName = args[0]
+Model model = model(fullClassName)
+
+addStatus "\nCreating persistent token class $fullClassName"
+
+render template: template('PersistentLogin.groovy.template'),
+ destination: file("grails-app/domain/$model.packagePath/${model.simpleName}.groovy"),
+ model: model, overwrite: false
+
+file('grails-app/conf/application.groovy').withWriterAppend { BufferedWriter writer ->
+ writer.newLine()
+ writer.writeLine 'grails.plugin.springsecurity.rememberMe.persistent = true'
+ writer.writeLine "grails.plugin.springsecurity.rememberMe.persistentToken.domainClassName = '$fullClassName'"
+ writer.newLine()
+}
diff --git a/plugin/src/main/scripts/s2-create-role-hierarchy-entry.groovy b/plugin/src/main/scripts/s2-create-role-hierarchy-entry.groovy
new file mode 100644
index 000000000..669f17b3f
--- /dev/null
+++ b/plugin/src/main/scripts/s2-create-role-hierarchy-entry.groovy
@@ -0,0 +1,46 @@
+/* Copyright 2015-2016 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
+ *
+ * http://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.
+ */
+
+import grails.codegen.model.Model
+
+/**
+ * @author fpape
+ * @author Burt Beckwith
+ */
+
+description 'Creates a domain class for a persistent role hierarchy for the Spring Security Core plugin', {
+ usage '''
+grails s2-create-role-hierarchy-entry [DOMAIN CLASS NAME]
+
+Example: grails s2-create-role-hierarchy-entry com.yourapp.RoleHierarchyEntry
+'''
+
+ argument name: 'Domain class name', description: 'The domain class full name with package'
+}
+
+String fullClassName = args[0]
+Model model = model(fullClassName)
+
+addStatus "\nCreating role hierarchy entry class $fullClassName"
+
+render template: template('RoleHierarchyEntry.groovy.template'),
+ destination: file("grails-app/domain/$model.packagePath/${model.simpleName}.groovy"),
+ model: model, overwrite: false
+
+file('grails-app/conf/application.groovy').withWriterAppend { BufferedWriter writer ->
+ writer.newLine()
+ writer.writeLine "grails.plugin.springsecurity.roleHierarchyEntryClassName = '$fullClassName'"
+ writer.newLine()
+}
diff --git a/plugin/src/main/scripts/s2-quickstart.groovy b/plugin/src/main/scripts/s2-quickstart.groovy
new file mode 100644
index 000000000..3d02fadc0
--- /dev/null
+++ b/plugin/src/main/scripts/s2-quickstart.groovy
@@ -0,0 +1,284 @@
+/* Copyright 2006-2016 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
+ *
+ * http://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.
+ */
+
+import grails.codegen.model.Model
+import groovy.transform.Field
+
+@Field String usageMessage = '''
+ grails s2-quickstart [requestmap-class-name] [--groupClassName=group-class-name]
+or grails s2-quickstart --uiOnly
+
+Example: grails s2-quickstart com.yourapp User Role
+Example: grails s2-quickstart com.yourapp User Role --groupClassName=RoleGroup
+Example: grails s2-quickstart com.yourapp Person Authority Requestmap
+Example: grails s2-quickstart --uiOnly
+'''
+
+@Field Map templateAttributes
+@Field boolean uiOnly
+@Field boolean salt
+
+description 'Creates domain classes and updates config settings for the Spring Security plugin', {
+
+ usage usageMessage
+
+ argument name: 'Domain class package', description: 'The package to use for the domain classes', required: false
+ argument name: 'User class name', description: 'The name of the User/Person class', required: false
+ argument name: 'Role class name', description: 'The name of the Role class', required: false
+ argument name: 'Requestmap class name', description: 'The name of the Requestmap class', required: false
+
+ flag name: 'groupClassName', description: 'If specified, role/group classes will also be generated using the flag value as the role-group name'
+ flag name: 'uiOnly', description: 'If specified, no domain classes are created but the plugin settings are initialized (useful with LDAP, Mock, Shibboleth, etc.)'
+}
+
+Model userModel
+Model roleModel
+Model requestmapModel
+Model groupModel
+uiOnly = flag('uiOnly')
+salt = flag('salt')
+if (uiOnly) {
+ addStatus '\nConfiguring Spring Security; not generating domain classes'
+}
+else {
+
+ if (args.size() < 3) {
+ error 'Usage:' + usageMessage
+ return false
+ }
+
+ String packageName = args[0]
+ String groupClassName = flag('groupClassName')
+ String groupClassNameMessage = ''
+ if (groupClassName) {
+ groupModel = model(packageName + '.' + groupClassName)
+ groupClassNameMessage = ", and role/group classes for '" + groupModel.simpleName + "'"
+ }
+
+ userModel = model(packageName + '.' + args[1])
+ roleModel = model(packageName + '.' + args[2])
+
+ String message = "Creating User class '" + userModel.simpleName + "'"
+ if (4 == args.size()) {
+ requestmapModel = model(packageName + '.' + args[3])
+ message += ", Role class '" + roleModel.simpleName + "', and Requestmap class '" + requestmapModel.simpleName + "'" + groupClassNameMessage
+ }
+ else {
+ message += " and Role class '" + roleModel.simpleName + "'" + groupClassNameMessage
+ }
+ message += " in package '" + packageName + "'"
+ addStatus message
+
+ templateAttributes = [
+ packageName: userModel.packageName,
+ userClassName: userModel.simpleName,
+ userClassProperty: userModel.modelName,
+ roleClassName: roleModel.simpleName,
+ roleClassProperty: roleModel.modelName,
+ requestmapClassName: requestmapModel?.simpleName,
+ groupClassName: groupModel?.simpleName,
+ groupClassProperty: groupModel?.modelName]
+
+ createDomains userModel, roleModel, requestmapModel, groupModel
+}
+
+updateConfig userModel?.simpleName, roleModel?.simpleName, requestmapModel?.simpleName, userModel?.packageName, groupModel != null
+
+if (uiOnly) {
+ addStatus '''
+************************************************************
+* Your grails-app/conf/application.groovy has been updated *
+* with security settings; please verify that the *
+* values are correct. *
+************************************************************
+'''
+}
+else {
+ addStatus '''
+************************************************************
+* Created security-related domain classes. Your *
+* grails-app/conf/application.groovy has been updated with *
+* the class names of the configured domain classes; *
+* please verify that the values are correct. *
+************************************************************
+'''
+}
+
+private Map extractVersion(String versionString) {
+ def arr = versionString.split('\\.')
+ def v = [mayor: 0, minor: 0, bug: 0]
+ try {
+ if ( arr.size() >= 1) {
+ v.mayor = arr[0].toInteger()
+ }
+ if ( arr.size() >= 2) {
+ v.minor = arr[1].toInteger()
+ }
+ if ( arr.size() >= 3) {
+ v.bug = arr[2].toInteger()
+ }
+ } catch ( Exception e ) {
+ v = [mayor: 0, minor: 0, bug: 0]
+ }
+ v
+}
+
+private boolean versionAfterOrEqualsToThreshold(String threshold, String value) {
+ if ( value == null ) {
+ return false
+ }
+ if ( value.startsWith(threshold) ) {
+ return true
+ }
+
+ def va = extractVersion(value)
+ def vb = extractVersion(threshold)
+ def l = [va, vb]
+ l.sort { Map a, Map b ->
+ def compare = a.mayor <=> b.mayor
+ if ( compare != 0 ) {
+ return compare
+ }
+ compare = a.minor <=> b.minor
+ if ( compare != 0 ) {
+ return compare
+ }
+ a.bug <=> b.bug
+ }
+ def sortedValue = l[0].collect { k, v -> v }.join('.')
+ threshold.startsWith(sortedValue)
+}
+
+private void createDomains(Model userModel, Model roleModel, Model requestmapModel, Model groupModel) {
+
+ def props = new Properties()
+ file("gradle.properties")?.withInputStream { props.load(it) }
+
+ final threshold = '6.0.10'
+
+ boolean gormVersionAfterThreshold = versionAfterOrEqualsToThreshold(threshold, props.gormVersion ?: props.getProperty("gorm.version"))
+
+ if ( gormVersionAfterThreshold ) {
+ generateFile 'PersonWithoutInjection', userModel.packagePath, userModel.simpleName
+ if ( salt ) {
+ generateFile 'PersonPasswordEncoderListenerWithSalt', userModel.packagePath, userModel.simpleName, "${userModel.simpleName}PasswordEncoderListener", 'src/main/groovy'
+ } else {
+ generateFile 'PersonPasswordEncoderListener', userModel.packagePath, userModel.simpleName, "${userModel.simpleName}PasswordEncoderListener", 'src/main/groovy'
+ }
+ def beansList = [[import: "import ${userModel.packageName}.${userModel.simpleName}PasswordEncoderListener", definition: "${userModel.propertyName}PasswordEncoderListener(${userModel.simpleName}PasswordEncoderListener)"]]
+ addBeans(beansList, 'grails-app/conf/spring/resources.groovy')
+
+ } else {
+ if ( salt ) {
+ generateFile 'PersonWithSalt', userModel.packagePath, userModel.simpleName
+ } else {
+ generateFile 'Person', userModel.packagePath, userModel.simpleName
+ }
+ }
+
+ generateFile 'Authority', roleModel.packagePath, roleModel.simpleName
+ generateFile 'PersonAuthority', roleModel.packagePath, userModel.simpleName + roleModel.simpleName
+
+ if (requestmapModel) {
+ generateFile 'Requestmap', requestmapModel.packagePath, requestmapModel.simpleName
+ }
+
+ if (groupModel) {
+ generateFile 'AuthorityGroup', groupModel.packagePath, groupModel.simpleName
+ generateFile 'PersonAuthorityGroup', groupModel.packagePath, userModel.simpleName + groupModel.simpleName
+ generateFile 'AuthorityGroupAuthority', groupModel.packagePath, groupModel.simpleName + roleModel.simpleName
+ }
+}
+
+private void updateConfig(String userClassName, String roleClassName, String requestmapClassName, String packageName, boolean useRoleGroups) {
+
+ file('grails-app/conf/application.groovy').withWriterAppend { BufferedWriter writer ->
+ writer.newLine()
+ writer.newLine()
+ writer.writeLine '// Added by the Spring Security Core plugin:'
+ if (!uiOnly) {
+ writer.writeLine "grails.plugin.springsecurity.userLookup.userDomainClassName = '${packageName}.$userClassName'"
+ writer.writeLine "grails.plugin.springsecurity.userLookup.authorityJoinClassName = '${packageName}.$userClassName$roleClassName'"
+ writer.writeLine "grails.plugin.springsecurity.authority.className = '${packageName}.$roleClassName'"
+ }
+ if (useRoleGroups) {
+ writer.writeLine "grails.plugin.springsecurity.authority.groupAuthorityNameField = 'authorities'"
+ writer.writeLine 'grails.plugin.springsecurity.useRoleGroups = true'
+ }
+ if (requestmapClassName) {
+ writer.writeLine "grails.plugin.springsecurity.requestMap.className = '${packageName}.$requestmapClassName'"
+ writer.writeLine "grails.plugin.springsecurity.securityConfigType = 'Requestmap'"
+ }
+ writer.writeLine 'grails.plugin.springsecurity.controllerAnnotations.staticRules = ['
+ writer.writeLine "\t[pattern: '/', access: ['permitAll']],"
+ writer.writeLine "\t[pattern: '/error', access: ['permitAll']],"
+ writer.writeLine "\t[pattern: '/index', access: ['permitAll']],"
+ writer.writeLine "\t[pattern: '/index.gsp', access: ['permitAll']],"
+ writer.writeLine "\t[pattern: '/shutdown', access: ['permitAll']],"
+ writer.writeLine "\t[pattern: '/assets/**', access: ['permitAll']],"
+ writer.writeLine "\t[pattern: '/**/js/**', access: ['permitAll']],"
+ writer.writeLine "\t[pattern: '/**/css/**', access: ['permitAll']],"
+ writer.writeLine "\t[pattern: '/**/images/**', access: ['permitAll']],"
+ writer.writeLine "\t[pattern: '/**/favicon.ico', access: ['permitAll']]"
+ writer.writeLine ']'
+ writer.newLine()
+
+ writer.writeLine 'grails.plugin.springsecurity.filterChain.chainMap = ['
+ writer.writeLine "\t[pattern: '/assets/**', filters: 'none'],"
+ writer.writeLine "\t[pattern: '/**/js/**', filters: 'none'],"
+ writer.writeLine "\t[pattern: '/**/css/**', filters: 'none'],"
+ writer.writeLine "\t[pattern: '/**/images/**', filters: 'none'],"
+ writer.writeLine "\t[pattern: '/**/favicon.ico', filters: 'none'],"
+ writer.writeLine "\t[pattern: '/**', filters: 'JOINED_FILTERS']"
+ writer.writeLine ']'
+ writer.newLine()
+ }
+}
+
+private void generateFile(String templateName, String packagePath, String className, String fileName = null, String folder = 'grails-app/domain') {
+ render template(templateName + '.groovy.template'),
+ file("${folder}/$packagePath/${fileName ?: className}.groovy"),
+ templateAttributes, false
+}
+
+private void addBeans(List