我正在构建一个Web应用程序,其中的用户将通过我们的ldap数据库进行身份验证,但应用程序本身不会包含用户数据库,因此除角色之外的所有详细信息都将来自ldap。经过多次努力,我已经将我的应用程序连接到数据库并进行身份验证,但我无法获取任何用户详细信息以映射到主体。
我的Config.groovy包含以下内容:
grails.plugin.springsecurity.ldap.search.base = 'OU=***,DC=***,DC=***'
grails.plugin.springsecurity.ldap.search.filter = "(sAMAccountName={0})"
grails.plugin.springsecurity.ldap.mapper.userDetailsClass = '<pack.age>.award.MyUserDetails'
grails.plugin.springsecurity.ldap.context.managerDN = 'CN=***,OU=*** ,DC=***,dc=***'
grails.plugin.springsecurity.ldap.context.managerPassword = '[redacted]'
grails.plugin.springsecurity.ldap.context.server = 'ldaps://server:port'
grails.plugin.springsecurity.ldap.authorities.retrieveGroupRoles = false
grails.plugin.springsecurity.ldap.authorities.retrieveDatabaseRoles = true
grails.plugin.springsecurity.ldap.search.attributesToReturn = ['mail', 'displayName']
grails.plugin.springsecurity.providerNames = ['ldapAuthProvider'].
MyUserDetails.groovy:
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.userdetails.User
class MyUserDetails extends User {
// extra instance variables
final String fullname
final String email
MyUserDetails(String username, String password, boolean enabled, boolean accountNonExpired,
boolean credentialsNonExpired, boolean accountNonLocked, boolean passwordNonExpired, String fullname,
String email, Collection authorities) {
super(username, password, enabled, accountNonExpired,
credentialsNonExpired, accountNonLocked, passwordNonExpired, authorities)
println "test";
this.fullname = fullname
this.email = email
}
}
MyUserDetailsContextMapper.groovy:
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 edu.bellevue.award.MyUserDetails
class MyUserDetailsContextMapper implements UserDetailsContextMapper {
UserDetails mapUserFromContext(DirContextOperations ctx, String username,
Collection authorities) {
String fullname = ctx.originalAttrs.attrs['cn'].values[0]
String email = ctx.originalAttrs.attrs['mail'].values[0].toString().toLowerCase()
def userDetails = new MyUserDetails(username, '', true, true, true, true, true,
fullname, email)
return userDetails
}
void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
throw new IllegalStateException("Only retrieving data from AD is currently supported")
}
}
通过所有日志消息,我可以看到我的应用程序正在连接到数据库并进行身份验证,但如果我尝试打印出主体(仅使用println或log.info),它只会说anonymousUser。我不知道它是否相关,但是我得到了一些例外。
| Error 2014-02-12 15:43:25,630 [http-bio-8080-exec-1] ERROR [/award].[default] - Servlet.service() for servlet [default] in context with path [/award] threw exception
Message: No signature of method: static java.lang.Math.max() is applicable for argument types: (java.lang.Integer, null) values: [4, null]
Possible solutions: max(int, int), max(double, double), max(float, float), max(long, long), min(int, int), wait()
Line | Method
->> 251 | doAppend in org.apache.log4j.AppenderSkeleton
还有:
AuthorizationFailureEvent[source=FilterInvocation: URL: /grails-errorhandler]
2014-02-12 15:43:25,720 [http-bio-8080-exec-1] DEBUG access.ExceptionTranslationFilter - Access is denied (user is anonymous); redirecting to authentication entry point
Message: Access is denied
Line | Method
->> 47 | decide in grails.plugin.springsecurity.access.vote.AuthenticatedVetoableDecisionManager