Java 使用Spring Securitu获取通过Active Directory登录的用户的电子邮件地址
我正在开发一个基于SpringMVC的web应用程序,它使用SpringSecurity允许用户使用其Active Directory凭据登录。我想在用户登录后获取其电子邮件地址。我已经让登录工作,现在我正试图找出如何获得用户的电子邮件。看起来我应该从Java 使用Spring Securitu获取通过Active Directory登录的用户的电子邮件地址,java,spring-mvc,spring-security,active-directory,Java,Spring Mvc,Spring Security,Active Directory,我正在开发一个基于SpringMVC的web应用程序,它使用SpringSecurity允许用户使用其Active Directory凭据登录。我想在用户登录后获取其电子邮件地址。我已经让登录工作,现在我正试图找出如何获得用户的电子邮件。看起来我应该从InetOrgPerson对象中获取。我尝试在xml配置中指定InetOrgPersonContextMapper,如下所示: <bean id="ldapActiveDirectoryAuthProvider" class="org.spr
InetOrgPerson
对象中获取。我尝试在xml配置中指定InetOrgPersonContextMapper
,如下所示:
<bean id="ldapActiveDirectoryAuthProvider" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<constructor-arg name="domain" value="foo.bar" />
<constructor-arg name="url" value="ldap://foo.bar" />
<property name="useAuthenticationRequestCredentials" value="true" />
<property name="convertSubErrorCodesToExceptions" value="true" />
<property name="userDetailsContextMapper">
<bean class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper" />
</property>
</bean>
这给了我一个类强制转换异常,表示它无法将UsernamePasswordAuthenticationToken
强制转换为InetOrgPerson
。我决定尝试手动获取主体
对象,而不是让Spring注入它:
@RequestMapping(value = "/startProcess.html", method = RequestMethod.POST)
public ModelAndView startProcess(@ModelAttribute Token token, Principal principal)
{
ModelAndView mav = new ModelAndView();
String user = principal.getName();
Object p = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String email = ((InetOrgPerson)p).getMail();
logger.info("Got email \"" + email + "\" for user \"" + user + "\"");
...
}
这告诉我它不能将
ldapuserdetailsimple
强制转换为InetOrgPerson
。LdapUserDetailsImpl
不应该是InetOrgPerson
吗,因为我使用的是InetOrgPersonContextMapper
?我希望这个解决方案能在您的情况下起作用。
您可以使用LdapTemplate检索CustomMapper中指定的属性,即InetOrgPersonContextMapper类
其中contextSource是对的实例的引用@Autowire LdapTemplate LdapTemplate代码>
ldapuserdetailsiml ldapUserDetails=(ldapuserdetailsiml)p代码>
String dn=
InetOrgPerson
InetOrgPerson=ldapTemplate.lookup(dn,新的InetOrgPersonContextMapper())代码>
我忽略了这样一个事实,即在用户登录后,我正在使用自定义的
AuthenticationSuccessHandler
并使用UsernamePasswordAuthenticationToken
覆盖Authentication
我将
InetOrgPersonContextMapper
留在ActiveDirectoryLdapAuthenticationProvider
上,并在我的AuthenticationSuccessHandler
中将主体
强制转换为InetOrgPerson
并将其作为主体
存储在用户名密码验证令牌
中。之后,我可以成功地将主体
转换为控制器中的InetOrgPerson
,并调用getMail()
首先,您需要将映射器更改为org.springframework.security.ldap.userdetails.inetorgpersontextmapper
<beans:bean id="inetOrgPersonContextMapper" class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper">
</beans:bean>
我理解
getCredentials()
的结果是一个字符串,即用户名。对于您的实现来说不是这样吗?如果是这样的话,您将直接在Active Directory中查询具有该用户名的人的电子邮件地址。这应该是getPrincipal()
,getPrincipal()
再次返回一个字符串。您无法将字符串有效地用作InetOrgPerson
。考虑到例外情况是getPrincipal正在返回UsernamePasswordAuthenticationToken,并且我必须调用principal.getName()来获取用户名,因此我不同意您的看法。。。上次我检查字符串对象没有getName函数。我认为我不能使用此方法,因为我使用的是ActiveDirectoryLdapAuthenticationProvider
。文档指定使用ActiveDirectoryLdapAuthenticationProvider
时不需要ContextSource
。非常感谢!“改变地图绘制者”是我在同一问题上所需要的全部。
<beans:bean id="inetOrgPersonContextMapper" class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper">
</beans:bean>
<beans:bean id="adAuthenticationProvider" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
<beans:constructor-arg value="mydomain.com.local" />
<beans:constructor-arg value="ldap://servername/" />
<beans:property name="userDetailsContextMapper" ref="inetOrgPersonContextMapper" />
</beans:bean>
InetOrgPerson userDetails = (InetOrgPerson)(SecurityContextHolder.getContext().getAuthentication().getPrincipal());