首页 > 解决方案 > 如果我们想从 ActiveDirectory 获取用户详细信息,是否需要编写 CustomActiveDirectoryLdapAuthenticationProvider

问题描述

如果我们需要从 ActiveDirectory 获取用户属性,例如名称、sn 等。我们不能使用使用 Active Directory 配置约定的专用 LDAP 身份验证提供程序进行配置,例如“springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider”

 @Override
    protected void configure(HttpSecurity http) throws Exception {

            http.csrf().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                        .authorizeRequests().antMatchers("/", "logout").permitAll().and().httpBasic();
    }


     @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception { 

            auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
        }

     @Bean
        public AuthenticationManager authenticationManager() {

         return new ProviderManager(Arrays.asList(activeDirectoryLdapAuthenticationProvider()));
        }

     @Bean
        public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() {

            ActiveDirectoryLdapAuthenticationProvider adProvider = new ActiveDirectoryLdapAuthenticationProvider(domain, url);
            adProvider.setConvertSubErrorCodesToExceptions(true);
            adProvider.setUseAuthenticationRequestCredentials(true);

            return adProvider;
        }

然后使用 AuthenticationManager 如下所示。

Authentication auth = new UsernamePasswordAuthenticationToken(userName, password);
        Authentication a = authenticationManager.authenticate(auth);

但是,对于正确的用户名和密码,我得到 a.isAuthenticated() 为真,我也得到 a.getName() 作为我的用户名。但是,如何检索 sn、dispalyname、name 和其他属性。我们是否需要像这里提到的那样编写一个 CustomActiveDirectoryLdapAuthenticationProvider http://code-addict.pl/active-directory-spring-security/

标签: spring-bootspring-securityactive-directoryspring-ldapspring-security-ldap

解决方案


你不。Spring Security 自带UserDetailsContextMapper接口

/**
 * Creates a fully populated UserDetails object for use by the security framework.
 *
 * @param ctx the context object which contains the user information.
 * @param username the user's supplied login name.
 * @param authorities
 * @return the user object.
 */
UserDetails mapUserFromContext(DirContextOperations ctx, String username,
        Collection<? extends GrantedAuthority> authorities);

默认实现,LdapUserDetailsMapper

当前仅映射搜索返回的组。

// Map the roles
for (int i = 0; (this.roleAttributes != null)
        && (i < this.roleAttributes.length); i++) {
    String[] rolesForAttribute = ctx.getStringAttributes(this.roleAttributes[i]);

    if (rolesForAttribute == null) {
        this.logger.debug("Couldn't read role attribute '"
                + this.roleAttributes[i] + "' for user " + dn);
        continue;
    }
        for (String role : rolesForAttribute) {
        GrantedAuthority authority = createAuthority(role);
            if (authority != null) {
            essence.addAuthority(authority);
        }
    }
}

但是,通过实现您自己的UserDetailsMapper,您可以检索从 LDAP 返回的任何和所有记录。

您只需决定要获取的属性

Object attribute = ctx.getObjectAttribute("some-ldap-attribute");

这是您在身份验证事件期间获取自定义值的方式。

如果您只想从 LDAP 目录中查询、搜索和获取数据,您可以利用SpringSecurityLdapTemplate

它旨在模仿RestTemplate对 HTTP 的作用,但对 LDAP 的作用。


推荐阅读