使用AD和Apache shiro从LDAP服务器检索全名或显示名称
问题描述:
我试图根据LDAP服务器验证一组凭据,并且能够成功验证它们。现在我试图获取登录到服务器的用户的全名或显示名称。我无法获得相同的结果。作为LDAP概念的新手,我无法想出一种获取用户完整显示名称的方法。一些可以帮我如何让登录的用户的完整的显示名称使用AD和Apache shiro从LDAP服务器检索全名或显示名称
下面是shiro.ini文件正在使用:
[main]
activeDirectoryRealm =
org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
activeDirectoryRealm.systemUsername = adminusername
activeDirectoryRealm.systemPassword = adminpswd
activeDirectoryRealm.searchBase = "OU=User Accounts,DC=dmn,DC=net"
activeDirectoryRealm.url = ldaps://localhost:389
我的Java代码如下:
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
public class ExampleActiveDirectory {
public static final String userName = "myusername";
public static final String password = "mypassword";
public static void main(String[] args)
{
//Factory<SecurityManager> factory = new IniSecurityManagerFactory("N:\\workspace\\LdapAuthentication\\src\\auth.ini");
Factory<SecurityManager> factory = new IniSecurityManagerFactory("N:\\workspace\\LdapAuthentication\\src\\shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
System.out.println("userName is : " +userName);
System.out.println("password is : " +password);
UsernamePasswordToken token = new UsernamePasswordToken(userName,password);
Subject currentUser = SecurityUtils.getSubject();
try
{
//currentUser.login(token) ;
securityManager.login(currentUser,token).isAuthenticated();
System.out.println("We've authenticated! :)");
}
catch (AuthenticationException e)
{
System.out.println("We did not authenticate :(");
e.printStackTrace();
}
}
}
答
发现如下解决方案:
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import org.apache.shiro.web.tags.UserTag;
public class RetrieveUserAttributes {
public static void main(String[] args) {
RetrieveUserAttributes retrieveUserAttributes = new RetrieveUserAttributes();
retrieveUserAttributes.getUserBasicAttributes("username", retrieveUserAttributes.getLdapContext());
}
public LdapContext getLdapContext(){
LdapContext ctx = null;
try{
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_AUTHENTICATION, "Simple");
env.put(Context.SECURITY_PRINCIPAL, "adminusername");
env.put(Context.SECURITY_CREDENTIALS, "adminpswrd");
env.put(Context.PROVIDER_URL, "ldaps://localhost:389");
ctx = new InitialLdapContext(env, null);
System.out.println("Connection Successful.");
}catch(NamingException nex){
System.out.println("LDAP Connection: FAILED");
nex.printStackTrace();
}
return ctx;
}
UserTag getUserBasicAttributes(String username, LdapContext ctx) {
UserTag user=null;
try {
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
String[] attrIDs = { "distinguishedName",
"sn",
"givenname",
"mail",
"telephonenumber"};
constraints.setReturningAttributes(attrIDs);
//First input parameter is search bas, it can be "CN=Users,DC=YourDomain,DC=com"
//Second Attribute can be uid=username
NamingEnumeration answer = ctx.search("DC=domain,DC=com", "sAMAccountName="
+ "username", constraints);
if (answer.hasMore()) {
Attributes attrs = ((SearchResult) answer.next()).getAttributes();
System.out.println("distinguishedName "+ attrs.get("distinguishedName"));
System.out.println("givenname "+ attrs.get("givenname"));
System.out.println("sn "+ attrs.get("sn"));
System.out.println("mail "+ attrs.get("mail"));
System.out.println("telephonenumber "+ attrs.get("telephonenumber"));
}else{
throw new Exception("Invalid User");
}
} catch (Exception ex) {
ex.printStackTrace();
}
return user;
}
}
currentUser.getPrincipal()会给你不便。像用户john doe的j.doe,以防你搜索这个。否则,请提供您希望看到的示例结果。 –
我很喜欢寻找这样的结果:如果我输入用户名为jdoe,代码需要提供输出 - john doe – Arjun
然后我认为你需要从Shiro的ActiveDirectoryRealm类扩展并查看它的方法“getRoleNamesForUser”。正在使用searchBase和searchFilter检索结果,并在AD上执行搜索。在这种类型中,您可以编写自己的方法,使用搜索库和过滤器,然后查找属性“name”而不是“memberOf”。这个属性应该给你你想要的价值。 –