SEC-271: added ldap authentication parser

This commit is contained in:
Vishal Puri 2007-07-02 07:54:59 +00:00
parent 1dfc2baea2
commit c658efbc69
11 changed files with 315 additions and 50 deletions

View File

@ -7,7 +7,7 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="M2_REPO/commons-collections/commons-collections/3.1/commons-collections-3.1.jar" sourcepath="M2_REPO/commons-collections/commons-collections/3.1/commons-collections-3.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/cas/casclient/2.0.11/casclient-2.0.11.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/2.0.4/spring-beans-2.0.4.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/2.0.4/spring-beans-2.0.4.jar" sourcepath="/spring"/>
<classpathentry kind="var" path="M2_REPO/jdbm/jdbm/1.0/jdbm-1.0.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/directory/shared/shared-asn1/0.9.5.3/shared-asn1-0.9.5.3.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-support/2.0.4/spring-support-2.0.4.jar"/>
@ -39,6 +39,6 @@
<classpathentry kind="var" path="M2_REPO/org/acegisecurity/acegi-security/1.0.5-SNAPSHOT/acegi-security-1.0.5-SNAPSHOT.jar" sourcepath="M2_REPO/org/acegisecurity/acegi-security/1.0.5-SNAPSHOT/acegi-security-1.0.5-SNAPSHOT-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/directory/server/apacheds-core-shared/1.0.0/apacheds-core-shared-1.0.0.jar"/>
<classpathentry kind="var" path="M2_REPO/net/sf/ehcache/ehcache/1.2.4/ehcache-1.2.4.jar" sourcepath="M2_REPO/net/sf/ehcache/ehcache/1.2.4/ehcache-1.2.4-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/2.0.4/spring-core-2.0.4.jar" sourcepath="/spring"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/2.0.4/spring-core-2.0.4.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -1,23 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>spring-security-config</name>
<comment>Acegi Security System for Spring</comment>
<projects/>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.core.springbuilder</name>
</buildCommand>
</buildSpec>
<natures>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
</natures>
</projectDescription>
<name>spring-security-config</name>
<comment>Acegi Security System for Spring</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
</natures>
</projectDescription>

View File

@ -2,5 +2,5 @@
<fixed facet="jst.java"/>
<fixed facet="jst.utility"/>
<installed facet="jst.utility" version="1.0"/>
<installed facet="jst.java" version="1.3"/>
<installed facet="jst.java" version="5.0"/>
</faceted-project>

View File

