Cannot Create User Object in grails 2.1.1 using Spring Security - grails

I have the following class
class SentryUser {
transient springSecurityService
String userName
String password
boolean enabled
boolean accountExpired = false
boolean accountLocked = false
boolean passwordExpired = false
static constraints = {
userName blank: false, unique: true
password blank: false
}
static mapping = {
password column: '`password`'
}
Set<SentryRole> getAuthorities() {
SentryUserSentryRole.findAllBySentryUser(this).collect { it.sentryRole } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
I'm calling the following code in bootstrap
def admin = new SentryUser(userName: "sample#sample.com",
enabled: true).save(failOnError: true)
and getting the following error
context.GrailsContextLoader Error executing bootstraps: groovy.lang.MissingMethodException: No signature of method: SentryUser.save() is applicable for argument types: () values: []
I'm on grails 2.1.1 and using the spring security plugin.

You're calling save(Map) but the MME is complaining about save() with no arguments. I've seen this discrepancy before when I didn't have any persistence plugins (hibernate/mongodb) installed in my application - it was a plugin project that I was trying to run as a standalone app and the default BuildConfig for a new plugin project doesn't include a dependency on hibernate.

Related

Grails 3 + Spring Security Core Plugin Confirm Password

Hello today I've started to learn Grails 3 with Spring Security Core Plugin but I'm having hard time with password Validation. When user is registering I want him to type password and confirmPassword. Everything would be ok if not hashing the password. I want my password to be encoded in database but with encoding I'm not able to compare those 2 passwords.
Here is my class:
#EqualsAndHashCode(includes='username')
#ToString(includes='username', includeNames=true, includePackage=false)
class User implements Serializable {
private static final long serialVersionUID = 1
transient springSecurityService
String username
String password
String confirmPass
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
User(String username, String password) {
this()
this.username = username
this.password = password
this.confirmPass = password
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this)*.role
}
// because of that I can't compare password and confirmPass
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}
static transients = ['springSecurityService']
static constraints = {
username blank: false, unique: true
password blank: false, size: 5..60, password: true, display: false, validator: { val, obj ->
if (!obj.id && !obj.password) {
return 'validation.user.password' // my message
}
}
confirmPass blank: // now I'm stuck here, I've tried isPasswordValid() but won't work cuz of 'salt' What shout go here?
}
static mapping = {
password column: '`password`'
}
}
What should I do to make it working(valid both password are same and then encoded password store in database).

Grails Scaffold hide table column

How I can hide password column from GORM view:
My domain class:
class SecUser {
static scaffold = true
transient springSecurityService
String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static transients = ['springSecurityService']
static constraints = {
username blank: false, unique: true
password (display:false, blank: false)
}
static mapping = {
password column: '`password`'
}
Set<SecRole> getAuthorities() {
SecUserSecRole.findAllBySecUser(this).collect { it.secRole } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
// password = password
}
}
The display: false constraint is used to hide the property from the default scaffolded view. The project at https://github.com/jeffbrown/scaffolddisplay demonstrates this. You must have something in your app that is getting in the way of that. Possibly you have generated views which contain the property. Possibly you are using a plugin which is providing the view.

Grails Spring Security Core unable to log in

