Created
March 14, 2011 14:28
-
-
Save ig0774/869205 to your computer and use it in GitHub Desktop.
An example of integrating Guice and Shiro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Collection; | |
import java.util.LinkedHashSet; | |
import java.util.Set; | |
import java.util.TreeSet; | |
import javax.naming.NamingException; | |
import org.apache.shiro.authc.pam.AuthenticationStrategy; | |
import org.apache.shiro.authc.pam.FirstSuccessfulStrategy; | |
import org.apache.shiro.mgt.DefaultSecurityManager; | |
import org.apache.shiro.mgt.SecurityManager; | |
import org.apache.shiro.realm.Realm; | |
import org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm; | |
import org.apache.shiro.realm.ldap.DefaultLdapContextFactory; | |
import org.apache.shiro.realm.ldap.LdapContextFactory; | |
import com.google.inject.AbstractModule; | |
import com.google.inject.Inject; | |
import com.google.inject.Module; | |
import com.google.inject.Provider; | |
import com.google.inject.ProvisionException; | |
import com.google.inject.name.Named; | |
import com.google.inject.name.Names; | |
public class ActiveDirectoryAuthenticationModule { | |
public final class ActiveDirectoryAuthenticationModuleBuilder { | |
private final Set<String> domainControllers = new TreeSet<String>(); | |
private final Set<String> principalSuffixes = new TreeSet<String>(); | |
private boolean usingSSL = false; | |
private int port = -1; | |
private long sessionTimeout = -1; | |
private String domain = null; | |
private String searchBase = null; | |
private String systemUser = null; | |
private String systemUserPassword = null; | |
private ActiveDirectoryAuthenticationModuleBuilder() {} | |
public ActiveDirectoryAuthenticationModuleBuilder overPort(int port) { | |
if (port < 1 || port > 65536) | |
throw new IllegalArgumentException(String.format("%d is not a valid port number", port)); | |
this.port = port; | |
return this; | |
} | |
public ActiveDirectoryAuthenticationModuleBuilder usingSSL() { | |
usingSSL = true; | |
return this; | |
} | |
public ActiveDirectoryAuthenticationModuleBuilder usingSystemUser(String systemUser) { | |
if (systemUser == null || systemUser.isEmpty()) | |
throw new IllegalArgumentException("System user cannot be null or empty"); | |
this.systemUser = systemUser; | |
return this; | |
} | |
public ActiveDirectoryAuthenticationModuleBuilder withSystemUserPassword(String systemUserPassword) { | |
if (systemUserPassword == null || systemUserPassword.isEmpty()) | |
throw new IllegalArgumentException("System user password cannot be null or empty"); | |
this.systemUserPassword = systemUserPassword; | |
return this; | |
} | |
public ActiveDirectoryAuthenticationModuleBuilder withDomainController(String domainController) { | |
if (domainController == null || domainController.isEmpty()) | |
throw new IllegalArgumentException("Domain controller cannot be null or empty"); | |
domainControllers.add(domainController); | |
return this; | |
} | |
public ActiveDirectoryAuthenticationModuleBuilder withPrincipalSuffix(String suffix) { | |
if (suffix == null || suffix.isEmpty()) | |
throw new IllegalArgumentException("Principal suffix cannot be null or empty"); | |
if (!suffix.startsWith("@")) | |
suffix = "@" + suffix; | |
principalSuffixes.add(suffix); | |
return this; | |
} | |
public ActiveDirectoryAuthenticationModuleBuilder withSearchBase(String searchBase) { | |
if (searchBase == null || searchBase.isEmpty()) | |
throw new IllegalArgumentException("Search base cannot be null or empty"); | |
this.searchBase = searchBase; | |
return this; | |
} | |
public ActiveDirectoryAuthenticationModuleBuilder withSessionTimeout(int sessionTimeoutInMinutes) { | |
// 2562047788015 * 3600000 ~= Long.MAX_VALUE -- prevents value overruns | |
if (sessionTimeoutInMinutes < 1 || sessionTimeoutInMinutes > 2562047788015L) { | |
sessionTimeout = -1; | |
return this; | |
} | |
sessionTimeout = 3600000 * sessionTimeoutInMinutes; | |
return this; | |
} | |
public ActiveDirectoryAuthenticationModuleBuilder withSessionTimeoutInHours(int sessionTimeoutInHours) { | |
return withSessionTimeout(60 * sessionTimeoutInHours); | |
} | |
public Module buildModule() { | |
return new AbstractModule() { | |
@Override | |
protected void configure() { | |
if (systemUser == null || systemUser.isEmpty()) | |
if (systemUserPassword == null || systemUserPassword.isEmpty()) | |
throw new IllegalStateException("System user and password must be supplied to be able to connect to Active Directory"); | |
else | |
throw new IllegalStateException("System user must be supplied in order to connect to Active Directory"); | |
if (systemUserPassword == null || systemUserPassword.isEmpty()) | |
throw new IllegalStateException("System user password must be supplied in order to connect to Active Directory"); | |
bind(SecurityManager.class).toProvider(new Provider<SecurityManager>() { | |
@Inject private Provider<ActiveDirectoryRealm> realmProvider; | |
@Inject private Provider<AuthenticationStrategy> authenticationStrategyProvider; | |
@Inject private Provider<DefaultLdapContextFactory> ldapContextFactoryProvider; | |
@Override | |
public SecurityManager get() { | |
Collection<Realm> realms = new LinkedHashSet<Realm>(); | |
if (!principalSuffixes.isEmpty()) | |
for (String upnSuffix : principalSuffixes) { | |
DefaultLdapContextFactory factory = ldapContextFactoryProvider.get(); | |
factory.setPrincipalSuffix(upnSuffix); | |
ActiveDirectoryRealm realm = realmProvider.get(); | |
realm.setPrincipalSuffix(upnSuffix); | |
realm.setLdapContextFactory(factory); | |
realms.add(realm); | |
} | |
else { | |
LdapContextFactory factory = ldapContextFactoryProvider.get(); | |
ActiveDirectoryRealm realm = realmProvider.get(); | |
realm.setLdapContextFactory(factory); | |
realms.add(realm); | |
} | |
DefaultSecurityManager securityManager = new DefaultSecurityManager(realms); | |
securityManager.setAuthenticationStrategy(authenticationStrategyProvider.get()); | |
if (sessionTimeout > 0) | |
securityManager.setGlobalSessionTimeout(216000000); | |
return securityManager; | |
} | |
}); | |
bind(ActiveDirectoryRealm.class).toProvider(new Provider<ActiveDirectoryRealm>() { | |
@Inject @Named("realmUrl") String url; | |
@Override | |
public ActiveDirectoryRealm get() { | |
ActiveDirectoryRealm realm = new ActiveDirectoryRealm(); | |
if (url != null && !url.isEmpty()) realm.setUrl(url); | |
if (searchBase != null && !searchBase.isEmpty()) realm.setSearchBase(searchBase); | |
realm.setSystemUsername(systemUser); | |
realm.setSystemPassword(systemUserPassword); | |
return realm; | |
} | |
}); | |
bind(DefaultLdapContextFactory.class).toProvider(new Provider<DefaultLdapContextFactory>() { | |
@Inject @Named("realmUrl") String url; | |
@Override | |
public DefaultLdapContextFactory get() { | |
DefaultLdapContextFactory factory = new DefaultLdapContextFactory(); | |
if (url != null && !url.isEmpty()) factory.setUrl(url); | |
if (searchBase != null && !searchBase.isEmpty()) factory.setSearchBase(searchBase); | |
factory.setSystemUsername(systemUser); | |
factory.setSystemPassword(systemUserPassword); | |
return factory; | |
} | |
}); | |
StringBuilder realmUrl = new StringBuilder(); | |
for (String domainController : domainControllers) | |
realmUrl.append(String.format("%s://%s:%d ", usingSSL ? "ldaps" : "ldap", domainController, port > 0 ? port : usingSSL ? 636 : 389)); | |
bindConstant().annotatedWith(Names.named("realmUrl")).to(realmUrl.toString()); | |
} | |
}; | |
} | |
} | |
private ActiveDirectoryAuthenticationModule() {} | |
private ActiveDirectoryAuthenticationModuleBuilder get() { | |
return new ActiveDirectoryAuthenticationModuleBuilder(); | |
} | |
public static ActiveDirectoryAuthenticationModuleBuilder configure() { | |
return new ActiveDirectoryAuthenticationModule().get(); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Basically, to use, configure the realm, e.g.,
And wherever you need it, inject a
SecurityManager
.