Grails 7, Removing user still has access.
Expected Behavior
I stop the app and remove Admin user from BootStrap, i expect Admin user has no access any more.
Actual Behaviour
Even Admin user does exist anymore. I can verify that from H2-DB and in grails-spring-security-ui:7.0.0-RC2 console. Admin user still has access to the app.
You can go page to page no problem. You are still Amin. Even admin user doesn't exist.
Steps To Reproduce
- create an app with 'grails-spring-security:7.0.0-RC2' or 'grails-spring-security-ui:7.0.0-RC2'.
- add Admin user and role from BootStrap.groovy
- Create an GSP page with tags sec:username/ or <sec:loggedInUserInfo field='username'/>
- start the app.
- login with Remember Me checked.
- All work correctly
- Don't close browser
- turn OFF the app
- remove Admin from BootStrap.groovy
- Start app
- go back to browser
- Shift-Reload browser,
- tags sec:username/ or <sec:loggedInUserInfo field='username'/> still think you are login as Admin
You can go page to page no problem. You are still Amin. Even admin user doesn't exist.
Environment Information
java=21.0.8-zulu gradle=8.14.3 groovy=4.0.28 grails=7.0.0-RC2
Example Application
https://github.com/arjangch/grails-project-helper/tree/main/example3
Version
7.0.0-RC2
Is this related to https://github.com/apache/grails-spring-security/issues/1183 ?
To clarify:
The app is fully stopped and restarted and the admin user, which was present in the db, is no longer in the db?
Double check in different laptop. Using FF browser. Using the same Example3 app in my github.
- Create Admin user and role from BootStrap
- grails run-app
- Check h2-db console. Admin is there.
SELECT * FROM "user" - login as admin / admin
- Check tags sec:ifNotLoggedIn and sec:username/ and <sec:loggedInUserInfo field='username'/> are all working fine. Click around Admin should have access to everything.
- Don't close tab.
- Don't logout
- stop the app ctrl-c in command line
- comment out admin user in BootStrap
- grails run-app
- Check h2-db console. You are kicked out you need to login again to h2-db console
SELECT * FROM "user"admin user is not there any more- go back to browser
- Shift-reload the page
- Admin user still showing in sec:ifNotLoggedIn and sec:username/
- in testSpringTags.gsp page <sec:loggedInUserInfo field='username'/> is showing admin user
- click around. Everything working fine.
- click on Logout button
- you are logged out
- try to login with admin / admin
- you are not able to login because admin user doesn't exist.
It behaves like it is cached in cookie in browser. Does Remember Me has anything to do with this?
Just for fun of it. Clean server between restart made no difference.
8.1. gradle clean
8.2. grails clean
8.3. rm -rf build
@arjangch Could you try running the app without Spring Boot Devtools?
Steps 1-12 above the same result
Step 8. stop the app ctrl-c in command line
Comment out org.springframework.boot:spring-boot-devtools in gradle.groovy
Step 10. grails run-app
Step 11. db-console got kicked out
Tag <sec:loggedInUserInfo field='username'/> doesn't show any username
Main page asking me to login
It seems that is working as it should if i comment out boot:spring-boot-devtools.
This sounds like its expected behavior of including devtools. This doesn't seem like a bug. @arjangch you would agree?
Correct, it is not a bug. However, does devtools need to be included in default grails project (out of the box). Or should grails-spring-security doc say remove devtools? I am sure other people (like me) don't pay attention.
Until we have another open source reloading tool, I'd say Spring Boot Dev tools should be included by default in generated applications, as it has since Grails 4. There is already a comment on it around large applications, and we could add this detail to that comment.
We will need to update documentation for Grails Spring Security.
The reason why spring-boot-devtools is changing behavior is because it is setting server.servlet.session.persistent=true. I did some testing on this and found that Spring Boot / Spring Security (no Grails) will show this same behavior when server.servlet.session.persistent=true (which is false by default).