added new security element in the spring-security schema and wrote a parser for the element

This commit is contained in:
Vishal Puri 2007-05-13 13:33:33 +00:00
parent 20e21811f0
commit ced5cb4f85
7 changed files with 240 additions and 2 deletions

View File

@ -0,0 +1,76 @@
/**
*
*/
package org.acegisecurity.config;
import java.util.ArrayList;
import java.util.List;
import org.acegisecurity.providers.ProviderManager;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
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.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* @author vpuri
*
*/
public class AuthenticationMechanismBeanDefinitionParser extends AbstractBeanDefinitionParser implements
BeanDefinitionParser {
private static final Object AUTHENTICATION_JDBC = "authentication-jdbc";
private static final String REF = "ref";
private boolean providerExists = false;
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
ManagedList providers = new ManagedList();
Assert.notNull(parserContext, "ParserContext must not be null");
RootBeanDefinition authMechanismBeanDef = new RootBeanDefinition(ProviderManager.class);
NodeList childNodes = element.getChildNodes();
for (int i = 0, n = childNodes.getLength(); i < n; i++) {
Node node = childNodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element childElement = (Element) node;
providerExists = true;
if (AUTHENTICATION_JDBC.equals(node.getLocalName())) {
String attribute = childElement.getAttribute(REF);
if (StringUtils.hasLength(attribute)) {
// create a beandefinition
providers.add(new RuntimeBeanReference(attribute));
}
}
// TODO:Add other providers here
}
authMechanismBeanDef.getPropertyValues().addPropertyValue("providers", providers);
}
if (!providerExists) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(AuthenticationProviderOrderResolver.class);
BeanDefinitionHolder beanDefinitionHolder = new BeanDefinitionHolder(rootBeanDefinition,
"providerOrderResolver");
registerBeanDefinition(beanDefinitionHolder, parserContext.getRegistry());
}
return authMechanismBeanDef;
}
}

View File

@ -0,0 +1,41 @@
package org.acegisecurity.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.acegisecurity.AuthenticationManager;
import org.acegisecurity.providers.AuthenticationProvider;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.OrderComparator;
public class AuthenticationProviderOrderResolver implements BeanFactoryPostProcessor {
/**
*
*/
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// retrieve all the AuthenticationProvider instances
List providers = retrieveAllAuthenticationProviders(beanFactory);
String[] names = beanFactory.getBeanNamesForType(AuthenticationManager.class);
RootBeanDefinition definition = (RootBeanDefinition)beanFactory.getBeanDefinition(names[0]);
definition.getPropertyValues().addPropertyValue("providers",providers);
}
/**
*
* @param beanFactory
* @return
*/
private List retrieveAllAuthenticationProviders(ConfigurableListableBeanFactory beanFactory) {
Map m = beanFactory.getBeansOfType(AuthenticationProvider.class);
List l = new ArrayList(m.values());
Collections.sort(l, new OrderComparator());
return l;
}
}

View File

