Developer's Diary
Software development, with Terry Ebdon
|
Yesterday I added spring-security-core:4.0.0 to my Grails app. I hit a couple of problems:
The logout issue is probably something silly that I've done. Not a big deal, this is just demo-ware and I don't need to demo log outs. When I get a minute I'll create a test project to see what I've screwed up.
The user roles problem is weird. Grails created three persistent classes: User, Role and UserRole. I then reversed my previous User implementation into the new class.
I've protected the app with a static rule, in grails-app/conf/application.groovy
:
That works great, you now have to login to do anything. I'll be using role based authorisation, so need to create create Role
instances, in sample data, and assign users to those roles.
I use a helper function to create adult users. This forces the date of birth to be 1-JAN-1970, generates a unique email address, sets the password to 'fred' and returns the saved User instance.
This is where things go horribly wrong.
.save()
shouldn't be required. See below.UserRole.create()
creates a non-persistent object. Fair enough. But calling the object's save()
method doesn't work, i.e. the object's id
property is null after .save( failOnError: true )
. This snippet reveals the problem:
The UserRole's id is null in the terminal log.
I then check the UserRole mapping with this code:
where printRoles
is defined as:
The terminal log confirms that no user roles have been assigned.
The log is consistent with the UserRole instances not being saved. But why don't I see the .save()
failing, due to the failOnError: true
argument? It doesn't add up. I did some digging into Spring Security Core reference documentation. This shows the User
class implementing an authorities
property. Sure enough, it's defined in my User
class. OK, let's add that to the mix:
Running with this just confirms what I already know; the UserRole
objects aren't being saved.
I looked at the sample code for the book Grails in Action, 2nd ed. The only significant difference is that it doesn't call .save()
on the created UserRole
. So that work-around shouldn't be required. A peek at the generated UserRole.create()
method confirms this.
Interesting that it explicitly returns the instance, doesn't .save()
return the UserRole? I changed UserRole.create()
to pass failOnError: true
and removed the explicit saves from my bootstrap class. That made no difference. I need to recreate the problem in a throw-away project. Hopefully the throw-away will work, then I can diff the projects to find the error.
11-JUN-2020 👈 Top of page 👉 13-JUN-2020
© 2020 Terry Ebdon.
Find me coding on GitHub, networking on LinkedIn, answering questions on Stack Exchange and hanging out on twitter.