8 changed files with 312 additions and 4 deletions
@ -0,0 +1,69 @@
@@ -0,0 +1,69 @@
|
||||
/** |
||||
* |
||||
*/ |
||||
package org.acegisecurity.config; |
||||
|
||||
import org.acegisecurity.ui.logout.LogoutFilter; |
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder; |
||||
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.ParserContext; |
||||
import org.springframework.util.StringUtils; |
||||
import org.w3c.dom.Element; |
||||
|
||||
/** |
||||
* @author vpuri |
||||
* @since |
||||
*/ |
||||
public class LogoutFilterBeanDefinitionParser extends AbstractBeanDefinitionParser { |
||||
|
||||
// ~ Instance fields
|
||||
// ================================================================================================
|
||||
private static final String REDIRECT_AFTER_LOGOUT_URL = "redirectAfterLogoutUrl"; |
||||
|
||||
private static final String LOGOUT_URL = "logoutUrl"; |
||||
|
||||
// ~ Methods
|
||||
// ================================================================================================
|
||||
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { |
||||
|
||||
// add the properties
|
||||
RootBeanDefinition definition = new RootBeanDefinition(LogoutFilter.class); |
||||
setConstructorArgumentIfAvailable(0, element, REDIRECT_AFTER_LOGOUT_URL, "logoutSuccessUrl", definition); |
||||
// setPropertyIfAvailable(element,
|
||||
// element.getAttribute(REDIRECT_AFTER_LOGOUT_URL), "logoutSuccessUrl",
|
||||
// definition);
|
||||
setPropertyIfAvailable(element, LOGOUT_URL, "filterProcessesUrl", definition); |
||||
|
||||
// register BFPP to check if LogoutFilter does not have setHandlers
|
||||
// populated, introspect app ctx for LogoutHandlers, using Ordered (if
|
||||
// present, otherwise assume Integer.MAX_VALUE)
|
||||
RootBeanDefinition bfpp = new RootBeanDefinition(LogoutHandlerOrderResolver.class); |
||||
parserContext.getReaderContext().registerWithGeneratedName(bfpp); |
||||
|
||||
return definition; |
||||
} |
||||
|
||||
private void setConstructorArgumentIfAvailable(int index, Element element, String attribute, String property, |
||||
RootBeanDefinition definition) { |
||||
String propertyValue = element.getAttribute(attribute); |
||||
if (StringUtils.hasText(propertyValue)) { |
||||
definition.getConstructorArgumentValues().addIndexedArgumentValue(index, propertyValue); |
||||
} |
||||
} |
||||
|
||||
private void setPropertyIfAvailable(Element element, String attribute, String property, |
||||
RootBeanDefinition definition) { |
||||
String propertyValue = element.getAttribute(attribute); |
||||
if (StringUtils.hasText(propertyValue)) { |
||||
definition.getPropertyValues().addPropertyValue(property, propertyValue); |
||||
} |
||||
} |
||||
|
||||
//
|
||||
|
||||
} |
||||
@ -0,0 +1,89 @@
@@ -0,0 +1,89 @@
|
||||
/** |
||||
* |
||||
*/ |
||||
package org.acegisecurity.config; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.acegisecurity.ui.logout.LogoutFilter; |
||||
import org.acegisecurity.ui.logout.LogoutHandler; |
||||
import org.acegisecurity.ui.logout.SecurityContextLogoutHandler; |
||||
import org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices; |
||||
import org.springframework.beans.BeansException; |
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor; |
||||
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.core.OrderComparator; |
||||
import org.springframework.core.Ordered; |
||||
|
||||
/** |
||||
* @author vpuri |
||||
* @since |
||||
*/ |
||||
public class LogoutHandlerOrderResolver implements BeanFactoryPostProcessor { |
||||
|
||||
// ~ Methods
|
||||
// ================================================================================================
|
||||
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { |
||||
// If LogoutFilter does not have setHandlers populated, introspect app
|
||||
// ctx for LogoutHandlers, using Ordered (if present, otherwise assume
|
||||
// Integer.MAX_VALUE)
|
||||
String[] names = beanFactory.getBeanNamesForType(LogoutFilter.class); |
||||
RootBeanDefinition definition = (RootBeanDefinition) beanFactory.getBeanDefinition(names[0]); |
||||
ValueHolder holder = getHandlersIfConfigured(beanFactory, definition); |
||||
if (holder == null) { |
||||
// intropect the appcontext for registerd LogoutHandler
|
||||
List logoutHandlers = retrieveAllLogoutHandlers(beanFactory); |
||||
definition.getConstructorArgumentValues().addIndexedArgumentValue(1, logoutHandlers); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param beanFactory |
||||
* @param definition |
||||
* @return |
||||
*/ |
||||
private ValueHolder getHandlersIfConfigured(ConfigurableListableBeanFactory beanFactory, |
||||
RootBeanDefinition definition) { |
||||
// there should be only one LogoutFilter
|
||||
return definition.getConstructorArgumentValues().getArgumentValue(1, null); |
||||
|
||||
} |
||||
|
||||
/** |
||||
* |
||||
* @param beanFactory |
||||
* @return |
||||
*/ |
||||
private List retrieveAllLogoutHandlers(ConfigurableListableBeanFactory beanFactory) { |
||||
String[] names = beanFactory.getBeanNamesForType(LogoutHandler.class); |
||||
ManagedList list = new ManagedList(); |
||||
|
||||
for (int i = 0, n = names.length; i < n; i++) { |
||||
RootBeanDefinition definition = (RootBeanDefinition) beanFactory.getBeanDefinition(names[i]); |
||||
|
||||
if (Ordered.class.isAssignableFrom(definition.getBeanClass())) { |
||||
definition.getPropertyValues().addPropertyValue("order", getOrder(definition.getBeanClass())); |
||||
list.add(definition); |
||||
} |
||||
} |
||||
Collections.sort(list, new OrderComparator()); |
||||
return list; |
||||
} |
||||
|
||||
private int getOrder(Class clazz) { |
||||
if (clazz.getName().equals(TokenBasedRememberMeServices.class.getName())) { |
||||
return 0; |
||||
} |
||||
if (clazz.getName().equals(SecurityContextLogoutHandler.class.getName())) { |
||||
return 1; |
||||
} |
||||
return Integer.MAX_VALUE; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
/** |
||||
* |
||||
*/ |
||||
package org.acegisecurity.config; |
||||
|
||||
import junit.framework.TestCase; |
||||
|
||||
import org.acegisecurity.GrantedAuthority; |
||||
import org.acegisecurity.GrantedAuthorityImpl; |
||||
import org.acegisecurity.userdetails.User; |
||||
import org.acegisecurity.userdetails.UserDetailsService; |
||||
import org.acegisecurity.userdetails.memory.InMemoryDaoImpl; |
||||
import org.acegisecurity.userdetails.memory.UserMap; |
||||
import org.springframework.beans.PropertyValue; |
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; |
||||
import org.springframework.beans.factory.support.RootBeanDefinition; |
||||
import org.springframework.context.ApplicationContext; |
||||
import org.springframework.context.support.ClassPathXmlApplicationContext; |
||||
|
||||
/** |
||||
* @author vpuri |
||||
* |
||||
*/ |
||||
public class PrincipalRepositoryNamespaceTests extends TestCase { |
||||
|
||||
public void testParserWithUserDefinition() { |
||||
ApplicationContext context = new ClassPathXmlApplicationContext( |
||||
"org/acegisecurity/config/principal-repository-user-map.xml"); |
||||
|
||||
ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) context |
||||
.getAutowireCapableBeanFactory(); |
||||
|
||||
String[] names = clbf.getBeanNamesForType(UserDetailsService.class); |
||||
assertEquals(1, names.length); |
||||
|
||||
RootBeanDefinition definition = (RootBeanDefinition) clbf.getBeanDefinition(names[0]); |
||||
assertEquals(InMemoryDaoImpl.class, definition.getBeanClass()); |
||||
|
||||
UserMap map = new UserMap(); |
||||
|
||||
GrantedAuthority[] authotities = { new GrantedAuthorityImpl("ROLE_YO"), new GrantedAuthorityImpl("ROLE_YOYO") }; |
||||
|
||||
User user = new User("vishal", "nottellingya", true, true, true, true, authotities); |
||||
|
||||
map.addUser(user); |
||||
|
||||
assertPropertyValues(map, definition, "userMap"); |
||||
|
||||
} |
||||
|
||||
private void assertPropertyValues(UserMap assertionValue, RootBeanDefinition definition, String property) { |
||||
PropertyValue propertyValue = definition.getPropertyValues().getPropertyValue(property); |
||||
assertNotNull(propertyValue); |
||||
assertTrue(propertyValue.getValue() instanceof UserMap); |
||||
UserMap users = (UserMap) propertyValue.getValue(); |
||||
assertTrue(assertionValue.getUserCount() == users.getUserCount()); |
||||
assertEquals(assertionValue.getUser("vishal"), users.getUser("vishal")); |
||||
assertTrue(users.getUser("vishal").isEnabled()); |
||||
assertTrue(users.getUser("vishal").isAccountNonExpired()); |
||||
assertTrue(users.getUser("vishal").isAccountNonLocked()); |
||||
assertTrue(users.getUser("vishal").isCredentialsNonExpired()); |
||||
assertEquals(2, users.getUser("vishal").getAuthorities().length); |
||||
assertEquals(new GrantedAuthorityImpl("ROLE_YO"), users.getUser("vishal").getAuthorities()[0]); |
||||
assertEquals(new GrantedAuthorityImpl("ROLE_YOYO"), users.getUser("vishal").getAuthorities()[1]); |
||||
} |
||||
} |
||||
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
<?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 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" --> |
||||
|
||||
<!-- If LogoutFilter does not have setHandlers populated, introspect app ctx for LogoutHandlers, using Ordered (if present, otherwise assume Integer.MAX_VALUE) --> |
||||
<!-- The logoutUrl and redirectAfterLogout are both optional and default to that shown --> |
||||
<security:logout-support id="logoutFilter" |
||||
redirectAfterLogoutUrl="/" logoutUrl="/logout" /> |
||||
|
||||
<security:authentication-remember-me-services |
||||
id="rememberMeServices" key="someValue" /> |
||||
|
||||
<security:principal-repository id="userDetailsService"> |
||||
<security:user-definition username="vishal" |
||||
password="nottellingya" enabled="true"> |
||||
<security:granted-authority authority="ROLE_YO" /> |
||||
<security:granted-authority authority="ROLE_YOYO" /> |
||||
<!-- TODO: <security:granted-authority-ref authorityBeanRef="fooBarAuthority"/>--> |
||||
</security:user-definition> |
||||
</security:principal-repository> |
||||
</beans> |
||||
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
<?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 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" --> |
||||
|
||||
<!-- 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:properties resource="classpath:org/acegisecurity/config/user.properties"/> |
||||
</security:principal-repository> |
||||
|
||||
</beans> |
||||
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
<?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 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" --> |
||||
|
||||
<!-- 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:user-definition username="vishal" password="nottellingya" enabled="true"> |
||||
<security:granted-authority authority="ROLE_YO"/> |
||||
<security:granted-authority authority="ROLE_YOYO"/> |
||||
<!-- TODO: <security:granted-authority-ref authorityBeanRef="fooBarAuthority"/>--> |
||||
</security:user-definition> |
||||
</security:principal-repository> |
||||
|
||||
<!-- TODO: <security:granted-authority id="fooBarAuthority" authority="ROLE_FOOBAR"/> --> |
||||
|
||||
</beans> |
||||
Loading…
Reference in new issue