Skip to content

Commit

Permalink
Merge pull request #397 from alvarosanchez/grails4upgrade
Browse files Browse the repository at this point in the history
fix for Grails 4 / Spring Security 5 based Spring-Security-Core plugin
  • Loading branch information
alvarosanchez committed May 10, 2019
2 parents ffa848c + d18ffef commit 68c3a6d
Show file tree
Hide file tree
Showing 14 changed files with 106 additions and 39 deletions.
21 changes: 13 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ buildscript {
}
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1"
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4'
classpath "io.spring.gradle:dependency-management-plugin:0.6.1.RELEASE"
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:latest.release"
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
//classpath "io.spring.gradle:dependency-management-plugin:0.6.1.RELEASE"
}
}

Expand Down Expand Up @@ -45,13 +45,17 @@ subprojects { Project project ->
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}

if (project.name in pluginProjects) {
if (project.name != "spring-security-rest-docs" &&
project.name != "spring-security-rest-testapp-profile" &&
!project.name.startsWith("build") ) {
apply plugin: "org.grails.grails-plugin"
apply plugin: "org.grails.grails-plugin-publish"
apply plugin: "com.jfrog.artifactory"
}

if (project.name in pluginProjects) {

sourceCompatibility = targetCompatibility = 1.7
sourceCompatibility = targetCompatibility = 1.8

dependencies {
console "org.grails:grails-console"
Expand All @@ -64,7 +68,7 @@ subprojects { Project project ->
provided "org.grails:grails-plugin-domain-class"

testCompile "org.grails:grails-gorm-testing-support"
testCompile "org.grails:grails-plugin-testing"
//testCompile "org.grails:grails-plugin-testing"
testCompile "org.grails:grails-web-testing-support"
testCompile('com.athaydes:spock-reports:1.2.13') {
transitive = false
Expand All @@ -90,7 +94,8 @@ subprojects { Project project ->
apply plugin: "org.grails.grails-profile-publish"
}

if (project.name in publishedProjects) {
if (project.name in publishedProjects && project.name != "spring-security-rest-docs" &&
project.name != "spring-security-rest-testapp-profile") {
grailsPublish {
user = bintrayUser
key = bintrayKey
Expand Down
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
grailsVersion=3.3.2
springSecurityCoreVersion=3.2.2
gradleWrapperVersion=3.5
grailsVersion=4.0.0.RC1
springSecurityCoreVersion=4.0.0.M2
gradleWrapperVersion=4.9
bintrayUser=alvarosanchez
pluginPortalUser=alvaro.sanchez
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
3 changes: 2 additions & 1 deletion spring-security-rest-testapp-profile/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ buildscript {

repositories {
mavenLocal()
jcenter()
maven { url "https://repo.grails.org/grails/core" }
}

dependencies {
runtime "org.grails.profiles:web:${grailsVersion}"
runtime "org.grails.profiles:web:4.0.0.RC1"
}

task installKeys << {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
description: First configuration of GORM
dependencies:
build:
- "org.grails.plugins:hibernate5:6.1.8"
- "org.grails.plugins:hibernate5:7.0.0.RC2"
compile:
- "org.grails.plugins:hibernate5"
- "org.hibernate:hibernate-core:5.1.5.Final"
- "org.hibernate:hibernate-ehcache:5.1.5.Final"
- "org.hibernate:hibernate-ehcache"
- "org.grails.plugins:hibernate5:7.0.0.RC2"
- "org.hibernate:hibernate-core:5.4.0.Final"
- "org.hibernate:hibernate-ehcache:5.4.0.Final"
- "org.grails.plugins:spring-security-rest-gorm:${pluginVersion}"
runtime:
- "com.h2database:h2"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
description: Second configuration of GORM
dependencies:
build:
- "org.grails.plugins:hibernate5:6.1.8"
- "org.grails.plugins:hibernate5:7.0.0.RC2"
compile:
- "org.grails.plugins:hibernate5"
- "org.hibernate:hibernate-core:5.1.5.Final"
- "org.hibernate:hibernate-ehcache:5.1.5.Final"
- "org.hibernate:hibernate-ehcache"
- "org.grails.plugins:hibernate5:7.0.0.RC2"
- "org.hibernate:hibernate-core:5.4.0.Final"
- "org.hibernate:hibernate-ehcache:5.4.0.Final"
- "org.grails.plugins:spring-security-rest-gorm:${pluginVersion}"
runtime:
- "com.h2database:h2"
Expand Down
4 changes: 2 additions & 2 deletions spring-security-rest-testapp-profile/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
grailsVersion=3.3.2
gradleWrapperVersion=3.5
grailsVersion=4.0.0.RC1
gradleWrapperVersion=4.9
6 changes: 4 additions & 2 deletions spring-security-rest-testapp-profile/profile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ build:
- org.grails.grails-core
dependencies:
compile:
- "org.grails.plugins:spring-security-rest:2.0.0.RC1"
- "org.grails:grails-datastore-rest-client"
- "org.grails.plugins:spring-security-rest:2.0.0.BUILD-SNAPSHOT"
- "org.springframework.security:spring-security-core:5.1.2.RELEASE"

testCompile:
- "org.grails:grails-datastore-rest-client:6.1.12"
- "org.grails.plugins:geb"
- "com.codeborne:phantomjsdriver:1.2.1"
- "org.seleniumhq.selenium:selenium-api:2.47.1"
Expand Down
4 changes: 3 additions & 1 deletion spring-security-rest-testapp-profile/profile.yml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ build:
dependencies:
compile:
- "org.grails.plugins:spring-security-rest:${pluginVersion}"
- "org.grails:grails-datastore-rest-client"
- "org.springframework.security:spring-security-core:5.1.2.RELEASE"

testCompile:
- "org.grails:grails-datastore-rest-client:6.1.12"
- "org.grails.plugins:geb"
- "com.codeborne:phantomjsdriver:1.2.1"
- "org.seleniumhq.selenium:selenium-api:2.47.1"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder
import org.springframework.security.provisioning.InMemoryUserDetailsManager

// Place your Spring DSL code here
beans = {

userDetailsService(InMemoryUserDetailsManager, [])

passwordEncoder(PlaintextPasswordEncoder)
//passwordEncoder(PlaintextPasswordEncoder)


}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ class BootStrap {
InMemoryUserDetailsManager userDetailsService

def init = { servletContext ->
UserDetails jimi = new User('jimi', 'jimispassword', [new SimpleGrantedAuthority('ROLE_USER'), new SimpleGrantedAuthority('ROLE_ADMIN')])
UserDetails jimi = new User('jimi', '{noop}jimispassword', [new SimpleGrantedAuthority('ROLE_USER'), new SimpleGrantedAuthority('ROLE_ADMIN')])
userDetailsService.createUser(jimi)

UserDetails alvaro = new User('115537660854424164575', 'N/A', [new SimpleGrantedAuthority('ROLE_USER'), new SimpleGrantedAuthority('ROLE_ADMIN')])
UserDetails alvaro = new User('115537660854424164575', '{noop}N/A', [new SimpleGrantedAuthority('ROLE_USER'), new SimpleGrantedAuthority('ROLE_ADMIN')])
userDetailsService.createUser(alvaro)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class JwtSpec extends AbstractRestSpec {
@Issue("https://github.com/alvarosanchez/grails-spring-security-rest/pull/344")
void "if the user no longer exists, token can't be refreshed"() {
given:
userDetailsManager.createUser(new User('foo', 'password', []))
userDetailsManager.createUser(new User('foo', '{noop}password', []))
RestResponse authResponse = sendCorrectCredentials('foo', 'password') as RestResponse
String refreshToken = authResponse.json.refresh_token
userDetailsManager.deleteUser('foo')
Expand All @@ -198,7 +198,7 @@ class JwtSpec extends AbstractRestSpec {
@Unroll
void "if the user is #status, token can't be refreshed"(User updatedUser, String status) {
given:
userDetailsManager.createUser(new User('foo', 'password', []))
userDetailsManager.createUser(new User('foo', '{noop}password', []))
RestResponse authResponse = sendCorrectCredentials('foo', 'password') as RestResponse
String refreshToken = authResponse.json.refresh_token
userDetailsManager.updateUser(updatedUser)
Expand All @@ -217,10 +217,10 @@ class JwtSpec extends AbstractRestSpec {

where:
updatedUser | status
new User('foo', 'password', false, true, true, true, []) | "disabled"
new User('foo', 'password', true, false, true, true, []) | "expired"
new User('foo', 'password', true, true, false, true, []) | "credentials expired"
new User('foo', 'password', true, true, true, false, []) | "locked"
new User('foo', '{noop}password', false, true, true, true, []) | "disabled"
new User('foo', '{noop}password', true, false, true, true, []) | "expired"
new User('foo', '{noop}password', true, true, false, true, []) | "credentials expired"
new User('foo', '{noop}password', true, true, true, false, []) | "locked"
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package grails.plugin.springsecurity.rest
import com.nimbusds.jose.EncryptionMethod
import com.nimbusds.jose.JWEAlgorithm
import com.nimbusds.jose.JWSAlgorithm
import grails.core.GrailsApplication
import grails.plugin.springsecurity.BeanTypeResolver
import grails.plugin.springsecurity.SecurityFilterPosition
import grails.plugin.springsecurity.SpringSecurityUtils
import grails.plugin.springsecurity.rest.authentication.DefaultRestAuthenticationEventPublisher
Expand All @@ -45,6 +47,16 @@ import grails.plugin.springsecurity.rest.token.rendering.DefaultAccessTokenJsonR
import grails.plugin.springsecurity.rest.token.storage.jwt.JwtTokenStorageService
import grails.plugins.Plugin
import groovy.util.logging.Slf4j
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.security.crypto.password.DelegatingPasswordEncoder
import org.springframework.security.crypto.password.LdapShaPasswordEncoder
import org.springframework.security.crypto.password.Md4PasswordEncoder
import org.springframework.security.crypto.password.MessageDigestPasswordEncoder
import org.springframework.security.crypto.password.NoOpPasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder
import org.springframework.security.crypto.password.StandardPasswordEncoder
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder
import org.springframework.security.web.access.AccessDeniedHandlerImpl
import org.springframework.security.web.access.ExceptionTranslationFilter
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint
Expand All @@ -54,7 +66,7 @@ import org.springframework.security.web.savedrequest.NullRequestCache
class SpringSecurityRestGrailsPlugin extends Plugin {

// the version or versions of Grails the plugin is designed for
String grailsVersion = "3.1.0 > *"
String grailsVersion = "4.0.0 > *"
List loadAfter = ['springSecurityCore']
List pluginExcludes = [
"grails-app/views/**"
Expand All @@ -76,6 +88,7 @@ class SpringSecurityRestGrailsPlugin extends Plugin {

def issueManagement = [ system: "GitHub", url: "https://github.com/alvarosanchez/grails-spring-security-rest/issues" ]
def scm = [ url: "https://github.com/alvarosanchez/grails-spring-security-rest" ]
GrailsApplication grailsApplication

Closure doWithSpring() { {->
def conf = SpringSecurityUtils.securityConfig
Expand Down Expand Up @@ -270,9 +283,16 @@ class SpringSecurityRestGrailsPlugin extends Plugin {
authenticationEventPublisher(NullRestAuthenticationEventPublisher)
}

String algorithm = conf.password.algorithm
Class beanTypeResolverClass = conf.beanTypeResolverClass ?: BeanTypeResolver
def beanTypeResolver = beanTypeResolverClass.newInstance(conf, grailsApplication)

passwordEncoder(beanTypeResolver.resolveType('passwordEncoder', DelegatingPasswordEncoder), algorithm, idToPasswordEncoder(conf))

if (printStatusMessages) {
println '... finished configuring Spring Security REST\n'
}

}}

@Override
Expand Down Expand Up @@ -300,4 +320,43 @@ class SpringSecurityRestGrailsPlugin extends Plugin {
}
}


Map<String, PasswordEncoder> idToPasswordEncoder(ConfigObject conf) {

final String ENCODING_ID_BCRYPT = "bcrypt"
final String ENCODING_ID_LDAP = "ldap"
final String ENCODING_ID_MD4 = "MD4"
final String ENCODING_ID_MD5 = "MD5"
final String ENCODING_ID_NOOP = "noop"
final String ENCODING_ID_PBKDF2 = "pbkdf2"
final String ENCODING_ID_SCRYPT = "scrypt"
final String ENCODING_ID_SHA1 = "SHA-1"
final String ENCODING_IDSHA256 = "SHA-256"

MessageDigestPasswordEncoder messageDigestPasswordEncoderMD5 = new MessageDigestPasswordEncoder(ENCODING_ID_MD5)
messageDigestPasswordEncoderMD5.encodeHashAsBase64 = conf.password.encodeHashAsBase64 // false
messageDigestPasswordEncoderMD5.iterations = conf.password.hash.iterations // 10000

MessageDigestPasswordEncoder messsageDigestPasswordEncoderSHA1 = new MessageDigestPasswordEncoder(ENCODING_ID_SHA1)
messsageDigestPasswordEncoderSHA1.encodeHashAsBase64 = conf.password.encodeHashAsBase64 // false
messsageDigestPasswordEncoderSHA1.iterations = conf.password.hash.iterations // 10000

MessageDigestPasswordEncoder messsageDigestPasswordEncoderSHA256 = new MessageDigestPasswordEncoder(ENCODING_IDSHA256)
messsageDigestPasswordEncoderSHA256.encodeHashAsBase64 = conf.password.encodeHashAsBase64 // false
messsageDigestPasswordEncoderSHA256.iterations = conf.password.hash.iterations // 10000

int strength = conf.password.bcrypt.logrounds
[(ENCODING_ID_BCRYPT): new BCryptPasswordEncoder(strength),
(ENCODING_ID_LDAP): new LdapShaPasswordEncoder(),
(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_SHA1): messsageDigestPasswordEncoderSHA1,
(ENCODING_IDSHA256): messsageDigestPasswordEncoderSHA256,
"sha256": new StandardPasswordEncoder()]
}


}

0 comments on commit 68c3a6d

Please sign in to comment.