我正在尝试将Stripes网络应用转换为Grails。 Stripes应用程序使用Spring Security,但我希望Grails应用程序使用Spring Security Grails插件。
应用程序已经有User
和Role
(Java)类需要重用,即我不能使用s2-quickstart脚本生成的Grails域类。
Spring Security插件文档描述了如何使用现有的User
域类。步骤似乎是:
UserDetails
域类User
实现
UserDetailsService
实现
userDetailsService
。但是,文档不提供有关如何使用现有Role
类的任何信息以及表示User
和Role
之间多对多关系的类。< / p>
使用Grails Spring Security插件的现有Role
,User
和UserRole
类需要执行哪些其他步骤?如果我不想生成任何域类,是否有任何理由让我运行s2-quickstart脚本?
最后,您需要的是新的
GrailsUser
大概GrailsUser
这里是指自定义UserDetails
实施?在我的情况下,我可能只是直接实现接口。这样的事情看起来合情合理吗?
class UserAdapter implements UserDetails {
private String password
private Collection<GrantedAuthority> springRoles
UserAdapter(User user) {
this.password = user.password
Collection<Role> roles = // load legacy Role objects
this.springRoles = roles.collect { new GrantedAuthorityImpl(it.authority) }
}
// If using password hashing, presumably this is the hashed password?
String getPassword() {
password
}
///////// other UserDetails methods omitted
Collection<GrantedAuthority> getAuthorities() {
springRoles
}
}
我没有将整个User
对象存储在UserAdapter
中,因为您有关于在HTTP会话中存储潜在大对象的警告。
你需要的是.....和一个GrantedAuthority实例列表(如果是GrailsUser则是id)
如果我使用我自己的UserDetails
实现,那么我可以忽略这个关于提供id
的评论吗?
最后,如果我按照上面列出的方法,我应该在Config.groovy
中设置these properties,是否需要运行s2-quickstart
脚本(或其他任何脚本)?
答案 0 :(得分:4)
请记住,Spring Security并不关心数据的来源,在使用DAO身份验证提供程序进行身份验证时只需要一个UserDetails
实例,它可以来自任何地方。使用域类和数据库表很方便,但这只是一种方法。做什么适用于您的数据。最后,您需要的是一个新的GrailsUser
(或其他一些impl)实例,其中设置了username
和password
,设置了3个布尔值,以及{{1}的列表实例(以及GrantedAuthority
,如果它是id
)。
拥有旧版用户和角色数据时,最简单的方法是创建自定义GrailsUser
。使用GORM,原始SQL查询,无论您需要什么来获取所需数据。
另一种选择是编写自己的UserDetailsService
,就像Glen在这里做的那样:http://blogs.bytecode.com.au/glen/2010/01/15/hacking-custom-authentication-providers-with-grails-spring-security.html - 虽然这是一个更大的解决方案,也涉及到您不需要的自定义过滤器。 DAO提供程序使用AuthenticationProvider
但是可以创建自己的功能,将功能组合到一个类中。
虽然将UserDetailsService
域类重用为User
并不是一个好主意。即使您实现了该接口,您也将在HTTP会话中存储一个断开连接的潜在大型对象(如果有附加集合)。 POJO / POGO实现(Spring Security的UserDetails
类,插件的User
类等)非常小,只有少数字符串和布尔值。
答案 1 :(得分:1)
在config.groovy文件中,您必须指定要使用的域类:
grails.plugins.springsecurity.userLookup.userDomainClassName = 'your.package.User'
grails.plugins.springsecurity.userLookup.authorityJoinClassName = 'your.package.UserRole'
grails.plugins.springsecurity.authority.className = 'your.package.Role'
我认为实施自己的userDetail服务不是必要的,因为Spring安全使用
SpringSecurityUtils.securityConfig.userLookup
确定之前配置的域类的方法。您的域类必须提供必需的字段和关系。