Skip to content

Instantly share code, notes, and snippets.

@ig0774
Created March 14, 2011 14:28
Show Gist options
  • Save ig0774/869205 to your computer and use it in GitHub Desktop.
Save ig0774/869205 to your computer and use it in GitHub Desktop.
An example of integrating Guice and Shiro
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();
};
}
@ig0774
Copy link
Author

ig0774 commented Mar 14, 2011

Basically, to use, configure the realm, e.g.,

 Module adModule = ActiveDirectoryAuthenticationModule.configure()
    .withDomainController("dc1.fabrikam.com")
    .withSystemUser("[email protected]")
    .withSystemUserPassword("secure")
    .buildModule();

And wherever you need it, inject a SecurityManager.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment