【问题标题】:Grails security plugin custom redirectionGrails 安全插件自定义重定向
【发布时间】:2015-06-23 18:36:51
【问题描述】:

我是 Groovy 和 Grails 的新手。我使用 Spring Security 插件使用数据库请求的请求映射开发了一个应用程序。我想要根据角色自定义重定向到主页。

如果用户是 ROLE_ADMIN,他将在视图 adminUser/Homepage.gsp 中重定向到他的主页

如果用户是 ROLE_USER,他将被重定向到他在视图 User/Homepage.gsp 中的主页

我无法根据用户登录获得任何自定义身份验证重定向。

【问题讨论】:

  • 注入springSecurityService会给出一个空指针异常下面是代码和错误信息

标签: grails spring-security


【解决方案1】:
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
    }
}

这是我的工作代码.... 而是注入一个依赖项,我使用 SpringSecurityUtils 获取当前用户角色并将其重定向到所需的页面...... 感谢大家的支持。

@sean3838 感谢您帮助我.....

【讨论】:

    【解决方案2】:

    假设你的 BuildConfig 中有这样一行:

        compile ":spring-security-core:2.0-RC4"
    

    在您的 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)
    

    使用此代码创建的示例管理员用户:

        UserRole.create admin, roleAdmin, true
    

    还有一些像这样在 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()],
    

    其中 LSSRole 是一个枚举,一些代码如下:

            "/" {
                controller = "dispatch"
                action = "index"
            }
    

    在成功登录后将用户转移到的 UrlMappings 中,您可以构建这样的调度程序,以根据用户的角色将用户分派到不同的登录页面:

    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
    }
    

    希望这会有所帮助。

    【讨论】:

    • 请注意,在 DispatcherController 中使用这种方法,不需要对 springSecurityService 进行显式依赖注入,它可以按原样工作。
    • 非常感谢您的回答,这是一种很好的重定向方法.....但我的情况有点不同,您的逻辑无法在我的应用程序中组合......
    【解决方案3】:

    你必须在你的方法之前注入 springSecurityService 。此外,getAuthorities() 应该返回一个列表,因此您必须遍历它(这是因为人们可以拥有多个角色)。

    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
        }
    }
    

    【讨论】:

    • 非常感谢您的帮助 bt 问题仍然存在,它再次返回 null ..... springSecurityService 没有被初始化,它得到一个 nullpointer 异常.....下面是我的错误代码:- [错误消息] 消息:无法在空对象上调用方法 getPrincipal()
    【解决方案4】:

    这就是我的做法。我已经根据您的需要对其进行了修改。如果有帮助,请告诉我。

    在 auth() 方法下的 springsecurities LoginController 中执行以下操作(它将获取用户在单击登录之前所在的页面):

    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]
    }
    

    现在在 src/groovy 中创建一个身份验证成功处理程序:

    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
        }
    }
    

    现在在 conf/spring/resources.groovy 下创建一个 bean,如下所示:

    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')
        }
    }
    

    那么你应该很高兴。让我知道它是否有效。

    【讨论】:

      猜你喜欢
      • 2011-06-07
      • 2013-07-21
      • 2014-11-11
      • 1970-01-01
      • 2016-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-18
      相关资源
      最近更新 更多