Java如何对接支持短信双因素认证的LDAP服务并提交验证码
解决方案
不同LDAP服务厂商的短信二次认证实现规则有差异,以下为业界最通用的实现方案,若不匹配你的LDAP服务配置可参考厂商文档调整凭证拼接逻辑。
首先修复原代码的已知问题:原代码中Attribute dnAttr = attrs.get("distinguishedName");行的attrs未初始化,需先通过Attributes attrs = result.getAttributes();获取属性集。
方案1:密码+验证码拼接提交(90%以上场景适用)
大部分LDAP服务开启短信MFA后,要求将用户密码与收到的短信验证码直接拼接作为身份凭证提交,修改后代码如下:
FileReader reader = new FileReader(file); Properties p = new Properties(); p.load(reader); DirContext ctx = new InitialDirContext(p); SearchControls controls = new SearchControls(); controls.setSearchScope(SearchControls.SUBTREE_SCOPE); controls.setCountLimit(1); controls.setTimeLimit(5000); String searchString = "(sAMAccountName=" + p.getProperty("USERNAME") + ")"; NamingEnumeration<SearchResult> results = ctx.search("", searchString, controls); if (results.hasMore()) { SearchResult result = (SearchResult) results.next(); // 修复原代码未获取attrs的bug Attributes attrs = result.getAttributes(); Attribute dnAttr = attrs.get("distinguishedName"); String dn = (String) dnAttr.get(); p.put(Context.SECURITY_PRINCIPAL, dn); System.out.print("password: "); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String passwd = br.readLine(); // 新增:获取用户输入的短信验证码 System.out.print("SMS verification code: "); String smsCode = br.readLine(); // 拼接密码和验证码作为凭证,部分厂商要求用特殊分隔符拼接,比如密码+#+验证码,可按需调整 String fullCredential = passwd + smsCode; p.put(Context.SECURITY_CREDENTIALS, fullCredential); new InitialDirContext(p); // 验证失败会抛出异常 System.out.println("Login successful"); }
如果你的LDAP厂商要求用特殊分隔符拼接凭证,比如密码和验证码之间加#,将拼接逻辑修改为passwd + "#" + smsCode即可。
方案2:通过LDAP自定义属性传递验证码
如果你的LDAP服务要求单独传递验证码,不需要和密码拼接,可直接在Properties中添加厂商指定的验证码属性即可,示例如下:
// 假设厂商指定验证码的属性键为ldap.mfa.code p.put("ldap.mfa.code", smsCode); p.put(Context.SECURITY_CREDENTIALS, passwd);
内容的提问来源于stack exchange,提问作者zackhalil
相关产品推荐
相关产品推荐

