In my grails app I have customized the post authorization workflow by writing a custom auth success handler (in resources.groovy) as shown below.
authenticationSuccessHandler (MyAuthSuccessHandler) {
def conf = SpringSecurityUtils.securityConfig
requestCache = ref('requestCache')
defaultTargetUrl = conf.successHandler.defaultTargetUrl
alwaysUseDefaultTargetUrl = conf.successHandler.alwaysUseDefault
targetUrlParameter = conf.successHandler.targetUrlParameter
useReferer = conf.successHandler.useReferer
redirectStrategy = ref('redirectStrategy')
superAdminUrl = "/admin/processSuperAdminLogin"
adminUrl = "/admin/processAdminLogin"
userUrl = "/admin/processUserLogin"
}
As you can from the last three lines in the closure above, depending on the Role granted to the logging in User I am redirecting her to separate actions within the AdminController where a custom UserSessionBean is created and stored in the session.
It works fine for a regular login case which in my app is like so:
- User comes to the app via either
http://localhost:8080/my-app/ORhttp://localhost:8080/my-app/login/auth - She enters her valid login id and password and proceeds.
- The app internally accesses MyAuthSuccessHandler which redirects to AdminController considering the Role granted to this User.
- The UserSessionBean is created and stored it in the session
- User is taken to the app home page
I have also written a custom MyUserDetailsService by extending GormUserDetailsService which is correctly accessed in the above flow.
PROBLEM SCENARIO:
Consider a user directly accessing a protected resource (in this case the controller is secured with @Secured annotation) within the app.
- User clicks
http://localhost:8080/my-app/inbox/index - App redirects her to
http://localhost:8080/my-app/login/auth - User enters her valid login id and password
- User is taken to
http://localhost:8080/my-app/inbox/index
The MyAuthSuccessHandler is skipped entirely in this process and hence my UserSessionBean is not created leading to errors upon further use in places where the UserSessionBean is accessed.
QUESTIONS:
- In the problem scenario, does the app skip the
MyAuthSuccessHandlerbecause there is a target URL for it to redirect to upon login? - Can we force the process to always pass through
MyAuthSuccessHandlereven with the target URL present? - If the answer to 2 is no, is there an alternative as to how and where the UserSessionBean can still be created?
You can implement a customized eventListener to handle the post-login process, without disrupting the original user requested url.
In config.groovy, insert a config item:
In you resources.groovy, add a bean like this:
And create a eventListener in src/groovy like this:
Done.