Java 使用Spring Securitu获取通过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

我正在开发一个基于SpringMVC的web应用程序,它使用SpringSecurity允许用户使用其Active Directory凭据登录。我想在用户登录后获取其电子邮件地址。我已经让登录工作,现在我正试图找出如何获得用户的电子邮件。看起来我应该从
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类

  • 创建类的bean



    其中contextSource是对的实例的引用

  • 通过自动布线将LDAPTemplatebean注入控制器
    @Autowire LdapTemplate LdapTemplate

  • 将主体实例强制转换为
    ldapuserdetailsiml ldapUserDetails=(ldapuserdetailsiml)p

  • 检索用户DN
    String dn=

  • 使用ldapTemplate实例的方法来获取映射(由映射器映射)对象,即
    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());