Reputation: 462
I am new to Groovy and Grails. I have developed an application using the Spring Security plugin using a database requested request map. I want a custom redirection to the home pages according to the roles.
If the user is ROLE_ADMIN he would be redirected to his home page in views adminUser/Homepage.gsp
If the user is ROLE_USER he would be redirected to his home page in views User/Homepage.gsp
I am not able to get any custom authentication redirection according to the user login.
Upvotes: 3
Views: 1234
Reputation: 462
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import grails.plugin.springsecurity.SpringSecurityUtils
public class MyAuthSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler
{
@Override
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response)
{
def returnUrl = request.getSession().getAttribute('returnUrl')
def roles = SpringSecurityUtils.getPrincipalAuthorities()
for (String role in roles)
{
if (role.equals("ROLE_ADMIN")) {
returnUrl = '/AdminUser/index.gsp'
}
else if (role.equals("ROLE_USER")) {
returnUrl = '/User/index.gsp'
}
else {
returnUrl = '/'
}
}
request.getSession().removeAttribute('returnUrl')
return returnUrl
}
}
Here is my working code.... rather injecting a dependency I used SpringSecurityUtils for getting the current user role and redirecting it to the desired page...... thanks all for your support.
@sean3838 thanks for helping me out.....
Upvotes: 2
Reputation: 2377
Assuming you have a line like this in your BuildConfig:
compile ":spring-security-core:2.0-RC4"
and some code like this in your BootStrap:
def roleAdmin = new Role(authority:LSSRole.ROLE_ADMIN.toString()).save(failOnError: true)
def roleFirm = new Role(authority:LSSRole.ROLE_FIRM.toString()).save(failOnError: true)
def roleLaw = new Role(authority:LSSRole.ROLE_LAWYER.toString()).save(failOnError: true)
def roleFin = new Role(authority:LSSRole.ROLE_FINANCE.toString()).save(failOnError: true)
with a sample admin user created with this code:
UserRole.create admin, roleAdmin, true
and some code like this in Config:
'/dbconsole/**': [LSSRole.ROLE_ADMIN.toString()],
'/secure/**': [LSSRole.ROLE_ADMIN.toString()],
'/payment/**': [LSSRole.ROLE_FIRM.toString()],
'/filing/**': [LSSRole.ROLE_FIRM.toString()],
'/finance/**': [LSSRole.ROLE_FINANCE.toString()],
'/lawyer/**': [LSSRole.ROLE_LAWYER.toString()],
where LSSRole is an enum, and some code like this:
"/" {
controller = "dispatch"
action = "index"
}
in your UrlMappings to divert users to after a successful login, you can build a dispatcher like this to dispatch users to different landing pages based on their roles:
class DispatchController {
def index() {
def controller = 'login'
def action = 'auth'
if (SpringSecurityUtils.ifAllGranted(LSSRole.ROLE_ADMIN.toString())) {
controller = 'secure'
action = 'index'
} else if (SpringSecurityUtils.ifAllGranted(LSSRole.ROLE_FINANCE.toString())) {
controller = 'finance'
action = 'index'
} else if (SpringSecurityUtils.ifAllGranted(LSSRole.ROLE_FIRM.toString())) {
controller = 'filing'
action = 'summary'
} else if (SpringSecurityUtils.ifAllGranted(LSSRole.ROLE_LAWYER.toString())) {
controller = 'lawyer'
action = 'index'
} else {
flash.message = 'Where do you think you\'re going? Nno no no'
SecurityContextHolder.clearContext()
}
redirect controller:controller, action:action
}
Hope this helps.
Upvotes: 0
Reputation: 65
You have to inject springSecurityService before your method. Also, getAuthorities() should return a list so you'll have to loop through it (this is because people can have more than one role).
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
public class MyAuthSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler
{
def springSecurityService
@Override
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response)
{
def returnUrl = request.getSession().getAttribute('returnUrl')
def roles = springSecurityService.getPrincipal().getAuthorities()
for (role in roles)
{
if (role == 'ROLE_ADMIN')
{
returnUrl = '/adminUser/Homepage.gsp'
}
else if (role == 'ROLE_USER')
{
returnUrl = '/User/Homepage.gsp'
}
}
request.getSession().removeAttribute('returnUrl')
return returnUrl
}
}
Upvotes: 0
Reputation: 65
This is how I do it. I've modified it for your needs. Let me know if it helps.
Inside springsecurities LoginController under the auth() method do something like this (it will get the page the user was on before clicking login):
def auth() {
session['returnUrl'] = request.getHeader("Referer")
def config = SpringSecurityUtils.securityConfig
if (springSecurityService.isLoggedIn()) {
redirect uri: config.successHandler.defaultTargetUrl
return
}
String view = 'auth'
String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}"
render view: view, model: [postUrl: postUrl,
rememberMeParameter: config.rememberMe.parameter]
}
Now inside src/groovy create an auth success handler:
package packageName
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
public class MyAuthSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler
{
@Override
protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response)
{
def returnUrl = request.getSession().getAttribute('returnUrl')
// Get current users role using springSecurityService
// You can inject springSecurityService into this class
// http://stackoverflow.com/questions/6467167/how-to-get-current-user-role-with-spring-security-plugin
if (role == 'ROLE_ADMIN')
{
returnUrl = '/adminUser/Homepage.gsp'
}
else if (role == 'ROLE_USER')
{
returnUrl = '/User/Homepage.gsp'
}
else
{
returnUrl = 'redirect somewhere'
}
request.getSession().removeAttribute('returnUrl')
return returnUrl
}
}
Now under conf/spring/resources.groovy create a bean like so:
import grails.plugin.springsecurity.SpringSecurityUtils
// Place your Spring DSL code here
beans = {
authenticationSuccessHandler(packageName.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')
}
}
Then you should be good to go. Let me know if it works.
Upvotes: 1