Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix for Grails 4 / Spring Security 5 based Spring-Security-Core plugin #397

Merged
merged 6 commits into from
May 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()]
}


}