问题描述
我正在尝试将一个Stripes Web应用程序转换为Grails。 Stripes应用程序使用Spring Security,但我希望Grails应用程序使用Spring Security Grails插件。
该应用程序已具有用户
和角色
(Java )我需要重用的类,即我不能使用脚本生成。
Spring Security插件文档描述了如何使用现有的用户
域类。这些步骤似乎是:
- 定义一个
UserDetails
实现,它从现有的User
domain class - 定义一个定制的
UserDetailsService
1) - 将(2)的实例注册为名为
userDetailsService
的Spring bean。 - define a
UserDetails
implementation that reads from the existingUser
domain class - define a custom
UserDetailsService
implementation that returns instances of (1) - register an instance of (2) as a Spring bean named
userDetailsService
.
ol>
然而,文档没有提供任何有关如何使用现有的 Role
类和表示多个用户
和角色
。
使用现有的角色
,用户
和 UserRole $使用Grails Spring Security插件的c $ c>类?是否有任何理由让我运行脚本如果我不想生成任何域类>
据推测 GrailsUser
指的是自定义的 UserDetails
实施?在我的情况下,我可能会直接实现接口。这样看起来是否合理?
类UserAdapter实现UserDetails {
private String password
private Collection<的GrantedAuthority> springRoles
UserAdapter(用户用户){
this.password = user.password
集合< Role>角色= //加载旧角色对象
this.springRoles = roles.collect {new GrantedAuthorityImpl(it.authority)}
}
//如果使用密码哈希,大概是这样的是哈希密码?
String getPassword(){
密码
}
/////////其他UserDetails方法省略
集合<的GrantedAuthority> getAuthorities(){
springRoles
}
}
'I'因为存在有关在HTTP会话中存储潜在大对象的警告,所以不会在 UserAdapter
中存储整个用户
对象。
如果我使用我自己的 UserDetails
实现,那么大概我可以忽略这个注释提供一个 id
?
最后,如果我遵循上面概述的方法,应该设置在 Config.groovy
并且我是否需要运行 s2-quickstart
脚本(或其他)?
请记住Spring Security的确如此不用关心数据来自何处,只需要一个 UserDetails
实例进行DAO身份验证提供程序的身份验证,并且它可以来自任何地方。使用域类和数据库表很方便,但这只是一种方法。做什么适用于您的数据。最后,你需要的是一个新的 GrailsUser
(或其他一些impl)实例,其中用户名
和 password
set,3个布尔值集合,以及 GrantedAuthority
实例列表(以及 id
如果它是
GrailsUser
)。
当您拥有旧用户时最简单的事情角色数据是创建一个自定义的 UserDetailsService
。使用GORM,原始SQL查询,无论您需要获取所需的数据。
另一种选择是编写您自己的 AuthenticationProvider $ c $像格伦在这里做的: - 虽然这是一个更大的解决方案,也涉及您不需要的自定义过滤器。 DAO提供程序使用
UserDetailsService
,但创建自己的函数可以将功能组合到一个类中,这很好。
不过,重用 User
域类作为 UserDetails
不是一个好主意。即使你实现了接口,你也会在HTTP会话中存储一个断开连接的潜在大对象(如果有附加集合)对象。 POJO / POGO实现(Spring Security的 User
类,插件的 GrailsUser
类)非常小,只是一些字符串和布尔值。
I'm trying to convert a Stripes web app to Grails. The Stripes app uses Spring Security, but I would like the Grails app to use the Spring Security Grails plugin.
The app already has User
and Role
(Java) classes that I need to reuse, i.e. I cannot use the Grails domain classes that the s2-quickstart script generates.
The Spring Security plugin docs describe how to use an existing User
domain class. The steps seem to be:
However the docs don't provide any information about how to use an existing Role
class and the class that represents the many-to-many relationship between User
and Role
.
What other steps are necessary to use existing Role
, User
, and UserRole
classes with the Grails Spring Security plugin? Is there any reason for me to run the s2-quickstart script if I don't want to generate any domain classes?
Follow-Up Questions to Burt's Answer
Presumably GrailsUser
here refers to the custom UserDetails
implementation? In my case I'll probably just implement the interface directly. Does something like this seem reasonable?
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
}
}
I'm not storing the whole User
object within UserAdapter
because of your warning about storing a potentially large object in the HTTP session.
If I use my own UserDetails
implementation as above, then presumably I can ignore this comment about providing an id
?
Finally, if I follow the approach outlined above, should I set these properties in Config.groovy
and do I need to run the s2-quickstart
script (or any others)?
Keep in mind that Spring Security doesn't care where the data comes from, it just needs a UserDetails
instance when authenticating with the DAO auth provider and it can come from anywhere. It's convenient to use domain classes and database tables, but it's just one approach. Do what works for your data. In the end, what you need is a new GrailsUser
(or some other impl) instance with the username
and password
set, the 3 booleans set, and a List of GrantedAuthority
instances (and the id
if it's a GrailsUser
).
The simplest thing to do when you have legacy user and role data is to create a custom UserDetailsService
. Use GORM, raw SQL queries, whatever you need to get the required data.
Another option is to write your own AuthenticationProvider
like Glen did here: http://blogs.bytecode.com.au/glen/2010/01/15/hacking-custom-authentication-providers-with-grails-spring-security.html - although that's a larger solution that also involves a custom filter which you wouldn't need. The DAO provider uses a UserDetailsService
but it's fine to create your own that combines the functionality into one class.
It's not a good idea to reuse your User
domain class as the UserDetails
though. Even if you implement the interface, you'd be storing a disconnected potentially large (if there are attached collections) object in the HTTP session. The POJO/POGO implementations (Spring Security's User
class, the plugin's GrailsUser
class, etc.) are very small and just a few Strings and booleans.
这篇关于使用Spring Security插件使用现有的域类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!