added support of multiple fallback suffixes
This commit is contained in:
@ -16,6 +16,8 @@
|
||||
package de.muehlencord.shared.account.shiro.realm;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
@ -39,7 +41,8 @@ public class UserNameActiveDirectoryRealm extends ActiveDirectoryRealm {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(UserNameActiveDirectoryRealm.class);
|
||||
|
||||
private boolean permissionsLookupEnabled = true;
|
||||
protected String fallbackPrincipalSuffix = null;
|
||||
protected List<String> fallbackPrincipalSuffixes = null;
|
||||
private NamingException lastException = null;
|
||||
|
||||
@Override
|
||||
public boolean supports(AuthenticationToken token) {
|
||||
@ -49,69 +52,54 @@ public class UserNameActiveDirectoryRealm extends ActiveDirectoryRealm {
|
||||
@Override
|
||||
protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException {
|
||||
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
|
||||
String userName = upToken.getUsername();
|
||||
LdapContext ctx = lookupUserWithSuffix(upToken, ldapContextFactory, principalSuffix);
|
||||
|
||||
String userName = getUserName(upToken, principalSuffix);
|
||||
LdapContext ctx = null;
|
||||
try {
|
||||
ctx = lookupUser(userName, upToken.getCredentials(), ldapContextFactory);
|
||||
} catch (NamingException ex) {
|
||||
if (fallbackPrincipalSuffix == null) {
|
||||
throw ex;
|
||||
}
|
||||
if (fallbackPrincipalSuffixes != null) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Lookup with principalSuffix {} failed, falling back to {}", principalSuffix, fallbackPrincipalSuffix);
|
||||
LOGGER.debug("Trying the fallbackSuffixes = {}", fallbackPrincipalSuffixes.toString());
|
||||
}
|
||||
} finally {
|
||||
LdapUtils.closeContext(ctx);
|
||||
}
|
||||
|
||||
if ((ctx == null) && (fallbackPrincipalSuffix != null)) {
|
||||
userName = getUserName(upToken, fallbackPrincipalSuffix);
|
||||
try {
|
||||
ctx = lookupUser(userName, upToken.getCredentials(), ldapContextFactory);
|
||||
} catch (NamingException ex) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Lookup with fallbackSuffix {} also failed", fallbackPrincipalSuffix);
|
||||
}
|
||||
throw ex;
|
||||
} finally {
|
||||
LdapUtils.closeContext(ctx);
|
||||
Iterator<String> it = fallbackPrincipalSuffixes.iterator();
|
||||
while ((ctx == null) && (it.hasNext())) {
|
||||
ctx = lookupUserWithSuffix(upToken, ldapContextFactory, it.next());
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx == null) {
|
||||
throw new NamingException("Unknown error authenticationing user "+userName+". Context still null. Check implementation");
|
||||
if (lastException != null) {
|
||||
throw lastException;
|
||||
} else {
|
||||
throw new NamingException("Unknown error authenticationing user " + userName + ". Context still null. Check implementation");
|
||||
}
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("User {} LDAP authenticated", userName);
|
||||
LOGGER.debug("building authentication info");
|
||||
}
|
||||
LOGGER.debug("building authentication info");
|
||||
AuthenticationInfo authInfo = buildAuthenticationInfo(userName, upToken.getPassword());
|
||||
|
||||
LOGGER.debug("authentifaction info created");
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("authentifaction info created");
|
||||
}
|
||||
|
||||
return authInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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}.
|
||||
*
|
||||
* @param principals the principal of the Subject whose account is being
|
||||
* retrieved.
|
||||
* This implementation expects the <tt>principal</tt> argument to be a String username.
|
||||
*
|
||||
* 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.
|
||||
* @throws NamingException if an error occurs when searching the LDAP server.
|
||||
*/
|
||||
@Override
|
||||
protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException {
|
||||
@ -139,12 +127,12 @@ public class UserNameActiveDirectoryRealm extends ActiveDirectoryRealm {
|
||||
this.permissionsLookupEnabled = permissionsLookupEnabled;
|
||||
}
|
||||
|
||||
public String getFallbackPrincipalSuffix() {
|
||||
return fallbackPrincipalSuffix;
|
||||
public List<String> getFallbackPrincipalSuffixes() {
|
||||
return fallbackPrincipalSuffixes;
|
||||
}
|
||||
|
||||
public void setFallbackPrincipalSuffix(String fallbackPrincipalSuffix) {
|
||||
this.fallbackPrincipalSuffix = fallbackPrincipalSuffix;
|
||||
public void setFallbackPrincipalSuffixes(List<String> fallbackPrincipalSuffixes) {
|
||||
this.fallbackPrincipalSuffixes = fallbackPrincipalSuffixes;
|
||||
}
|
||||
|
||||
private String getUserName(UsernamePasswordToken upToken, String suffix) {
|
||||
@ -166,4 +154,26 @@ public class UserNameActiveDirectoryRealm extends ActiveDirectoryRealm {
|
||||
return ldapContextFactory.getLdapContext(userName, credentials);
|
||||
}
|
||||
|
||||
private LdapContext lookupUserWithSuffix(UsernamePasswordToken upToken, LdapContextFactory ldapContextFactory, String currentSuffix) {
|
||||
String userName = getUserName(upToken, currentSuffix);
|
||||
LdapContext ctx = null;
|
||||
try {
|
||||
ctx = lookupUser(userName, upToken.getCredentials(), ldapContextFactory);
|
||||
} catch (NamingException ex) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Lookup with suffix {} failed", currentSuffix);
|
||||
}
|
||||
if (LOGGER.isTraceEnabled()) {
|
||||
LOGGER.error(ex.getMessage());
|
||||
LOGGER.trace("Detailed stacktrace", new Object[]{ex});
|
||||
}
|
||||
|
||||
lastException = ex;
|
||||
return null;
|
||||
} finally {
|
||||
LdapUtils.closeContext(ctx);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user