java - SpringBoot,如何在不使用ldif的情况下使用LDAP进行身份验证?

标签 java spring spring-security spring-boot

我正在 SpringBoot 中尝试 LDAP 身份验证示例 here

它使用的是 ldif 方法,我认为该方法不适用于我的要求,因为我们的 ldap 管理员不会告诉我在哪里可以找到我需要的 ldif。 在 springboot 之前,我曾经使用自己的 ldap 实现,而不是使用 ldif。有没有办法验证不只使用 ldif SECURITY_AUTHENTICATION.simple ? 下面是我如何在基本 Java 没有 spring 的情况下进行 ldap 安全性。如何在 Spring 中执行此操作而不使用 ldif 只是基本用户名密码。

boolean isLdapRegistred(String username, String password) {
    boolean result = false;
    try {

        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://10.x.x.x:389");           
        env.put(Context.SECURITY_AUTHENTICATION, "simple");         
        env.put(Context.SECURITY_PRINCIPAL, "OUR-DOMAIN\\" + username);
        env.put(Context.SECURITY_CREDENTIALS, password);

        // Create the initial context
        DirContext ctx = new InitialDirContext(env);
        result = ctx != null;
        if (ctx != null)
        ctx.close();
        System.out.println(result);
        return result;
    } catch (Exception e) {
        System.out.println("oops");
        return result;
    }

}

下面是 SpringBoots 示例,需要使用我的凭据而不是 ldif。

@Configuration
protected static class AuthenticationConfiguration extends
        GlobalAuthenticationConfigurerAdapter {

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .ldapAuthentication()
                .userDnPatterns("uid={0},ou=people")
                .groupSearchBase("ou=groups")
                .contextSource().ldif("classpath:test-server.ldif");
    }
}

最佳答案

这个对我来说非常有效,但我需要对其进行微小的修改。

    @Configuration
    @EnableWebSecurity
    public class HttpSecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(ldapAuthenticationProvider());
        }

        @Bean
        public AuthenticationProvider ldapAuthenticationProvider() throws Exception {
            DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(
Arrays.asList("ldapServerUrl:port"),rootDn);
            contextSource.afterPropertiesSet();
            LdapUserSearch ldapUserSearch = new FilterBasedLdapUserSearch(ldapUserSearchBase, ldapUserSearchFilter, contextSource);
            BindAuthenticator bindAuthenticator = new BindAuthenticator(contextSource);
            bindAuthenticator.setUserSearch(ldapUserSearch);
            LdapAuthenticationProvider ldapAuthenticationProvider = new LdapAuthenticationProvider(bindAuthenticator, new DefaultLdapAuthoritiesPopulator(contextSource, ldapGroupSearchBase));
            return ldapAuthenticationProvider;
        }
    }

我已经经历了好几天的痛苦才走到这一步 否则,您可以使用自定义身份验证并进行类似的操作

    @Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    private Logger log = Logger.getLogger(CustomAuthenticationProvider.class);

    @Override
    public Authentication authenticate(Authentication authentication) 
      throws AuthenticationException {

        String email = authentication.getName();
        String password = authentication.getCredentials().toString();

        log.info("email : " + email);
        log.info("password : " + password);

        try {
            if (authenticate(email, password)) {

                // use the credentials
                // and authenticate against the third-party system
                return new UsernamePasswordAuthenticationToken(
                        email, password, new ArrayList<>());
            } else {
                return null;
            }
        } catch (NamingException ex) {
            log.info(ex);
        }
        return null;
    }

    boolean isLdapRegistred(String username, String password) {
    boolean result = false;
    try {

        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://10.x.x.x:389");           
        env.put(Context.SECURITY_AUTHENTICATION, "simple");         
        env.put(Context.SECURITY_PRINCIPAL, "OUR-DOMAIN\\" + username);
        env.put(Context.SECURITY_CREDENTIALS, password);

        // Create the initial context
        DirContext ctx = new InitialDirContext(env);
        result = ctx != null;
        if (ctx != null)
        ctx.close();
        System.out.println(result);
        return result;
    } catch (Exception e) {
        System.out.println("oops");
        return result;
    }

}


    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(
          UsernamePasswordAuthenticationToken.class);
    }
}

在另一个类(class)

    @Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    private Logger log = Logger.getLogger(WebSecurityConfiguration.class);
    @Autowired
    private CustomAuthenticationProvider authProvider;

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

        auth.authenticationProvider(authProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
            .and()
            .httpBasic();
    }
}

然后奇迹就发生了

关于java - SpringBoot,如何在不使用ldif的情况下使用LDAP进行身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36732689/

相关文章:

java - 读取 URL 的第一行文本

spring - 如何在 spring-mvc 中为 springfox(更准确的 springfox-swagger2)设置主机 url?

java - Spring中有哪些获取ApplicationContext对象的方法?

grails - 如何使用 JOSSO 和 Spring Security 从 Grails 应用程序中的 LDAP 获取自定义属性?

java - 我什么时候应该在构造函数内部初始化类字段,什么时候应该在构造函数外部初始化?

java - tomcat 进程超时 120 分钟

java - 为什么这个线程在 Spring 中继续运行?

java - 使用 Spring Security 获取通过 Active Directory 登录的用户的电子邮件地址

java - ExceptionTranslator 的异常不会返回到 flex

java - 将 Perl 脚本中的值返回到 java 表单