首页  编辑  

SpringBoot集成AD LDAP认证

Tags: /Java/   Date Created:

SpringBoot集成 AD认证

在SpringBoot中集成AD认证,有两种模式直接认证模式和Bind模式。

  • 直接认证模式 - 直接把用户在登录界面输入的用户名和密码,发送给域控服务器进行认证
  • Bind模式 - App内部有一个Bind用户,该用户先连接AD域服务器,然后把用户在界面上输入的用户名和密码,通过Bind用户发送给服务器查询进行认证。

直接认证模式

直接认证模式,只需要配置AD的URL即可,无需引入额外的依赖包。

直接认证模式,不推荐使用,因为会存在JNDI注入风险,建议使用Bind模式进行认证。
  1. 首先在 application.properties/yml 中配置 ad.url
    ad.url=ldap://www.abc.com:389
  1. 认证代码
@PostMapping("/login")
public AjaxResult<Object> login(@RequestBody UserVO user) {
    try {
        Hashtable<String, String> hashEnv = new Hashtable<>();
        hashEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        hashEnv.put(Context.PROVIDER_URL, Util.getProperty("ad.url", "ldap://www.abc.com:389"));
        hashEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
        hashEnv.put(Context.REFERRAL, "follow");
        hashEnv.put(Context.SECURITY_PRINCIPAL, user.getUsername());
        hashEnv.put(Context.SECURITY_CREDENTIALS, user.getPassword());
        hashEnv.put("com.sun.jndi.ldap.connect.timeout", "3000");
        hashEnv.put("java.naming.ldap.attributes.binary", "objectSid");
        DirContext ctx = new InitialDirContext(hashEnv);
        ctx.close();
        log.debug("AD Login success");
        return AjaxResult.ok(null, "Login Success");
    } catch (AuthenticationException e) {
        String s = "AD authorization failed: " + e.getMessage();
        log.error(s);
        return AjaxResult.fail(s);
    } catch (CommunicationException e) {
        String s = "AD connection failed: " + e.getMessage();
        log.error(s);
        return AjaxResult.fail(s);
    } catch (Exception e) {
        String s = "unknown error: " + e.getMessage();
        log.error(s);
        return AjaxResult.fail(s);
    }
}
  1. 客户端Post
    post url: /login
    post body:
{
    "username": "username",
    "password": "password"
}
如果提示不正确,可以试试在用户名后面添加域后缀 @abc.com 后缀,具体询问管理员。

Bind模式

Bind模式,通过 LdapTemplate 组件来进行验证。需要引入额外的依赖。Bind模式用户名无需添加域后缀,因为配置中已经指定了base。

  1. 首先引入依赖,修改 pom.xml ,添加依赖,然后 Maven Sync:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>
  1. 修改 application.properties/yml,增加SpringBoot AD自动配置,记得修改对应的Bind用户的用户名和密码:
spring.ldap.urls=ldap://www.abc.com:389
spring.ldap.base=DC=abc,DC=com
spring.ldap.username=bind_username@abc.com
spring.ldap.password=bind_user_password
  1. 认证代码
@Autowired
private LdapTemplate ldapTemplate;

@PostMapping("/login")
public AjaxResult<Object> login(@RequestBody UserVO user) {
    try {
        DirContext ctx = ldapTemplate.getContextSource().getContext(user.getUsername(), user.getPassword());
        EqualsFilter filter = new EqualsFilter("sAMAccountName", user.getUsername());
        ldapTemplate.setIgnorePartialResultException(true);
        boolean flag = ldapTemplate.authenticate("", filter.toString(), user.getPassword());
        if (flag) {
            return AjaxResult.ok(true, "login success");
        } else {
            return AjaxResult.fail("login failed");
        }
    } catch (Exception e) {
        return AjaxResult.fail(e.getMessage());
    }
}
  1. 客户端Post
    post url: /login
    post body:
{
    "username": "username",
    "password": "password"
}