我有一个 Spring MVC REST 应用程序。我已经使用 AD 作为身份验证提供程序实现了 Spring 安全性。我需要实现一些可以帮助搜索 AD 的控制器方法。因此,我定义了一个用户详细信息服务,该服务自动LdapTemplate
连接以在 AD 上执行查询。
UserDetailsSvc.java
@Component
public class UserDetailsSvc {
@Autowired
LdapTemplate ldapTemplate;
private final Logger logger = Logger.getLogger(UserDetailsSvc.class);
@SuppressWarnings("unchecked")
public UserDetails getUserDetails(String username) {
// Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// logger.info("Auth Details: " + authentication.getPrincipal() + "/" + authentication.getCredentials());
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("objectClass", "user"));
filter.and(new EqualsFilter("userPrincipalName", username));
logger.info("AD filter: " + filter.encode());
LinkedList<Map<String, String>> list = (LinkedList<Map<String, String>>)
ldapTemplate.search("", filter.encode(), new UserAttributesMapper());
logger.info("AD Search complete");
UserDetails ud = new UserDetails();
if (!list.isEmpty()) {
// Should only return one item
ud.setName(username);
ud.setDetails(list.get(0));
}
return ud;
}
private class UserAttributesMapper implements AttributesMapper {
@Override
public Map<String, String> mapFromAttributes(Attributes attributes) throws javax.naming.NamingException {
Map<String, String> map = new HashMap<String, String>();
logger.info("UserAttributesMapper: " + attributes.toString() );
String fullname = (String) attributes.get("displayName").get();
String email = (String) attributes.get("mail").get();
String title = (String) attributes.get("title").get();
String image = (String) attributes.get("extensionAttribute1").get();
String username = (String) attributes.get("uid").get();
map.put("fullname", fullname);
map.put("email", email);
map.put("title", title);
map.put("image", image);
map.put("username", username);
logger.info("user details : " + map.get("fullname") + map.get("email") + map.get("title") + map.get("image") + map.get("username"));
return map;
}
}
}
spring security xml 文件的片段。
弹簧安全.xml
<beans:bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<beans:constructor-arg ref="contextSource" />
<beans:property name="ignorePartialResultException" value="true" />
</beans:bean>
<beans:bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<beans:property name="url" value="${ldap.url}" />
<beans:property name="base" value="${ldap.basecn}" />
<beans:property name="authenticationSource" ref="authenticationSource" />
</beans:bean>
<beans:bean id="authenticationSource" class="org.springframework.ldap.authentication.DefaultValuesAuthenticationSourceDecorator">
<beans:property name="target" ref="springSecurityAuthenticationSource" />
<beans:property name="defaultUser" value="{ldap.defuser}" />
<beans:property name="defaultPassword" value="{ldap.password}" />
</beans:bean>
<beans:bean id="springSecurityAuthenticationSource"
class="org.springframework.security.ldap.authentication.SpringSecurityAuthenticationSource" />
问题是ldapTemplate.search
throws NullPointerException
。你能帮忙吗?
这是我得到的例外:
java.lang.NullPointerException
at java.util.Hashtable.put(Hashtable.java:542)
at org.springframework.ldap.core.support.SimpleDirContextAuthenticationStrategy.setupEnvironment(SimpleDirContextAuthenticationStrategy.java:44)
at org.springframework.ldap.core.support.AbstractContextSource.setupAuthenticatedEnvironment(AbstractContextSource.java:155)
at org.springframework.ldap.core.support.AbstractContextSource.getAuthenticatedEnv(AbstractContextSource.java:481)
at org.springframework.ldap.core.support.AbstractContextSource.getContext(AbstractContextSource.java:106)
at org.springframework.ldap.core.support.AbstractContextSource.getReadOnlyContext(AbstractContextSource.java:125)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:287)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:259)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:571)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:556)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:411)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:431)
at org.springframework.ldap.core.LdapTemplate.search(LdapTemplate.java:451)
at com.vmware.concorde.appadm.service.UserDetailsSvc.getUserDetails(UserDetailsSvc.java:44)
at com.vmware.concorde.appadm.web.UserController.findUsers(UserController.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
...
谢谢卡利安