Vlad
Vlad

Reputation: 652

Can't authenticate in Spring LDAP

I use win server 2003 with AD. And want to connect via Spring LDAP. An error occurs when I try to connect to 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]
<...>

Code from baeldung.com

LdapClient

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;
    }
}

AppConfig

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

Start point App

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!";
    }

}

AD structure.

AD

Application structure

Application structure

As I understand problem in contextSource. How can I fix?

Any help is appreciated.

Upvotes: 1

Views: 3262

Answers (2)

NaN
NaN

Reputation: 9094

The problem is that you have to define a subdomain in your partitionSuffix:

Original:

ldap.partitionSuffix=dc=GRSU,dc=local

Correct:

ldap.partitionSuffix=ou=Users,dc=GRSU,dc=local

enter image description here

Upvotes: 0

kkflf
kkflf

Reputation: 2570

You have not initiated your spring application. This is the starting point of spring, without initializing nothing work will. You will have to add something like this to your main method:

SpringApplication.run(Application.class, args);

and add the following annotation(If you are using springboot):

@SpringBootApplication

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

Upvotes: 1

Related Questions