diff --git a/core/src/main/java/hudson/security/LDAPSecurityRealm.java b/core/src/main/java/hudson/security/LDAPSecurityRealm.java index bbfb6af..338a9e1 100644 --- a/core/src/main/java/hudson/security/LDAPSecurityRealm.java +++ b/core/src/main/java/hudson/security/LDAPSecurityRealm.java @@ -5,7 +5,10 @@ import org.acegisecurity.MockAuthenticationManager; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.DataBoundConstructor; import hudson.model.Descriptor; +import hudson.model.Hudson; +import hudson.util.spring.BeanBuilder; import net.sf.json.JSONObject; +import groovy.lang.Binding; /** * {@link SecurityRealm} implementation that uses LDAP for authentication. @@ -13,6 +16,10 @@ import net.sf.json.JSONObject; * @author Kohsuke Kawaguchi */ public class LDAPSecurityRealm extends SecurityRealm { + /** + * LDAP to connect to, and root DN. + * String like "ldap://monkeymachine:389/dc=acegisecurity,dc=org" + */ public final String providerUrl; @DataBoundConstructor @@ -21,8 +28,12 @@ public class LDAPSecurityRealm extends SecurityRealm { } public AuthenticationManager createAuthenticationManager() { - // TODO - return new MockAuthenticationManager(true); + Binding binding = new Binding(); + binding.setVariable("it", this); + + BeanBuilder builder = new BeanBuilder(); + builder.parse(Hudson.getInstance().servletContext.getResourceAsStream("/WEB-INF/security/LDAPBindSecurityRealm.groovy"),binding); + return findBean(AuthenticationManager.class,builder.createApplicationContext()); } public DescriptorImpl getDescriptor() { diff --git a/war/resources/WEB-INF/security/LDAPBindSecurityRealm.groovy b/war/resources/WEB-INF/security/LDAPBindSecurityRealm.groovy new file mode 100644 index 0000000..22cc699 --- /dev/null +++ b/war/resources/WEB-INF/security/LDAPBindSecurityRealm.groovy @@ -0,0 +1,41 @@ +import org.acegisecurity.providers.ProviderManager +import org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider +import org.acegisecurity.providers.ldap.LdapAuthenticationProvider +import org.acegisecurity.providers.ldap.authenticator.BindAuthenticator +import org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator +import org.acegisecurity.ldap.DefaultInitialDirContextFactory + +/* + Configure LDAP as the authentication realm. + + Authentication is performed by doing LDAP bind. +*/ + +initialDirContextFactory(DefaultInitialDirContextFactory,it.providerUrl) { + + // if anonymous bind is not allowed --- but what is the use of anonymous bind? + // managerDn = "..." + // managerPassword="..." +} + +bindAuthenticator(BindAuthenticator,initialDirContextFactory) { + userDnPatterns = [ + "uid={0},ou=people" + ] +} +authoritiesPopulator(DefaultLdapAuthoritiesPopulator,initialDirContextFactory,"ou=groups") { + // groupRoleAttribute = "ou"; +} + +authenticationManager(ProviderManager) { + providers = [ + // talk to LDAP + bean(LdapAuthenticationProvider,bindAuthenticator,authoritiesPopulator), + // this doesn't mean we allow anonymous access. + // we just authenticate anonymous users as such, + // so that later authorization can reject them if so configured + bean(AnonymousAuthenticationProvider) { + key = "anonymous" + } + ] +} \ No newline at end of file