从LDAP获取当前用户所属组与角色的问题排查
Hey there! I see the issue right away—your current LDAP search filter is pulling all groups instead of just the ones that include the logged-in user (Bob). Let's fix that.
The Problem with Your Filter
Your current filter:
"(&(objectclass=groupOfUniqueNames))"
This only filters for entries that are groupOfUniqueNames objects, but it doesn't check if Bob is a member of those groups. In your LDAP setup, groups use the uniqueMember attribute to store their members, so we need to add that condition to the filter.
The Correct Filter
We need to modify the filter to include Bob's full DN (distinguished name) as a value in the uniqueMember attribute:
"(&(objectclass=groupOfUniqueNames)(uniqueMember=uid=bob,ou=people,dc=springframework,dc=org))"
If you want to make this dynamic (so it works for any logged-in user instead of hardcoding Bob's DN), you can extract the principal from your environment:
String userDn = environment.get(Context.SECURITY_PRINCIPAL); String filter = "(&(objectclass=groupOfUniqueNames)(uniqueMember=" + userDn + "))";
Modified Code Example
Here's your updated run method with the fix, plus some extra improvements (like handling missing attributes and cleaner value extraction):
@Override public void run(String... args) throws Exception { String searchbase = "dc=springframework,dc=org"; Hashtable<String, String> environment = new Hashtable<>(); environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); environment.put(Context.PROVIDER_URL, "ldap://localhost:8389"); environment.put(Context.SECURITY_AUTHENTICATION, "simple"); environment.put(Context.SECURITY_PRINCIPAL, "uid=bob,ou=people,dc=springframework,dc=org"); environment.put(Context.SECURITY_CREDENTIALS, "bobspassword"); // Connect to LDAP server (try-with-resources auto-closes the context) try (LdapContext ctx = new InitialLdapContext(environment, null)) { System.out.println("Connected!"); SearchControls controls = new SearchControls(); String[] attributes = {"cn", "ou"}; controls.setReturningAttributes(attributes); controls.setSearchScope(SearchControls.SUBTREE_SCOPE); // Dynamic filter using the logged-in user's DN String userDn = environment.get(Context.SECURITY_PRINCIPAL); String filter = "(&(objectclass=groupOfUniqueNames)(uniqueMember=" + userDn + "))"; NamingEnumeration<?> answer = ctx.search(searchbase, filter, controls); while (answer.hasMore()) { SearchResult rslt = (SearchResult) answer.next(); Attributes attrs = rslt.getAttributes(); // Safely get CN attribute (avoid null pointer exceptions) Attribute cnAttr = attrs.get("cn"); if (cnAttr != null) { String groupName = cnAttr.get().toString(); System.out.println("Group Name: " + groupName); } // Safely get OU attribute (some groups might not have this field) Attribute ouAttr = attrs.get("ou"); if (ouAttr != null) { String groupOu = ouAttr.get().toString(); System.out.println("Group OU: " + groupOu); } System.out.println("---"); } System.out.println("Listed all groups for the current user!"); } catch (NamingException e) { e.printStackTrace(); } System.exit(0); }
Key Improvements
- Dynamic Filter: Uses the logged-in user's DN from the environment, so you don't have to hardcode user-specific values.
- Null Safety: Checks if attributes like
ouexist before accessing them (since not all groups might have an OU attribute defined). - Try-with-resources: Automatically closes the
LdapContextto avoid resource leaks.
Testing the Fix
When you run this code, it should only return the developers and managers groups (since Bob is a member of both), and exclude submanagers (which only includes Ben).
内容的提问来源于stack exchange,提问作者art

