java集成ldap验证用户名和密码

前言

最近一个项目需要用到ldap验证,特此记录一下过程。
基本上的API的调用,但是有几个问题点还是要说明一下。

首先,先准备好四个属性:

url= ldap://127.0.0.1:port
base= xxx
username= xxx
password= xxx

连接LDAP

public static LdapContext connetldap() throws Exception {
        // 连接Ldap需要的信息
        String ldapFactory = "com.sun.jndi.ldap.LdapCtxFactory";
        String ldapUrl = "ldap://xxx";// url
        String ldapAccount = "xxx"; // 用户名
        String ldapPwd = "xxx";//密码
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, ldapFactory);
        // LDAP server
        env.put(Context.PROVIDER_URL, ldapUrl);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, ldapAccount);
        env.put(Context.SECURITY_CREDENTIALS, ldapPwd);
        ctx = new InitialLdapContext(env, connCtls);
        return ctx;
    }

查找信息

连接查找过程可能会出现各种问题,这里推荐两篇博客:
ldap查询语法
LDAP的特定错误

public static void search() throws Exception {
        LdapContext ctx = connetldap();
        // 设置过滤条件
        String filter = "(mail=*)";
        // 限制要查询的字段内容
        String[] attrPersonArray = { "uid", "userPassword", "displayName", "cn", "sn", "mail", "description"};
        SearchControls searchControls = new SearchControls();
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        // 设置将被返回的Attribute
        searchControls.setReturningAttributes(attrPersonArray);
        // 三个参数分别为:
        // 上下文;
        // 要搜索的属性,如果为空或 null,则返回目标上下文中的所有对象;
        // 控制搜索的搜索控件,如果为 null,则使用默认的搜索控件
        NamingEnumeration<SearchResult> answer = ctx.search("你的base", filter, searchControls);
        // 输出查到的数据
        while (answer.hasMore()) {
            SearchResult result = answer.next();
            NamingEnumeration<? extends Attribute> all = result.getAttributes().getAll();
            while (all.hasMore()) {
                Attribute attr = all.next();
                System.out.println(attr.getID() + "=" + attr.get());
            }
            System.out.println("============");
        }
    }

校验用户名密码

private static String getUserDn(String user) throws Exception{
        StringBuilder userDn = new StringBuilder();
        connetldap();
        try {
            SearchControls constraints = new SearchControls();
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
            NamingEnumeration<SearchResult> en = ctx.search("你的base", "查询条件", constraints);
            if (en == null || !en.hasMoreElements()) {
                System.out.println("未找到该用户");
            }
            // maybe more than one element
            while (en != null && en.hasMoreElements()) {
                SearchResult obj = en.nextElement();
                if (obj != null) {
                    userDn.append(obj.getName());
                    userDn.append("," + "你的base");
                } else {
                    System.out.println(obj);
                }
            }
        } catch (Exception e) {
            System.out.println("查找用户时产生异常。");
            e.printStackTrace();
        }

        return userDn.toString();
    }
public static boolean authenricate(String user, String password) throws Exception{
        boolean valide = false;
        String userDn = getUserDn(user);
        try {
            ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDn);
            ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
            ctx.reconnect(connCtls);
            System.out.println(userDn + " 验证通过");
            valide = true;
        } catch (AuthenticationException e) {
            System.out.println(userDn + " 验证失败");
            System.out.println(e.toString());
        } catch (NamingException e) {
            System.out.println(userDn + " 验证失败");
        }
        return valide;
    }
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
LDAP (Lightweight Directory Access Protocol) 是一种基于 TCP/IP 协议的轻量级目录访问协议,通常用于企业级应用程序中的用户身份验证和授权。Spring Boot 提供了对 LDAP 认证的支持,可以轻松地将其集成到应用程序中。 下面是一个基本的 LDAP 认证示例: 1. 添加依赖 在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-ldap</artifactId> </dependency> ``` 2. 配置 application.yml 在 application.yml 文件中添加以下配置: ```yaml spring: ldap: urls: ldap://localhost:389 base: dc=example,dc=com user-search-base: ou=people user-search-filter: (uid={0}) group-search-base: ou=groups group-search-filter: (uniqueMember={0}) group-role-attribute: cn manager-dn: cn=admin,dc=example,dc=com manager-password: admin ``` 这里配置了 LDAP 服务器的 URL、基础 DN、用户搜索基础 DN、用户搜索过滤器、组搜索基础 DN、组搜索过滤器、组角色属性、管理员 DN 和管理员密码。 3. 创建 UserDetailsServiceImpl 类 创建一个实现 UserDetailsService 接口的类,用于从 LDAP 中加载用户详细信息。 ```java @Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private LdapTemplate ldapTemplate; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { List<UserDetails> users = ldapTemplate.search( LdapQueryBuilder.query().where("uid").is(username), (AttributesMapper<UserDetails>) attrs -> { String password = (String) attrs.get("userPassword").get(); List<GrantedAuthority> authorities = new ArrayList<>(); attrs.getAll().stream() .filter(attr -> attr.getID().startsWith("memberOf")) .flatMap(attr -> LdapUtils.convertValueToList(attr).stream()) .forEach(groupDn -> { String groupName = LdapUtils.getRdnValue(new LdapName(groupDn)).toString(); authorities.add(new SimpleGrantedAuthority("ROLE_" + groupName)); }); return new User(username, password, authorities); }); if (users.isEmpty()) { throw new UsernameNotFoundException("User not found"); } return users.get(0); } } ``` 这里使用 LdapTemplate 搜索 LDAP 目录,将查询结果转换为 UserDetails 对象,并返回该对象。 4. 创建 WebSecurityConfig 类 创建一个继承 WebSecurityConfigurerAdapter 的类,用于配置 Spring Security。 ```java @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .defaultSuccessURL("/") .permitAll() .and() .logout() .logoutUrl("/logout") .permitAll(); } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } } ``` 这里配置了 HTTP 访问策略和登录、注销页面的 URL,并将 UserDetailsService 注册到 AuthenticationManagerBuilder 中。 5. 创建登录和注销页面 创建一个登录页面和一个注销页面,用于在浏览器中进行身份验证和注销。例如: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Login</title> </head> <body> <h1>Login</h1> <form action="/login" method="post"> <label for="username">Username:</label> <input type="text" id="username" name="username"><br><br> <label for="password">Password:</label> <input type="password" id="password" name="password"><br><br> <input type="submit" value="Login"> </form> </body> </html> ``` ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Logout</title> </head> <body> <h1>Logout</h1> <form action="/logout" method="post"> <input type="submit" value="Logout"> </form> </body> </html> ``` 6. 运行应用程序 现在可以启动应用程序并在浏览器中访问它。输入正确的用户名密码,应该可以成功登录。登录后,可以访问受保护的资源。注销后,应该不能访问受保护的资源。 以上是一个基本的 LDAP 认证示例,可以根据实际需求进行修改和扩展。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值