@ -0,0 +1,76 @@
/**
*
*/
package org.acegisecurity.config;
import org.acegisecurity.userdetails.jdbc.JdbcDaoImpl;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* @author vpuri
*
*/
public class PrincipalRepositoryBeanDefinitionParser extends AbstractBeanDefinitionParser implements
BeanDefinitionParser {
// ~ Instance fields ================================================================================================
private static final String JDBC = "jdbc";
private static final String DATASOURCE_REF = "dataSourceBeanRef";
private static final String DATASOURCE = "dataSource";
private static final String JDBCTEMPLATE_REF = "jdbcTemplateBeanRef";
private static final String JDBCTEMPLATE = "jdbcTemplate";
private static final String AUTHORITIES_BY_USERNAME_QUERY = "authoritiesByUsernameQuery";
private static final String ROLE_PREFIX = "rolePrefix";
private static final String USERNAME_BASED_PRIMARY_KEY="usernameBasedPrimaryKey";
//authoritiesByUsernameQuery="" rolePrefix="" usernameBasedPrimaryKey="true" usersByUsernameQuery=""
// ~ Method ================================================================================================
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
NodeList userDetailsServiceChildren = element.getChildNodes();
RootBeanDefinition userDetailsServiceJdbcDefinition = null;
for (int i = 0, n = userDetailsServiceChildren.getLength(); i < n; i++) {
Node userDetailsService = userDetailsServiceChildren.item(i);
if (JDBC.equals(userDetailsService.getLocalName()) && userDetailsService.getNodeType() == Node.ELEMENT_NODE) {
Element ele = (Element) userDetailsService;
userDetailsServiceJdbcDefinition = parseUserDetailsServiceJdbcDefinition(ele);
userDetailsServiceJdbcDefinition.setSource(parserContext.extractSource(element));
parserContext.getReaderContext().registerWithGeneratedName(userDetailsServiceJdbcDefinition);
}
}
return userDetailsServiceJdbcDefinition;
}
private RootBeanDefinition parseUserDetailsServiceJdbcDefinition(Element elementToParse) {
// parse attributes
RootBeanDefinition definition = new RootBeanDefinition(JdbcDaoImpl.class);
setPropertyIfAvailable(elementToParse, DATASOURCE_REF, DATASOURCE, definition);
setPropertyIfAvailable(elementToParse, JDBCTEMPLATE_REF, JDBCTEMPLATE, definition);
setPropertyIfAvailable(elementToParse, AUTHORITIES_BY_USERNAME_QUERY, AUTHORITIES_BY_USERNAME_QUERY, definition);
setPropertyIfAvailable(elementToParse, ROLE_PREFIX, ROLE_PREFIX, definition);
setPropertyIfAvailable(elementToParse, USERNAME_BASED_PRIMARY_KEY, USERNAME_BASED_PRIMARY_KEY, definition);
return definition;
}
private void setPropertyIfAvailable(Element el, String attribute, String property, RootBeanDefinition definition) {
String propertyValue = el.getAttribute(attribute);
if (StringUtils.hasText(propertyValue)) {
definition.getPropertyValues().addPropertyValue(property, new RuntimeBeanReference(propertyValue));
}
}
}

View File

@ -183,7 +183,7 @@
<xsd:complexType>
<xsd:attribute name="dataSourceBeanRef" type="xsd:string" />
<xsd:attribute name="authoritiesByUsernameQuery" type="xsd:string" use="optional"/>
<xsd:attribute name="jdbcTemplateRef" type="xsd:string" use="optional"/>
<xsd:attribute name="jdbcTemplateBeanRef" type="xsd:string" use="optional"/>
<xsd:attribute name="rolePrefix" type="xsd:string" use="optional"/>
<xsd:attribute name="usernameBasedPrimaryKey" type="xsd:boolean" use="optional"/>
<xsd:attribute name="usersByUsernameQuery" type="xsd:string" use="optional"/>

View File

@ -8,7 +8,9 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
public class RememberMeBeanDefinitionParserTest extends TestCase {
public void testRememberMeDefaults() {
ApplicationContext context = new ClassPathXmlApplicationContext("org/acegisecurity/config/principal-defaults.xml");
ApplicationContext context = new ClassPathXmlApplicationContext("org/acegisecurity/config/remember-me-defaults.xml");
}
}

View File

@ -0,0 +1,42 @@
<?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: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 -->
<!-- http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd" -->
<!-- userDetailsService, This is used if they want an out-of-the-bx UserDetailsService; if they write their own, this goes away and they wire a legacy bean definition and then the various
beans depending on a UserDetailsService will auto-detect it at runtime OR provide a way of setUserDetailsService(UserDetailsService) if to specified explicitly.
If they fail to provide a repository, the security-autodetect will set one up for them with a few basic in-memory users and pwds -->
<security:principal-repository id="userDetailsService">
<security:jdbc dataSourceBeanRef="dataSource" jdbcTemplateBeanRef="jdbcTemplate" authoritiesByUsernameQuery="" rolePrefix="" usernameBasedPrimaryKey="true" usersByUsernameQuery=""/>
</security:principal-repository>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>org.hsqldb.jdbcDriver</value>
</property>
<property name="url">
<value>jdbc:hsqldb:mem:test</value>
<!-- <value>jdbc:hsqldb:hsql://localhost/acl</value> -->
</property>
<property name="username">
<value>sa</value>
</property>
<property name="password">
<value></value>
</property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>

View File

@ -461,6 +461,7 @@
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<spring.version>2.0.4</spring.version>