来自服务的 Grails Spring Security 身份验证
Posted
技术标签:
【中文标题】来自服务的 Grails Spring Security 身份验证【英文标题】:Grails Spring Security authentication from a service 【发布时间】: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()
【问题讨论】:
【参考方案1】:您可能正在对密码进行双重编码。该插件的最新版本会生成一个用户/个人域类来为您编码密码,因此您无需调用springSecurityService.encodePassword("password")
,如果您这样做,则它会被编码两次。这应该有效:
User test = new User(
username: "test",
password: "password",
enabled: true
).save()
我省略了将accountExpired
、accountLocked
和passwordExpired
设置为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
)。但是,如果您想实际验证密码,请检查用户是否未锁定等,然后使用 ProviderManager
(authenticationManager
bean)进行正确验证是必要的。
当我使用“摘要”身份验证时,我已经实现了上面的服务以确保获得令牌......无论如何我错过了已移动到域类的 encodePassword()最后一个版本(即 beforeInsert())以上是关于来自服务的 Grails Spring Security 身份验证的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Grails 和 AngularJS 上使用 Spring Security 进行 Ajax 登录
如何使用 Spring resource.groovy 正确注入 Grails 服务