Не удается пройти аутентификацию в Spring LDAP

Я использую Win Server 2003 с AD. И хотите подключиться через Spring LDAP. При попытке подключиться к http://localhost:8090/ возникает ошибка:

2017-05-19 22:48:46.768 ERROR 18868 --- [nio-8090-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause

java.lang.NullPointerException: null
    at hello.ldap.client.LdapClient.authenticate(LdapClient.java:26) ~[classes/:na]
    at hello.HelloController.index(HelloController.java:13) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
<...>

Код с сайта baeldung.com

Клиент Ldap

package hello.ldap.client;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.ldap.core.*;
import org.springframework.ldap.support.LdapNameBuilder;

import javax.naming.Name;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.List;

public class LdapClient {

    @Autowired
    private Environment env;

    @Autowired
    private ContextSource contextSource;

    @Autowired
    private LdapTemplate ldapTemplate;

    public void authenticate(final String username, final String password) {
        contextSource.getContext("cn=" + username + ",cn=users," + env.getRequiredProperty("ldap.partitionSuffix"), password);
    }

    public List<String> search(final String username) {
        return ldapTemplate.search(
          "cn=users",
          "cn=" + username,
          (AttributesMapper<String>) attrs -> (String) attrs
          .get("cn")
          .get());
    }

    public void create(final String username, final String password) {
        Name dn = LdapNameBuilder
          .newInstance()
          .add("cn", "users")
          .add("cn", username)
          .build();
        DirContextAdapter context = new DirContextAdapter(dn);

        context.setAttributeValues("objectclass", new String[] { "top", "person", "organizationalPerson", "inetOrgPerson" });
        context.setAttributeValue("cn", username);
        context.setAttributeValue("sn", username);
        context.setAttributeValue("userPassword", digestSHA(password));

        ldapTemplate.bind(context);
    }

    public void modify(final String username, final String password) {
        Name dn = LdapNameBuilder
          .newInstance()
          .add("ou", "users")
          .add("cn", username)
          .build();
        DirContextOperations context = ldapTemplate.lookupContext(dn);

        context.setAttributeValues("objectclass", new String[] { "top", "person", "organizationalPerson", "inetOrgPerson" });
        context.setAttributeValue("cn", username);
        context.setAttributeValue("sn", username);
        context.setAttributeValue("userPassword", digestSHA(password));

        ldapTemplate.modifyAttributes(context);
    }

    private String digestSHA(final String password) {
        String base64;
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA");
            digest.update(password.getBytes());
            base64 = Base64
              .getEncoder()
              .encodeToString(digest.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        return "{SHA}" + base64;
    }
}

Конфигурация приложения

package hello.ldap.javaconfig;

import hello.ldap.client.LdapClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;

@Configuration
@PropertySource("classpath:application.properties")
@ComponentScan(basePackages = { "hello.ldap.*" })
@Profile("default")
public class AppConfig {

    @Autowired
    private Environment env;

    @Bean
    public LdapContextSource contextSource() {
        LdapContextSource contextSource = new LdapContextSource();
        contextSource.setUrl(env.getRequiredProperty("ldap.url"));
        contextSource.setBase(env.getRequiredProperty("ldap.partitionSuffix"));
        contextSource.setUserDn(env.getRequiredProperty("ldap.principal"));
        contextSource.setPassword(env.getRequiredProperty("ldap.password"));
        return contextSource;
    }

    @Bean
    public LdapTemplate ldapTemplate() {
        return new LdapTemplate(contextSource());
    }

    @Bean
    public LdapClient ldapClient() {
        return new LdapClient();
    }

}

application.properties

server.port = 8090
ldap.partitionSuffix=dc=GRSU,dc=local
ldap.partition=GRSU
ldap.principal=cn=Jack Wood,cn=users
ldap.password=1234
ldap.port=389
ldap.url=ldap://192.168.56.101

Начальная точка Приложение

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

HelloController

package hello;

import hello.ldap.client.LdapClient;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
public class HelloController {

    @RequestMapping("/")
    public String index() {
        LdapClient ldapClient = new LdapClient();
        ldapClient.authenticate("Jack Wood", "1234");
        return "Greetings from Spring Boot!";
    }

}

Структура АД.

ОБЪЯВЛЕНИЕ

Структура приложения

Структура приложения

Как я понимаю проблема в contextSource. Как я могу исправить?

Любая помощь приветствуется.


person Woland    schedule 19.05.2017    source источник
comment
Лично я бы не стал доверять baeldung как действительному учебному сайту. Их практика часто немного отрывочна. Это мое собственное мнение.   -  person kkflf    schedule 19.05.2017
comment
@kkflf Какой учебник по Spring LDAP вы можете посоветовать?   -  person Woland    schedule 19.05.2017


Ответы (1)


Вы не инициировали свое весеннее приложение. Это отправная точка весны, без инициализации ничего работать не будет. Вам нужно будет добавить что-то вроде этого в ваш основной метод:

SpringApplication.run(Application.class, args);

и добавьте следующую аннотацию (если вы используете Springboot):

@SpringBootApplication

https://spring.io/guides/gs/spring-boot/

person kkflf    schedule 19.05.2017
comment
Спасибо за ваш комментарий. Пробовал исправить, но ошибка осталась. Обновил тему, посмотрите, пожалуйста. - person Woland; 19.05.2017
comment
Вместо этого вам следует просмотреть это руководство: spring.io/guides/gs/authenticating-ldap - person kkflf; 19.05.2017
comment
Я посмотрю на это завтра. - person kkflf; 21.05.2017