Grails Spring Security LDAP [英] Grails Spring Security LDAP
问题描述
我一直在墙上敲打我的头,试图将经过LDAP验证的grails用户映射到应用程序中的数据库角色和用户。遵循此答案和 documentation 。
如果我不包括bean ldap认证作品,但是在GORM中有很多关于创建和更新的关系。
我一直到达CustomUserDetails无法转换为UserDetails。
消息:无法将类'package.MdtUserDetails'的对象'ldap_username'转换为类'org.springframework.security。 core.userdetails.UserDetails'
在调用MdtUserDetails时,UserDetailsContextMapper类发生错误:
import java.util.Collection;
import org.springframework.ldap.core.DirContextAdapter $ b $ import org.springframework.ldap.core.DirContextOperations
import org.springframework.security.authentication.DisabledException
import org.springframework .security.core.GrantedAuthority
导入org.springframework.security.core.authority.GrantedAuthorityImpl
导入org.springframework.security.core.userdetails.UserDetails
导入org.springframework.security.ldap .userdetails.UserDetailsContextMapper
import grails.plugin.springsecurity.SpringSecurityUtils
import package.User
import package.Role
import package.UserRole
class MdtUserDetailsContextMapper implements UserDetailsContextMapper {
private static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]
def dataSource
@Override
public UserDetails mapUserFromContext(DirContextOperations ctx,String username,Collection<授予权威> (用户名)
字符串ldapName = ctx.originalAttrs.attrs ['name ']
String ldapEmail = ctx.originalAttrs.attrs ['mail']
String splitName = ldapName.split(:)[1]
String fullname = splitName.split(, )[1] ++ splitName.split(,)[0]
String email = ldapEmail.split(:)[1]
def roles
User.withTransaction {
if(!user){
user = new User(username:username,enabled:true,fullName:fullname,email:email)。 save(flush:true)
UserRole.create user,Role.findByAuthority('ROLE_USER'),true
roles = Role.findByAuthority('ROLE_USER')
}
else {
user = User.findByUsername(用户名)
user.fullName =全名
user.email = email
user.save(flush:true)
roles = user.getAuthorities()
}
}
if(!user.enabled)
throw new DisabledException(User is disabled,username)
def authorities = roles.collect {new GrantedAuthorityImpl(it .authority)}
authority.addAll(authority)
$ b $ def userDetails = new MdtUserDetails(fullname,email,username,,true,false,false,false,authorities)//错误在这里...
返回userDetails
}
@Override
public void mapUserToContext(UserDetails arg0,DirContextAdapter arg1){
}
}
这里是我的resources.goovy
import package.MdtUserDetailsContextMapper
pre>
import package.MdtUserDetailsService
beans = {
ldapUserDetailsMapper(MdtUserDetailsCont extMapper){
dataSource = ref(dataSource)
}
UserDetailsService(MdtUserDetailsService)
}
config.groovy:
grails.plugin.springsecurity。 ldap.context.managerDn ='cn = MDT Apache,ou = ServiceAccounts,ou = Users,ou = MDT,dc = mdthq,dc = mt,dc = ads'
grails.plugin.springsecurity.ldap.context。 managerPassword ='*******'
grails.plugin.springsecurity.ldap.context.server ='ldap:// server:389'
grails.plugin.springsecurity.ldap.authorities。 groupSearchBase ='ou = Groups,ou = MDT,dc = mdthq,dc = mt,dc = ads'
grails.plugin.springsecurity.ldap.search.base ='ou = Users,ou = MDT,dc = mdthq,dc = mt,dc = ads'
grails.plugin.springsecurity.ldap.authorities.retrieveGroupRoles = true
grails.plugin.springsecurity.ldap.authorities.retrieveDatabaseRoles = true
grails。 plugin.springsecurity.ldap.mapper.userDetailsClass ='package.MdtUserDetails'
grails.plugin.springsecurity.ldap.a uthorities.ignorePartialResultException = true //通常需要Active Directory
grails.plugin.springsecurity.ldap.search.filter =sAMAccountName = {0}//对于Active Directory,您需要此
grails.plugin .springsecurity.ldap.search.searchSubtree = true
grails.plugin.springsecurity.ldap.auth.hideUserNotFoundExceptions = false
grails.plugin.springsecurity.ldap.search.attributesToReturn = ['mail','displayName ','sAMAccountName'] //你想返回的额外属性;请参阅下面有关访问此数据的自定义类
grails.plugin.springsecurity.ldap.authorities.groupSearchFilter ='(成员:1.2.840.113556.1.4.1941:= {0})'
//检查首先针对LDAP,然后是Database
grails.plugin.springsecurity.providerNames = ['ldapAuthProvider','daoAuthenticationProvider']
然后UserDetails和UserDetailsService的类:
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority
import package.User
class MdtUserDetails extends User {
public MdtUserDetails( String fullName,String email,String username,String password,boolean enabled,boolean accountExpired,
boolean accountLocked,boolean passwordExpired,Collection< GrantedAuthority> authorities){
super(username :用户名,密码:密码,电子邮件:电子邮件,全名:fullName,启用:启用,accountExpired:accountExpired,accountLocked:accountLocked,passwordExpired:passwordExpired)
this.fullName = fullName
this。 email = email
$ b}
}
导入包。用户
导入grails.plugin。 springsecurity.userdetails.GrailsUserDetailsService
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UsernameNotFoundException
导入grails.plugin.springsecurity.SpringSecurityUtils
class MdtUserDetailsService实现GrailsUserDetailsService {
static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]
UserDetails loadUserByUsername(String username,boolean loadRoles)
throws UsernameNotFoundException {
return loadUserByUsername(username)
$ b $ UserDetails loadUserByUsername(String username)throws UsernameNotFoundException {
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)}
返回新的MdtUserDetails(user.fullName,user.email,user.username,user.password,user.enabled,
! user.accountExpired,!user.passwordExpired,
!user.accountLocked,authorities?:NO_ROLES)
}作为UserDetails
}
}
更新后的用户详细信息:
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.ldap.userdetails.LdapUserDetails
import package.Role
导入包。用户
类MdtUserDetails扩展用户实现LdapUserDetails {
最终字符串电子邮件
最终字符串全名
public MdtUserDetails(String fullName ,String email,String username,String password,boolean enabled,boolean accountExpired,
boolean accountLocked,boolean passwordExpired,Collection<授权机构>权限){
// super(username:username)
// super(用户名:用户名,密码:密码,电子邮件:电子邮件,fullName:fullName,启用:启用,accountExpired:accountExpired,accountLocked:accountLocked,passwordExpired:passwordExpired,authorties:权限)
this.fullName =全名
this.email =电子邮件
}
@覆盖
public Set< Role> getAuthorities(){
return super.getAuthorities()
$ b @Override
public boolean isAccountNonExpired(){
// TODO自动生成的方法存根
返回false;
$ b $覆盖
public boolean isAccountNonLocked(){
// TODO自动生成的方法存根
return false;
}
@Override
public boolean isCredentialsNonExpired(){
// TODO自动生成的方法存根
返回false;
$ b @Override
public String getDn(){
// TODO自动生成的方法存根
返回null;
}
}
编辑
最后想出了这个!UserBetails类中的
我扩展了我自己的用户class:
import package.User
class MdtUserDetails extends User {
相反,我需要从这里扩展springsecurity用户类:
import org.springframework.security.core.userdetails.User
解决方案
MdtUserDetails
需要实现UserDetails
界面。尝试如下所示:class MdtUserDetails extends User实现LdapUserDetails {
... //接口所需的一切
}
I've been banging my head on a wall try to map a grails user authenticated against LDAP to the database Roles and Users in the application. Following the examples in this answer and the documentation.
If I don't include the bean ldap auth works, but there are many ties in the GORM to a user for creates and updates.
I keep reaching the point where my CustomUserDetails cannot cast to the UserDetails.
Message: Cannot cast object 'ldap_username' with class 'package.MdtUserDetails' to class 'org.springframework.security.core.userdetails.UserDetails'
The error occurs in the UserDetailsContextMapper Class, when calling MdtUserDetails:
import java.util.Collection; import org.springframework.ldap.core.DirContextAdapter import org.springframework.ldap.core.DirContextOperations import org.springframework.security.authentication.DisabledException import org.springframework.security.core.GrantedAuthority import org.springframework.security.core.authority.GrantedAuthorityImpl import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.ldap.userdetails.UserDetailsContextMapper import grails.plugin.springsecurity.SpringSecurityUtils import package.User import package.Role import package.UserRole class MdtUserDetailsContextMapper implements UserDetailsContextMapper { private static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)] def dataSource @Override public UserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<GrantedAuthority> authority) { username = username.toLowerCase() User user = User.findByUsername(username) String ldapName = ctx.originalAttrs.attrs['name'] String ldapEmail = ctx.originalAttrs.attrs['mail'] String splitName = ldapName.split(": ")[1] String fullname = splitName.split(", ")[1] + " " + splitName.split(", ")[0] String email = ldapEmail.split(": ")[1] def roles User.withTransaction { if(!user){ user = new User(username: username, enabled: true, fullName: fullname, email: email).save(flush: true) UserRole.create user, Role.findByAuthority('ROLE_USER'), true roles = Role.findByAuthority('ROLE_USER') } else { user = User.findByUsername(username) user.fullName = fullname user.email = email user.save(flush: true) roles = user.getAuthorities() } } if ( !user.enabled ) throw new DisabledException("User is disabled", username) def authorities = roles.collect { new GrantedAuthorityImpl(it.authority) } authorities.addAll(authority) def userDetails = new MdtUserDetails(fullname, email, username, "", true, false, false, false, authorities) //the error is here... return userDetails } @Override public void mapUserToContext(UserDetails arg0, DirContextAdapter arg1) { } }
here is my resources.goovy
import package.MdtUserDetailsContextMapper import package.MdtUserDetailsService beans = { ldapUserDetailsMapper(MdtUserDetailsContextMapper) { dataSource = ref("dataSource") } UserDetailsService(MdtUserDetailsService) }
config.groovy:
grails.plugin.springsecurity.ldap.context.managerDn = 'cn=MDT Apache,ou=ServiceAccounts,ou=Users,ou=MDT,dc=mdthq,dc=mt,dc=ads' grails.plugin.springsecurity.ldap.context.managerPassword = '*******' grails.plugin.springsecurity.ldap.context.server = 'ldap://server:389' grails.plugin.springsecurity.ldap.authorities.groupSearchBase = 'ou=Groups,ou=MDT,dc=mdthq,dc=mt,dc=ads' grails.plugin.springsecurity.ldap.search.base = 'ou=Users,ou=MDT,dc=mdthq,dc=mt,dc=ads' grails.plugin.springsecurity.ldap.authorities.retrieveGroupRoles = true grails.plugin.springsecurity.ldap.authorities.retrieveDatabaseRoles = true grails.plugin.springsecurity.ldap.mapper.userDetailsClass = 'package.MdtUserDetails' grails.plugin.springsecurity.ldap.authorities.ignorePartialResultException = true // typically needed for Active Directory grails.plugin.springsecurity.ldap.search.filter="sAMAccountName={0}" // for Active Directory you need this grails.plugin.springsecurity.ldap.search.searchSubtree = true grails.plugin.springsecurity.ldap.auth.hideUserNotFoundExceptions = false grails.plugin.springsecurity.ldap.search.attributesToReturn = ['mail', 'displayName', 'sAMAccountName'] // extra attributes you want returned; see below for custom classes that access this data grails.plugin.springsecurity.ldap.authorities.groupSearchFilter = '(member:1.2.840.113556.1.4.1941:={0})' //check against LDAP first, then Database grails.plugin.springsecurity.providerNames = ['ldapAuthProvider', 'daoAuthenticationProvider']
Then classes for UserDetails and UserDetailsService:
import java.util.Collection; import org.springframework.security.core.GrantedAuthority import package.User class MdtUserDetails extends User { public MdtUserDetails(String fullName, String email, String username, String password, boolean enabled, boolean accountExpired, boolean accountLocked, boolean passwordExpired, Collection<GrantedAuthority> authorities) { super(username: username, password: password, email: email, fullName: fullName, enabled: enabled, accountExpired: accountExpired, accountLocked: accountLocked, passwordExpired: passwordExpired) this.fullName = fullName this.email = email } } import package.User import grails.plugin.springsecurity.userdetails.GrailsUserDetailsService import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.GrantedAuthorityImpl import org.springframework.security.core.userdetails.UserDetails import org.springframework.security.core.userdetails.UsernameNotFoundException import grails.plugin.springsecurity.SpringSecurityUtils class MdtUserDetailsService implements GrailsUserDetailsService { static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)] UserDetails loadUserByUsername(String username, boolean loadRoles) throws UsernameNotFoundException { return loadUserByUsername(username) } UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 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 MdtUserDetails(user.fullName, user.email, user.username, user.password, user.enabled, !user.accountExpired, !user.passwordExpired, !user.accountLocked, authorities ?: NO_ROLES) } as UserDetails } }
Updated UserDetails:
import java.util.Collection; import org.springframework.security.core.GrantedAuthority import org.springframework.security.ldap.userdetails.LdapUserDetails import package.Role import package.User class MdtUserDetails extends User implements LdapUserDetails{ final String email final String fullName public MdtUserDetails(String fullName, String email, String username, String password, boolean enabled, boolean accountExpired, boolean accountLocked, boolean passwordExpired, Collection<GrantedAuthority> authorities) { //super(username: username) //super(username: username, password: password, email: email, fullName: fullName, enabled: enabled, accountExpired: accountExpired, accountLocked: accountLocked, passwordExpired: passwordExpired, authorties: authorities) this.fullName = fullName this.email = email } @Override public Set<Role> getAuthorities(){ return super.getAuthorities() } @Override public boolean isAccountNonExpired() { // TODO Auto-generated method stub return false; } @Override public boolean isAccountNonLocked() { // TODO Auto-generated method stub return false; } @Override public boolean isCredentialsNonExpired() { // TODO Auto-generated method stub return false; } @Override public String getDn() { // TODO Auto-generated method stub return null; } }
EDIT
Finally figured this out!
in the UserDetails class I was extending my own user class:
import package.User class MdtUserDetails extends User {
Instead I needed to extend the springsecurity user class from here :
import org.springframework.security.core.userdetails.User
解决方案
MdtUserDetails
needs to implement theUserDetails
interface. Try something like this:class MdtUserDetails extends User implements LdapUserDetails { ... //everything required by the interface }
这篇关于Grails Spring Security LDAP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文