private String findUserDN(final String userName, final LdapContextFactory ldapContextFactory) { LdapContext systemLdapCtx = null; try { systemLdapCtx = ldapContextFactory.getSystemLdapContext(); final NamingEnumeration<SearchResult> usersFound = systemLdapCtx.search(searchBase, dnSearchFilter.replace(USERDN_SUBSTITUTION_TOKEN, userName), SUBTREE_SCOPE); return usersFound.hasMore() ? usersFound.next().getNameInNamespace() : null; } catch (final AuthenticationException ex) { log.info("LDAP authentication exception='{}'", ex.getLocalizedMessage()); throw new IllegalArgumentException(ex); } catch (final NamingException e) { log.info("LDAP exception='{}'", e.getLocalizedMessage()); throw new IllegalArgumentException(e); } finally { LdapUtils.closeContext(systemLdapCtx); } }
ctx = ldapContextFactory.getLdapContext(principal, credentials);
ldapContextFactory.getSystemLdapContext(); String[] attrs = {"cn"}; SearchControls searchCtls = new SearchControls( SearchControls.SUBTREE_SCOPE, 1, 0, attrs, false, false ); LdapContext ctx2 = ldapContextFactory.getLdapContext( loginUser, credentials ); LdapUtils.closeContext( ctx2 );
private Set<String> findLDAPGroupsForUser(final PrincipalCollection principals, final LdapContextFactory ldapContextFactory) throws NamingException { final String username = (String) getAvailablePrincipal(principals); LdapContext systemLdapCtx = null; try { systemLdapCtx = ldapContextFactory.getSystemLdapContext(); return findLDAPGroupsForUser(username, systemLdapCtx); } catch (final AuthenticationException ex) { log.info("LDAP authentication exception='{}'", ex.getLocalizedMessage()); return ImmutableSet.<String>of(); } finally { LdapUtils.closeContext(systemLdapCtx); } }
/** * Builds an {@link AuthenticationInfo} object by querying the active directory LDAP context for the * specified username. This method binds to the LDAP server using the provided username and password - * which if successful, indicates that the password is correct. * <p/> * This method can be overridden by subclasses to query the LDAP server in a more complex way. * * @param token the authentication token provided by the user. * @param ldapContextFactory the factory used to build connections to the LDAP server. * @return an {@link AuthenticationInfo} instance containing information retrieved from LDAP. * @throws NamingException if any LDAP errors occur during the search. */ protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; // Binds using the username and password provided by the user. LdapContext ctx = null; try { ctx = ldapContextFactory.getLdapContext(upToken.getUsername(), String.valueOf(upToken.getPassword())); } finally { LdapUtils.closeContext(ctx); } return buildAuthenticationInfo(upToken.getUsername(), upToken.getPassword()); }
/** * Builds an {@link org.apache.shiro.authz.AuthorizationInfo} object by querying the active directory LDAP context for the * groups that a user is a member of. The groups are then translated to role names by using the * configured {@link #groupRolesMap}. * <p/> * This implementation expects the <tt>principal</tt> argument to be a String username. * <p/> * Subclasses can override this method to determine authorization data (roles, permissions, etc) in a more * complex way. Note that this default implementation does not support permissions, only roles. * * @param principals the principal of the Subject whose account is being retrieved. * @param ldapContextFactory the factory used to create LDAP connections. * @return the AuthorizationInfo for the given Subject principal. * @throws NamingException if an error occurs when searching the LDAP server. */ protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException { String username = (String) getAvailablePrincipal(principals); // Perform context search LdapContext ldapContext = ldapContextFactory.getSystemLdapContext(); Set<String> roleNames; try { roleNames = getRoleNamesForUser(username, ldapContext); } finally { LdapUtils.closeContext(ldapContext); } return buildAuthorizationInfo(roleNames); }
@Test public void testUserDnTemplateSubstitution() throws NamingException { realm.setUserDnTemplate("uid={0},ou=users,dc=mycompany,dc=com"); LdapContextFactory factory = createMock(LdapContextFactory.class); realm.setContextFactory(factory); Object expectedPrincipal = "uid=jsmith,ou=users,dc=mycompany,dc=com"; expect(factory.getLdapContext(eq(expectedPrincipal), isA(Object.class))).andReturn(createNiceMock(LdapContext.class)); replay(factory); realm.getAuthenticationInfo(new UsernamePasswordToken("jsmith", "secret") ); verify(factory); }
/** * Builds an {@link org.apache.shiro.authz.AuthorizationInfo} object by querying the active directory LDAP context for the * groups that a user is a member of. The groups are then translated to role names by using the * configured {@link #groupRolesMap}. * <p/> * This implementation expects the <tt>principal</tt> argument to be a String username. * <p/> * Subclasses can override this method to determine authorization data (roles, permissions, etc) in a more * complex way. Note that this default implementation does not support permissions, only roles. * * @param principals the principal of the Subject whose account is being retrieved. * @param ldapContextFactory the factory used to create LDAP connections. * @return the AuthorizationInfo for the given Subject principal. * @throws NamingException if an error occurs when searching the LDAP server. */ protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException { String username = (String) getAvailablePrincipal(principals); // Perform context search LdapContext ldapContext = ldapContextFactory.getSystemLdapContext(); Set<String> roleNames; try { roleNames = getRoleNamesForUser(username, ldapContext); } finally { LdapUtils.closeContext(ldapContext); } return buildAuthorizationInfo(roleNames); }
@Test(expected= AuthenticationException.class) public void testGetAuthenticationInfoNamingException() throws NamingException { realm.setUserDnTemplate("uid={0},ou=users,dc=mycompany,dc=com"); LdapContextFactory factory = createMock(LdapContextFactory.class); realm.setContextFactory(factory); expect(factory.getLdapContext(isA(Object.class), isA(Object.class))) .andThrow(new NamingException("Communication error.")); replay(factory); realm.getAuthenticationInfo(new UsernamePasswordToken("jsmith", "secret") ); }
@Override public LdapContext getSystemLdapContext() throws NamingException { return delegate.getSystemLdapContext(); }
/** * This test simulates that if a non-String principal (i.e. not a username) is passed as the LDAP principal, that * it is not altered into a User DN and is passed as-is. This will allow principals to be things like X.509 * certificates as well instead of only strings. * * @throws NamingException not thrown */ @Test public void testGetAuthenticationInfoNonSimpleToken() throws NamingException { realm.setUserDnTemplate("uid={0},ou=users,dc=mycompany,dc=com"); LdapContextFactory factory = createMock(LdapContextFactory.class); realm.setContextFactory(factory); final UUID userId = UUID.randomUUID(); //ensure the userId is passed as-is: expect(factory.getLdapContext(eq(userId), isA(Object.class))).andReturn(createNiceMock(LdapContext.class)); replay(factory); realm.getAuthenticationInfo(new AuthenticationToken() { public Object getPrincipal() { return userId; } public Object getCredentials() { return "secret"; } }); verify(factory); }
public LdapPrincipal getPrincipal(String username) throws NamingException { LdapContext ctx = null; try { ctx = ctxFactory.getSystemLdapContext(); return getPrincipal(ctx, username); } catch (Exception e) { log.warn("getPrincipal ['{}'] -> error while retrieving LDAP data: {}", username, e.getMessage(), e); throw e; } finally { LdapUtils.closeContext(ctx); } }
@Test(expected= AuthenticationException.class) public void testGetAuthenticationInfoNamingAuthenticationException() throws NamingException { realm.setUserDnTemplate("uid={0},ou=users,dc=mycompany,dc=com"); LdapContextFactory factory = createMock(LdapContextFactory.class); realm.setContextFactory(factory); expect(factory.getLdapContext(isA(Object.class), isA(Object.class))) .andThrow(new javax.naming.AuthenticationException("LDAP Authentication failed.")); replay(factory); realm.getAuthenticationInfo(new UsernamePasswordToken("jsmith", "secret") ); }
private Set<String> getRoles(final PrincipalCollection principals, final LdapContextFactory ldapContextFactory) throws NamingException { final String username = (String) getAvailablePrincipal(principals); LdapContext systemLdapCtx = null; try { systemLdapCtx = ldapContextFactory.getSystemLdapContext(); return rolesFor(username, systemLdapCtx); } catch (AuthenticationException ex) { // principal was not authenticated on LDAP return Collections.emptySet(); } finally { LdapUtils.closeContext(systemLdapCtx); } }
ctx = ldapContextFactory.getLdapContext(principal, credentials);
private String findUserDN(final String userName, final LdapContextFactory ldapContextFactory) { LdapContext systemLdapCtx = null; try { systemLdapCtx = ldapContextFactory.getSystemLdapContext(); final NamingEnumeration<SearchResult> usersFound = systemLdapCtx.search(searchBase, dnSearchFilter.replace(USERDN_SUBSTITUTION_TOKEN, userName), SUBTREE_SCOPE); return usersFound.hasMore() ? usersFound.next().getNameInNamespace() : null; } catch (final AuthenticationException ex) { log.info("LDAP authentication exception='{}'", ex.getLocalizedMessage()); throw new IllegalArgumentException(ex); } catch (final NamingException e) { log.info("LDAP exception='{}'", e.getLocalizedMessage()); throw new IllegalArgumentException(e); } finally { LdapUtils.closeContext(systemLdapCtx); } }
/** * Builds an {@link AuthenticationInfo} object by querying the active directory LDAP context for the * specified username. This method binds to the LDAP server using the provided username and password - * which if successful, indicates that the password is correct. * <p/> * This method can be overridden by subclasses to query the LDAP server in a more complex way. * * @param token the authentication token provided by the user. * @param ldapContextFactory the factory used to build connections to the LDAP server. * @return an {@link AuthenticationInfo} instance containing information retrieved from LDAP. * @throws NamingException if any LDAP errors occur during the search. */ protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; // Binds using the username and password provided by the user. LdapContext ctx = null; try { ctx = ldapContextFactory.getLdapContext(upToken.getUsername(), String.valueOf(upToken.getPassword())); } finally { LdapUtils.closeContext(ctx); } return buildAuthenticationInfo(upToken.getUsername(), upToken.getPassword()); }
LdapContext ldapContext = ldapContextFactory.getSystemLdapContext();
@Override public LdapContext getLdapContext(Object principal, Object credentials) throws NamingException { return delegate.getLdapContext(principal, credentials); } }
private Set<String> findLDAPGroupsForUser(final PrincipalCollection principals, final LdapContextFactory ldapContextFactory) throws NamingException { final String username = (String) getAvailablePrincipal(principals); LdapContext systemLdapCtx = null; try { systemLdapCtx = ldapContextFactory.getSystemLdapContext(); return findLDAPGroupsForUser(username, systemLdapCtx); } catch (AuthenticationException ex) { log.info("LDAP authentication exception: " + ex.getLocalizedMessage()); return ImmutableSet.<String>of(); } finally { LdapUtils.closeContext(systemLdapCtx); } }