【问题标题】:Grails spring Security UIGrails Spring 安全用户界面
【发布时间】:2011-12-18 19:11:14
【问题描述】:

我是 Grails 的新手,我正在尝试构建一个简单的帮助台应用程序。我希望能够注册一个新用户,登录,发布请求/事件,将其保存到数据库中,并且从管理员方面我希望能够查看表中的所有请求/事件,并更改用户的权限。 对于安全部分(和安全管理),我正在考虑使用 Spring security 和 Spring security UI 插件。 现在我已经创建了应用程序,安装了 spring security 和它的 UI 扩展,添加了真实姓名、电子邮件和公司属性。当我运行应用程序时,我设法成功注册,当我通过电子邮件确认注册时,我会自动登录,但是当我尝试使用其他浏览器登录时,我收到以下错误:

“抱歉,我们无法找到具有该用户名和密码的用户”

但是数据库里有一个。

另外,我想拥有一个事件域类,我将在其中保存所有事件/请求数据。 User 和 Incident 域类之间的关系将是一对多的。我是像其他任何关系一样实现它,还是因为 User 是由 Spring Security 实现的,所以我必须做一些特别的事情? 我愿意接受任何建议。

【问题讨论】:

    标签: grails spring-security


    【解决方案1】:

    最新的 spring-security-core 和 spring-security-ui 0.1.2 不兼容。特别是,spring-security-core 将密码编码移动到 User 类中的 beforeInsert/beforeUpdate 事件处理程序中。 RegisterController.register spring-security-ui 中的控制器还不知道这一点,并尝试再次对其进行编码,从而产生双重编码的密码。要解决此问题,请覆盖 RegisterController 并将 register 操作更改为:

    def register = { RegisterCommand command ->
    
        if (command.hasErrors()) {
            render view: 'index', model: [command: command]
            return
        }
    
        def user = lookupUserClass().newInstance(email: command.email, username: command.username,
                                                 password: command.password, accountLocked: true, enabled: true)
        if (!user.validate() || !user.save()) {
            // TODO
        }
    
        def registrationCode = new RegistrationCode(username: user.username).save()
        String url = generateLink('verifyRegistration', [t: registrationCode.token])
    
        def conf = SpringSecurityUtils.securityConfig
        def body = conf.ui.register.emailBody
        if (body.contains('$')) {
            body = evaluate(body, [user: user, url: url])
        }
        mailService.sendMail {
            to command.email
            from conf.ui.register.emailFrom
            subject conf.ui.register.emailSubject
            html body.toString()
        }
    
        render view: 'index', model: [emailSent: true]
    }
    

    http://jira.grails.org/browse/GPSPRINGSECURITYUI-27 正在跟踪此问题。

    关于您的第二个问题,您可以像对待任何其他域对象一样对待您的 User 类。

    【讨论】:

    • 可以通过在 Config.groovy 中添加 grails.plugins.springsecurity.ui.encodePassword = false 行来防止双重编码
    【解决方案2】:

    当您使用 s2-quickstart 脚本将 Spring Security 添加到您的 grails 项目时,会自动创建用户和角色的域类。这些是普通的域类,因此您可以将任何您想要的(例如事件列表)添加到用户类。

    要在运行时获取当前登录的用户域对象,请使用

    springSecurityService.currentUser

    【讨论】:

      【解决方案3】:

      此问题已在“org.grails.plugins:spring-security-ui:1.0-RC3”中修复。 spring-security-ui 默认不对密码进行编码。

      以下是 grails spring Security UI 文档中的描述及其对问题的解决方案。搜索标题为“密码哈希”的部分

      http://grails-plugins.github.io/grails-spring-security-ui/v1/guide/customization.html

      “在最新版本的 Spring Security Core 插件中,“User”域类是gene该选项默认由s2-quickstart脚本用代码自动散列密码进行虚假验证。这使得代码更简单(例如在控制器中您在哪里创建用户或更新用户密码)但较旧的生成类没有此生成的代码。这对于像这样的插件来说是一个问题,因为无法可靠地确定域类是否对密码进行哈希处理,或者您是否使用较旧的显式调用springSecurityService.encodePassword()的方法。

      将执行密码散列的较新域类与调用 springSecurityService.encodePassword() 的控制器混合的不幸后果是密码被双重散列,并且用户无法登录。所以为了解决这个问题,你可以设置一个配置选项来告诉这个插件的控制器是否散列:grails.plugin.springsecurity.ui.encodePassword。

      此选项默认为 false,因此如果您有一个不处理散列的旧域类,只需启用此插件的散列:

      grails.plugin.springsecurity.ui.encodePassword = true"

      【讨论】:

        猜你喜欢
        • 2012-03-14
        • 1970-01-01
        • 2020-07-01
        • 2014-02-15
        • 2012-02-14
        • 1970-01-01
        • 1970-01-01
        • 2015-09-04
        • 2012-09-30
        相关资源
        最近更新 更多