@ -13,7 +13,13 @@
* limitations under the License.
*/
package org.acegisecurity.config;
import org.acegisecurity.ldap.DefaultInitialDirContextFactory;
import org.acegisecurity.providers.ProviderManager;
import org.acegisecurity.providers.ldap.LdapAuthenticationProvider;
import org.acegisecurity.providers.ldap.authenticator.BindAuthenticator;
import org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator;
import org.acegisecurity.util.BeanDefinitionParserUtils;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.ManagedList;
@ -23,14 +29,15 @@ import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* * {@link BeanDefinitionParser} for the <code>authentication-mechanism</code> tag,
* resolves to {@link org.acegisecurity.providers.ProviderManager} </br>
* * {@link BeanDefinitionParser} for the <code>authentication-mechanism</code>
* tag, resolves to {@link org.acegisecurity.providers.ProviderManager} </br>
*
* @author vpuri
* @see {@link org.springframework.beans.factory.BeanFactory}
* @see {@link org.acegisecurity.providers.ProviderManager}
@ -42,6 +49,8 @@ public class AuthenticationMechanismBeanDefinitionParser extends AbstractBeanDef
// ================================================================================================
private static final String AUTHENTICATION_JDBC = "authentication-jdbc";
private static final String AUTHENTICATION_LDAP="authentication-ldap";
private static final String REF = "ref";
@ -59,7 +68,7 @@ public class AuthenticationMechanismBeanDefinitionParser extends AbstractBeanDef
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element childElement = (Element) node;
//this.providerExists = true;
// this.providerExists = true;
if (AUTHENTICATION_JDBC.equals(node.getLocalName())) {
String attribute = childElement.getAttribute(REF);
@ -67,15 +76,16 @@ public class AuthenticationMechanismBeanDefinitionParser extends AbstractBeanDef
// create a beandefinition
providers.add(new RuntimeBeanReference(attribute));
}
} else if (AUTHENTICATION_LDAP.equals(node.getLocalName())){
providers.add(createLdapAuthencticationProviderBeanDefinition(childElement, parserContext));
}
// TODO:Add other providers here
}
authMechanismBeanDef.getPropertyValues().addPropertyValue("providers", providers);
}
return authMechanismBeanDef;
}
/**
* Creates a default bean definition.
* @return
@ -83,12 +93,51 @@ public class AuthenticationMechanismBeanDefinitionParser extends AbstractBeanDef
protected static RootBeanDefinition createAndRegisterBeanDefinitionWithDefaults(ParserContext parserContext) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(ProviderManager.class);
ManagedList providers = new ManagedList();
// create authentication-repository (DaoAuthenticationProvider) and add that to list
// create authentication-repository (DaoAuthenticationProvider) and add
// that to list
RootBeanDefinition authRepo = AuthenticationRepositoryBeanDefinitionParser.createBeanDefinitionWithDefaults();
providers.add(authRepo);
beanDefinition.getPropertyValues().addPropertyValue("providers", providers);
parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
return beanDefinition;
}
protected static RootBeanDefinition createLdapAuthencticationProviderBeanDefinition(Element element,
ParserContext parserContext) {
// element ldap
RootBeanDefinition ldapAuthProvider = new RootBeanDefinition(LdapAuthenticationProvider.class);
RootBeanDefinition initialDirContextFactory = createInitialDirContextFactoryBeanDefinition(element);
RootBeanDefinition ldapAuthoritiesPopulator = new RootBeanDefinition(DefaultLdapAuthoritiesPopulator.class);
RootBeanDefinition bindAuthenticator = new RootBeanDefinition(BindAuthenticator.class);
Element property = DomUtils.getChildElementByTagName(element, "property");
Assert.notNull(property);
parserContext.getDelegate().parsePropertyElement(property, bindAuthenticator);
bindAuthenticator.getConstructorArgumentValues().addIndexedArgumentValue(0, initialDirContextFactory);
// LdapAuthenticator
ldapAuthProvider.getConstructorArgumentValues().addIndexedArgumentValue(0, bindAuthenticator);
ldapAuthoritiesPopulator.getConstructorArgumentValues().addIndexedArgumentValue(0, initialDirContextFactory);
BeanDefinitionParserUtils.setConstructorArgumentIfAvailable(1, element, "groupSearchBase", false,
ldapAuthoritiesPopulator);
BeanDefinitionParserUtils.setPropertyIfAvailable(element, "groupRoleAttribute", "groupRoleAttribute", ldapAuthoritiesPopulator);
//LdapAuthoritiesPopulator
ldapAuthProvider.getConstructorArgumentValues().addIndexedArgumentValue(1, ldapAuthoritiesPopulator);
return ldapAuthProvider;
}
private static RootBeanDefinition createInitialDirContextFactoryBeanDefinition(Element element) {
RootBeanDefinition initialDirContextFactory = new RootBeanDefinition(DefaultInitialDirContextFactory.class);
BeanDefinitionParserUtils.setConstructorArgumentIfAvailable(0, element, "ldapUrl", false,
initialDirContextFactory);
BeanDefinitionParserUtils.setPropertyIfAvailable(element, "managerDn", "managerDn", initialDirContextFactory);
BeanDefinitionParserUtils.setPropertyIfAvailable(element, "managerPassword", "managerPassword",
initialDirContextFactory);
return initialDirContextFactory;
}
}

View File

@ -0,0 +1,42 @@
/**
*
*/
package org.acegisecurity.util;
import org.springframework.beans.factory.config.RuntimeBeanNameReference;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* @author Vishal Puri
*
*/
public class BeanDefinitionParserUtils {
/**
* Prevents instantiation
*/
private BeanDefinitionParserUtils() {
}
public static void setConstructorArgumentIfAvailable(int index, Element element, String attribute,
boolean isRunTimeBeanReference, RootBeanDefinition definition) {
String propertyValue = element.getAttribute(attribute);
if (StringUtils.hasText(propertyValue)) {
if(!isRunTimeBeanReference){
definition.getConstructorArgumentValues().addIndexedArgumentValue(index, propertyValue);
} else {
definition.getConstructorArgumentValues().addIndexedArgumentValue(index, new RuntimeBeanNameReference(propertyValue));
}
}
}
public static void setPropertyIfAvailable(Element element, String attribute, String property,
RootBeanDefinition definition) {
String propertyValue = element.getAttribute(attribute);
if (StringUtils.hasText(propertyValue)) {
definition.getPropertyValues().addPropertyValue(property, propertyValue);
}
}
}

View File

@ -3,11 +3,13 @@
<xsd:schema xmlns="http://www.springframework.org/schema/security"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:element name="autoconfig"/>
<xsd:import namespace="http://www.springframework.org/schema/beans" />
<xsd:element name="autoconfig" />
<xsd:element name="session-context-integration">
<xsd:complexType>
<xsd:attribute name="id" type="xsd:ID">
@ -88,13 +90,14 @@
<xsd:element name="authentication-remember-me-filter"
type="RememberMeFilter">
<xsd:annotation>
<xsd:documentation source="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<![CDATA[
<xsd:documentation
source="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<![CDATA[
makes the filter, but does little else, as it auto-detects everything
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:complexType name="RememberMeFilter">
<xsd:attribute name="id" type="xsd:ID">
@ -289,12 +292,61 @@
]]>
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="ref" type="xsd:string">
<xsd:sequence>
<xsd:element name="property">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:propertyType"></xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="ldapUrl" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
A short-cut alternative to a nested "<ref bean='...'/>" element.
The LDAP url of the server (and root context) to connect to.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="managerDn" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
The LDAP url of the server (and root context) to connect to.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="managerPassword" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
The manager user's password.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="groupSearchBase" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="groupRoleAttribute"
type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
]]>
</xsd:documentation>
</xsd:annotation>
@ -475,4 +527,5 @@
</xsd:schema>

