【问题标题】:Grails Spring Security authentication from a service来自服务的 Grails Spring Security 身份验证
【发布时间】:2014-01-08 06:35:16
【问题描述】:

由于我一直在我的 Grails 应用程序中使用专用服务以使身份验证与 vaadin UI 一起工作,因此我在验证登录时遇到了问题:

1) 在 bootstrap 中创建一个新用户并记录到 db (postgre)

User.withTransaction {
   User test = new User(
      username: "test",
      password: springSecurityService.encodePassword("password"),
      enabled: true,
      accountExpired: false,
      accountLocked: false,
      passwordExpired: false
   ).save()

Role dashManager = new Role(authority: "ROLE_USER").save()

new UserRole(user: test, role: dashManager).save()

2) vaadin ui 正常调用 grails 服务

boolean login(String username, String password) {
   try {
      println username + "----" + password
      security.signIn(username, password)
      return true
   } catch (SecurityServiceException e) {
      Notification.show("Login/Password incorrect", Notification.TYPE_ERROR_MESSAGE);
      return false
   }
}

3) 我的 securityService 总是返回无效

import grails.transaction.Transactional
import org.springframework.security.core.context.SecurityContextHolder as SCH
import org.springframework.security.authentication.BadCredentialsException
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken

@Transactional
class SecurityService {

    def springSecurityService
    def authenticationManager

    void signIn(String username, String password) {
        try {
            def authentication = new UsernamePasswordAuthenticationToken(username, password)
            SCH.context.authentication = authenticationManager.authenticate(authentication)
        } catch (BadCredentialsException e) {
            throw new SecurityException("Invalid username/password")
        }
    }

    void signOut() {
        SCH.context.authentication = null
    }

    boolean isSignedIn() {
        return springSecurityService.isLoggedIn()
    }
}

【问题讨论】:

    标签: grails spring-security grails-orm


    【解决方案1】:

    您可能正在对密码进行双重编码。该插件的最新版本会生成一个用户/个人域类来为您编码密码,因此您无需调用springSecurityService.encodePassword("password"),如果您这样做,则它会被编码两次。这应该有效:

    User test = new User(
       username: "test",
       password: "password",
       enabled: true
    ).save()
    

    我省略了将accountExpiredaccountLockedpasswordExpired 设置为false,因为这些是默认值。

    【讨论】:

      【解决方案2】:

      使用springSecurityService进行身份验证

       void signIn(String username, String password) {
              try {
                  springSecurityService.reauthenticate(username, password)
              } catch (BadCredentialsException e) {
                  throw new SecurityException("Invalid username/password")
              }
          }
      

      【讨论】:

      • 仅当您想要强制进行已知良好的身份验证时才使用reauthenticate。此方法的主要用途是在更新数据库后更新身份验证,以确保内存中的数据是同步的(因此得名 - 它是 reauthenticate,而不是 authenticate)。但是,如果您想实际验证密码,请检查用户是否未锁定等,然后使用 ProviderManagerauthenticationManager bean)进行正确验证是必要的。
      • 当我使用“摘要”身份验证时,我已经实现了上面的服务以确保获得令牌......无论如何我错过了已移动到域类的 encodePassword()最后一个版本(即 beforeInsert())
      猜你喜欢
      • 1970-01-01
      • 2016-02-09
      • 2013-11-13
      • 2012-07-05
      • 2011-08-16
      • 2014-04-20
      • 2014-12-13
      • 2014-12-08
      • 2013-12-16
      相关资源
      最近更新 更多