【发布时间】:2014-01-12 03:11:02
【问题描述】:
在我的 Grails 应用程序中,我使用 Spring Security 插件并定义了 custom userDetailsService Spring bean 以控制如何检索用户和角色数据,例如
class MyUserDetailsService implements GrailsUserDetailsService {
/**
* Some Spring Security classes (e.g. RoleHierarchyVoter) expect at least one role, so
* we give a user with no granted roles this one which gets past that restriction but
* doesn't grant anything.
*/
static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]
UserDetails loadUserByUsername(String username, boolean loadRoles) {
return loadUserByUsername(username)
}
UserDetails loadUserByUsername(String username) {
User.withTransaction { status ->
User user = User.findByUsername(username)
if (!user) {
throw new UsernameNotFoundException('User not found', username)
}
def authorities = user.authorities.collect {new GrantedAuthorityImpl(it.authority)}
return new CustomUserDetails(
user.username,
user.password,
user.enabled,
!user.accountExpired,
!user.passwordExpired,
!user.accountLocked,
authorities ?: NO_ROLES,
user.id,
user.name)
}
}
}
上面引用的CustomUserDetails 类只是用name 字段扩展GrailsUser:
class CustomUserDetails extends GrailsUser {
private static final long serialVersionUID = 1;
final String name
CustomUserDetails(String username,
String password,
boolean enabled,
boolean accountNonExpired,
boolean credentialsNonExpired,
boolean accountNonLocked,
Collection<GrantedAuthority> authorities,
long id,
String displayName) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities, id)
this.name = displayName
}
}
除了自定义用户和角色数据的检索方式之外,我还想控制用户的身份验证方式。在我的情况下,身份验证过程并不像通常的“检查输入的密码是否与数据库中的密码匹配”那么简单。用户如何通过身份验证的实际细节无关紧要,因此为了简单起见,我们假设如果用户的 name 字段与输入的密码匹配,则他被授予封装在 CustomUserDetails 中的角色(权限)。
我想插件中的某个地方有一个 Spring bean,我可以覆盖它以自定义默认身份验证机制,但是哪个?因为name字段仅由CustomUserDetails定义,所以我需要访问MyUserDetailsService返回的这个类的实例才能执行自定义身份验证,这可能吗?
【问题讨论】:
标签: grails spring-security grails-plugin