Installed spring-security-core 2.0-RC2 (with grails 2.3.6), ran the quick start but I'm not able to log in. Each time I try, I get the 'Sorry, we were not able to find a user with that username and password.' error.
Done some research and I'm not double encoding the password or nor am I using salt (from what I can tell). I've used earlier versions in other projects, so not sure what's going on. I've also dropped the encodePassword() from the domain class and verified in the DB that it's what I expect it to be
Here's my User domain class:
class User {
transient springSecurityService
String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static transients = ['springSecurityService']
static constraints = {
username blank: false, unique: true
password blank: false
}
static mapping = {
password column: '`password`'
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
and my Bootstrap:
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = new Role(authority: 'ROLE_USER').save(flush: true)
def testUser = new User(username: 'me', password: 'me')
testUser.save(flush: true)
UserRole.create testUser, adminRole, true
UserRole.create testUser, userRole, true
any idea of what I'm doing wrong?
Thanks!
That looks fine, but funny things can be happening under the hood. I wrote up a couple of blog posts to help diagnose issues like this. Check out http://burtbeckwith.com/blog/?p=2003 and http://burtbeckwith.com/blog/?p=2029

With specified username getting 'Sorry, we were not able to find a user with that username and password.' message when logging int

I have installed the grails Spring-Security plugin:
plugins {
compile ':spring-security-core:2.0-RC2'
}
Then I used the grails s2-quickstart com.jane Person Role command to create the needed domain classes.
As I have my own User class I refactored the code to use my User class:
package com.jane
class User {
transient springSecurityService
String email
String name
String password
Boolean isAgreeTerms = false
Date agreeTermsDt
Boolean isActive = false
Boolean isBlocked = false
Date dateCreated
Integer createdBy = 0
Date lastUpdated
Integer modifiedBy = 0
static transients = [ 'springSecurityService' ]
static hasMany = [ userProductTier: UserProductTier ]
static mapping = {
id column: "userID"
dateCreated column: 'createdDt'
lastUpdated column: 'modifiedDT'
}
static constraints = {
email blank: false, email: true, unique: true, size: 5..100
name blank: false, size: 3..50
password blank: false
}
void beforeInsert() {
if ( isAgreeTerms ) {
agreeTermsDt = new Date()
}
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
I then modified the config.groovy file to:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.jane.User'
grails.plugin.springsecurity.userLookup.usernamePropertyName = 'email'
grails.plugin.springsecurity.userLookup.enabledPropertyName = 'isActive'
grails.plugin.springsecurity.userLookup.accountExpiredPropertyName = 'isBlocked'
grails.plugin.springsecurity.userLookup.accountLockedPropertyName = 'isBlocked'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'com.jane.UserRole'
grails.plugin.springsecurity.authority.className = 'com.jane.Role'
I can create users fine, verify they are in the database, have verified that encodePassword is called once. But every time I try to login I get the following error:
Sorry, we were not able to find a user with that username and
password.
And here is the service method to create users:
User createTeamLeader( String name, String email, String password, Boolean isAgreeTerms, Integer productTierId ) {
User user = new User( name: name, email: email, password: password, isAgreeTerms: isAgreeTerms, isActive: true)
UserProductTier userProductTier = new UserProductTier( productTierId: productTierId )
user.addToUserProductTier( userProductTier )
user.save()
UserRole.create( user, Role.findByAuthority('ROLE_USER'), true )
UserRole.create( user, Role.findByAuthority('ROLE_LEAD'), true )
user
}
Often adding debug logging helps, since Spring Security logs a lot at the debug level:
log4j = {
...
debug 'org.springframework.security'
}
In this case it didn't show the problem, so I added an event listener to see if there was information in the failure event:
grails.plugin.springsecurity.useSecurityEventListener = true
grails.plugin.springsecurity.onAbstractAuthenticationFailureEvent = { e, appCtx ->
println "\nERROR auth failed for user $e.authentication.name: $e.exception.message\n"
}
That displayed this:
ERROR auth failed for user ernie#ss.com: No such property: authorities for class: com.jane.User
When you made changes in the class, you removed the getAuthorities method that was in the original version, and is used by the UserDetailsService to determine granted roles during authentication. Adding it back got things working:
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}

Grails : Error initializing spring security on server restart

I have a very strange behaviour on a production server.
When I start for the first time my server, there is no problem, but when I want to stop and restart it, I get the following error :
Configuring Spring Security Core ...
... finished configuring Spring Security Core
2013-10-31 12:03:08,156 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: null
java.lang.NullPointerException
at com.aftmevent.security.UserRole.create(UserRole.groovy:32)
at BootStrap$_closure1.doCall(BootStrap.groovy:16)
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:308)
at grails.util.Environment.executeForEnvironment(Environment.java:301)
at grails.util.Environment.executeForCurrentEnvironment(Environment.java:277)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
2013-10-31 12:03:08,156 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing Grails: null
java.lang.NullPointerException
at com.aftmevent.security.UserRole.create(UserRole.groovy:32)
at BootStrap$_closure1.doCall(BootStrap.groovy:16)
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:308)
at grails.util.Environment.executeForEnvironment(Environment.java:301)
at grails.util.Environment.executeForCurrentEnvironment(Environment.java:277)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
oct. 31, 2013 12:03:08 PM org.apache.catalina.core.StandardContext startInternal
Here is my BootStrap.groovy :
class BootStrap {
def springSecurityService
def init = { servletContext ->
def existingAdminRole = Role.findByAuthority('ROLE_ADMIN')
def existingUserRole = null
def existingAdminUser = null
if (existingAdminRole) {
existingUserRole = UserRole.findByRole(existingAdminRole)
}
if (existingUserRole) {
existingAdminUser = existingUserRole.user
}
if (!existingAdminUser) {
def adminRole = new Role(authority: 'ROLE_ADMIN')
def adminUser = new User(username: 'admin', password: 'admin', enabled: true)
if (adminRole.validate()) {
adminRole.save(flush: true, failOnError: true)
}
if (adminUser.validate()) {
adminUser.save(flush: true, failOnError: true)
}
UserRole userRole = UserRole.create(adminUser, adminRole, true)
if (userRole.validate()) {
userRole.save(flush: true, failOnError: true)
}
}
}
def destroy = {
}
}
Here is my User.groovy (adding the nullable constraint did not solve the problem) :
User.groovy :
class User {
transient springSecurityService
String username
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static constraints = {
username nullable: true, blank: false, unique: true
password nullable: true, blank: false
}
static mapping = {
password column: '`password`'
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this).collect { it.role } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
Here are my classe Role.groovy and UserRole.groovy :
Role.groovy :
class Role {
String authority
static mapping = {
cache true
}
static constraints = {
authority nullable: true, blank: false, unique: true
}
}
UserRole.groovy :
class UserRole implements Serializable {
User user
Role role
boolean equals(other) {
if (!(other instanceof UserRole)) {
return false
}
other.user?.id == user?.id &&
other.role?.id == role?.id
}
int hashCode() {
def builder = new HashCodeBuilder()
if (user) builder.append(user.id)
if (role) builder.append(role.id)
builder.toHashCode()
}
static UserRole get(long userId, long roleId) {
find 'from UserRole where user.id=:userId and role.id=:roleId',
[userId: userId, roleId: roleId]
}
static UserRole create(User user, Role role, boolean flush = false) {
new UserRole(user: user, role: role).save(flush: flush, insert: true)
}
static boolean remove(User user, Role role, boolean flush = false) {
UserRole instance = UserRole.findByUserAndRole(user, role)
if (!instance) {
return false
}
instance.delete(flush: flush)
true
}
static void removeAll(User user) {
executeUpdate 'DELETE FROM UserRole WHERE user=:user', [user: user]
}
static void removeAll(Role role) {
executeUpdate 'DELETE FROM UserRole WHERE role=:role', [role: role]
}
static mapping = {
id composite: ['role', 'user']
version false
}
}
Here is my DataSource.groovy file with the database settings :
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
driverClassName = 'com.mysql.jdbc.Driver'
username = 'root'
password = 'root'
url = 'jdbc:mysql://localhost:3306/database?autoreconnect=true&useUnicode=true&characterEncoding=utf-8'
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
}
}
production {
dataSource {
dbCreate = 'create-drop'
driverClassName = 'com.mysql.jdbc.Driver'
username = 'root'
password = 'root'
url = 'jdbc:mysql://localhost:3306/database?autoreconnect=true&useUnicode=true&characterEncoding=utf-8'
}
}
}
I really don't have any idea about what occured.
I have added the nullable constrainst, trying to put the databe into 'create-drop' / 'update'.
Funny thing : When I drop the databse then create it again, the first server start is good, but crash after a restart.
I try to put println logs into my BootStrap.groovy, I can see them into development environment, but not into production server.
So I'm not sure if my BootStrap is updated creating war.
I create the war using :
grails prod war target/my-new-war-0.0.x.war
Thanks for reading,
Snite
I'm not really sure what's wrong with your code, however your giant block of code was making my head hurt so I had to post this.
Role role = Role.findByAuthority("ROLE_ADMIN") ?: new Role(authority: "ROLE_ADMIN").save(flush: true, failOnError: true)
if (UserRole.countByRole(role) == 0) {
User user = new User(username: 'admin', password: 'admin', enabled: true).save(flush: true, failOnError: true)
UserRole.create(user, role, true)
}
hmmm well its a null point exception:
ERROR context.GrailsContextLoader - Error initializing the application: null
java.lang.NullPointerException
at com.aftmevent.security.UserRole.create(UserRole.groovy:32)
at BootStrap$_closure1.doCall(BootStrap.groovy:16)
Unsure if the pasted content matches up exactly to your own line numbers, something you could try for now is by going around and adding the question mark :
def existingAdminRole = Role.findByAuthority('ROLE_ADMIN')
def existingUserRole = null
def existingAdminUser = null
if (existingAdminRole) {
existingUserRole = UserRole.findByRole(existingAdminRole)
}
if (existingUserRole) {
existingAdminUser = existingUserRole.user
}
change to:
def existingAdminRole = Role?.findByAuthority('ROLE_ADMIN')
def existingUserRole = null
def existingAdminUser = null
if (existingAdminRole) {
existingUserRole = UserRole?.findByRole(existingAdminRole)
}
if (existingUserRole) {
existingAdminUser = existingUserRole?.user
}
Also you could try findorsavewhere rather than an attempt to generate a new record:
https://github.com/vahidhedayati/ajaxdependancyselectexample/blob/master/grails-app/conf/BootStrap.groovy
def n1=MyContinent.findOrSaveWhere(continentName: 'Asia')
def n2=MyContinent.findOrSaveWhere(continentName: 'Europe')
// Create countries and provde continent map value as above defs
def c1 = MyCountry.findOrSaveWhere(mycontinent: n2, countryName:'United Kingdom',ccode:'GB',language:'')
def c2 = MyCountry.findOrSaveWhere(mycontinent: n2, countryName:'France',ccode:'FR',language:'')
def c3 = MyCountry.findOrSaveWhere(mycontinent: n1, countryName:'China',ccode:'CN',language:'')
def c4 = MyCountry.findOrSaveWhere(mycontinent: n1, countryName:'India',ccode:'IN',language:'')
you will need to figure out what is going on in line 32 of UserRole which will be the start of your issue followed by BootStrap on line 16..
Thanks for all of your answer which help me to solve my issue.
It was stupid but in my rundeck script to deploy the war on the production server, it was an out of date version of the war which was used -_-
So doint it manually with the correct war version solve my problem.
Thanks because your advices help me to read adequat documentation on grails's framework and help me thinking looking here.
Cheers,
Snite

Resources