View File

@ -0,0 +1,52 @@
package org.acegisecurity.config;
import junit.framework.TestCase;
import org.acegisecurity.ldap.InitialDirContextFactory;
import org.acegisecurity.providers.ldap.LdapAuthenticationProvider;
import org.acegisecurity.providers.ldap.authenticator.BindAuthenticator;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Vishal Puri
*
*/
public class LdapAuthenticationProviderBeanDefinitionParserTests extends TestCase {
public void testBeanDefinitionCreation() {
ApplicationContext context = new ClassPathXmlApplicationContext("org/acegisecurity/config/ldap-config.xml");
ConfigurableListableBeanFactory bf = (ConfigurableListableBeanFactory) context.getAutowireCapableBeanFactory();
BeanDefinition def = (RootBeanDefinition) bf.getBeanDefinition("authenticationManager");
assertNotNull(def);
PropertyValues values = def.getPropertyValues();
PropertyValue value = values.getPropertyValue("providers");
assertNotNull(value);
ManagedList list = (ManagedList) value.getValue();
assertEquals(1, list.size());
RootBeanDefinition definition = (RootBeanDefinition) list.get(0);
assertEquals(LdapAuthenticationProvider.class, definition.getBeanClass());
assertEquals(2, definition.getConstructorArgumentValues().getArgumentCount());
ValueHolder holder = definition.getConstructorArgumentValues().getArgumentValue(0, BindAuthenticator.class);
assertNotNull(holder.getConvertedValue() instanceof BindAuthenticator);
RootBeanDefinition authenticatorDefinition = (RootBeanDefinition) holder.getValue();
assertEquals(1, authenticatorDefinition.getConstructorArgumentValues().getArgumentCount());
RootBeanDefinition initialContextDir = (RootBeanDefinition) authenticatorDefinition
.getConstructorArgumentValues().getArgumentValue(0, InitialDirContextFactory.class).getValue();
assertEquals("cn=manager,dc=acegisecurity,dc=org", initialContextDir.getPropertyValues().getPropertyValue(
"managerDn").getValue());
assertEquals("ldap://monkeymachine:389/dc=acegisecurity,dc=org", initialContextDir.getConstructorArgumentValues()
.getArgumentValue(0, String.class).getValue());
}
}

View File

@ -3,9 +3,7 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
<!-- http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd -->

View File

@ -3,9 +3,7 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
<!-- http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd -->

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">
<!-- http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd -->
<!-- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd" -->
<!-- make it optional, if not supplied autodetect all auth-providers from app ctx, using Ordered to resolve their order -->
<security:authentication-mechanism id="authenticationManager">
<security:authentication-ldap
ldapUrl="ldap://monkeymachine:389/dc=acegisecurity,dc=org"
managerDn="cn=manager,dc=acegisecurity,dc=org"
managerPassword="password" groupSearchBase="ou=groups"
groupRoleAttribute="ou">
<security:property name="userDnPatterns">
<list>
<value>uid={0},ou=people</value>
</list>
</security:property>
</security:authentication-ldap>
</security:authentication-mechanism>
<!--<bean id="initialDirContextFactory"
class="org.acegisecurity.ldap.DefaultInitialDirContextFactory">
<constructor-arg
value="ldap://monkeymachine:389/dc=acegisecurity,dc=org" />
<property name="managerDn">
<value>cn=manager,dc=acegisecurity,dc=org</value>
</property>
<property name="managerPassword">
<value>password</value>
</property>
</bean>
<bean id="ldapAuthProvider"
class="org.acegisecurity.providers.ldap.LdapAuthenticationProvider">
<constructor-arg>
<bean
class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator">
<constructor-arg>
<ref local="initialDirContextFactory" />
</constructor-arg>
<property name="userDnPatterns">
<list>
<value>uid={0},ou=people</value>
</list>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean
class="org.acegisecurity.providers.ldap.populator.DefaultLdapAuthoritiesPopulator">
<constructor-arg>
<ref local="initialDirContextFactory" />
</constructor-arg>
<constructor-arg>
<value>ou=groups</value>
</constructor-arg>
<property name="groupRoleAttribute">
<value>ou</value>
</property>
</bean>
</constructor-arg>
</bean>
-->
</beans>

View File

@ -3,9 +3,7 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/beans/spring-util-2.0.xsd
http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd">
<!-- http://www.springframework.org/schema/security file:/Users/vpuri/interface21/acegisecurity/trunk/acegisecurity/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd -->