【问题标题】:Can't authenticate in Spring LDAP无法在 Spring LDAP 中进行身份验证
【发布时间】:2017-05-19 12:41:52
【问题描述】:

我使用带有 AD 的 win server 2003。并希望通过 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的代码

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

起点 应用

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 中的问题。我该如何解决?

感谢任何帮助。

【问题讨论】:

  • 我个人不相信 baeldung 作为一个有效的教程网站。他们的做法往往有点粗略。这是我个人的看法。
  • @kkflf 你能推荐什么 Spring LDAP 教程?

标签: java spring authentication active-directory spring-ldap


【解决方案1】:

您尚未启动您的 spring 应用程序。这是 spring 的起点,没有初始化任何工作都不会。 您必须在 main 方法中添加类似这样的内容:

SpringApplication.run(Application.class, args);

并添加以下注释(如果您使用的是springboot):

@SpringBootApplication

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

【讨论】:

  • 感谢您的评论。我试图修复它,但错误仍然存​​在。更新了话题,请看。
  • 你应该看看这个教程:spring.io/guides/gs/authenticating-ldap
  • 也许你可以帮助topic
  • 我明天去看看。
猜你喜欢
  • 2015-10-30
  • 2011-02-01
  • 2018-08-09
  • 1970-01-01
  • 2021-09-02
  • 1970-01-01
  • 2012-11-18
  • 2020-08-07
  • 2019-08-30
相关资源
最近更新 更多