因此,您实际上需要将 AD 用户映射到 Person。
这是 src/groovy 中需要的 3 个类。显然根据需要修改它们:
package yourpackagename
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUser
import org.springframework.security.core.GrantedAuthority
class CustomUserDetails extends GrailsUser{
final String firstName
final String lastName
CustomUserDetails(String username, String password, boolean enabled,
boolean accountNonExpired, boolean credentialsNonExpired,
boolean accountNonLocked,
Collection<GrantedAuthority> authorities,
long id, String firstName, String lastName) {
super(username, password, enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, authorities, id)
this.firstName = firstName
this.lastName = lastName
}
}
package yourpackagenamehere
import org.codehaus.groovy.grails.plugins.springsecurity.GrailsUserDetailsService
import org.springframework.security.core.authority.GrantedAuthorityImpl
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
class CustomUserDetailsService 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)
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 CustomUserDetails(user.username, user.password, user.enabled,
!user.accountExpired, !user.passwordExpired,
!user.accountLocked, authorities ?: NO_ROLES, user.id,
user.firstName, user.lastName)
} as UserDetails
}
}
package yourpackagenamehere
import groovy.sql.Sql
import org.springframework.ldap.core.DirContextAdapter
import org.springframework.ldap.core.DirContextOperations
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper
import org.springframework.security.core.authority.GrantedAuthorityImpl
import org.springframework.security.core.GrantedAuthority
import org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.springframework.security.authentication.DisabledException
class CustomUserDetailsContextMapper implements UserDetailsContextMapper {
private static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]
def dataSource
@Override
public CustomUserDetails mapUserFromContext(DirContextOperations ctx, String username, Collection<GrantedAuthority> authority) {
username = username.toLowerCase()
User user = User.findByUsername(username)
String firstName = ctx.originalAttrs.attrs['givenname'].values[0]
String lastName = ctx.originalAttrs.attrs['sn'].values[0]
def roles
User.withTransaction {
if(!user){
user = new User(username: username, enabled: true, firstName: firstName, lastName: lastName)
user.save(flush: true)
}
else {
user = User.findByUsername(username)
user.firstName = firstName
user.lastName = lastName
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 CustomUserDetails(username, user.password, user.enabled, false, false, false, authorities, user.id, user.firstName, user.lastName)
return userDetails
}
@Override
public void mapUserToContext(UserDetails arg0, DirContextAdapter arg1) {
}
}
在 spring/resources.groovy 中的配置下:
import yourpackagenamehere.CustomUserDetailsService
import yourpackagenamehere.CustomUserDetailsContextMapper
beans = {
userDetailsService(CustomUserDetailsService)
ldapUserDetailsMapper(CustomUserDetailsContextMapper) {
dataSource = ref("dataSource")
}
}
在 Config.groovy 下,这是我的设置:
grails.plugins.springsecurity.ldap.context.managerDn = 'CN=username,OU=People,DC=foo,DC=com'
grails.plugins.springsecurity.ldap.context.managerPassword = 'password'
grails.plugins.springsecurity.ldap.context.server = 'ldap://foo.com:389/'
grails.plugins.springsecurity.ldap.authorities.ignorePartialResultException = true
grails.plugins.springsecurity.ldap.search.base = 'ou=People,dc=foo,dc=com'
grails.plugins.springsecurity.ldap.search.filter="sAMAccountName={0}"
grails.plugins.springsecurity.ldap.search.searchSubtree = true
grails.plugins.springsecurity.ldap.auth.hideUserNotFoundExceptions = false
grails.plugins.springsecurity.ldap.search.attributesToReturn = null
grails.plugins.springsecurity.providerNames = ['ldapAuthProvider', 'anonymousAuthenticationProvider']
grails.plugins.springsecurity.ldap.mapper.userDetailsClass = 'CustomUserDetails'
grails.plugins.springsecurity.ldap.authorities.retrieveGroupRoles = true
grails.plugins.springsecurity.ldap.authorities.retrieveDatabaseRoles = true
grails.plugins.springsecurity.ldap.authorities.groupSearchBase ='dc=foo,dc=com'
grails.plugins.springsecurity.ldap.authorities.groupSearchFilter = 'member={0}'