diff --git a/core/src/main/java/org/acegisecurity/config/AuthenticationMechanismBeanDefinitionParser.java b/core/src/main/java/org/acegisecurity/config/AuthenticationMechanismBeanDefinitionParser.java index af61ce778a..210c2d2f34 100644 --- a/core/src/main/java/org/acegisecurity/config/AuthenticationMechanismBeanDefinitionParser.java +++ b/core/src/main/java/org/acegisecurity/config/AuthenticationMechanismBeanDefinitionParser.java @@ -3,9 +3,6 @@ */ 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; @@ -28,7 +25,7 @@ import org.w3c.dom.NodeList; public class AuthenticationMechanismBeanDefinitionParser extends AbstractBeanDefinitionParser implements BeanDefinitionParser { - private static final Object AUTHENTICATION_JDBC = "authentication-jdbc"; + private static final String AUTHENTICATION_JDBC = "authentication-jdbc"; private static final String REF = "ref"; diff --git a/core/src/main/java/org/acegisecurity/config/AuthenticationRepositoryBeanDefinitionParser.java b/core/src/main/java/org/acegisecurity/config/AuthenticationRepositoryBeanDefinitionParser.java index 57f2c79be7..86deccd8b8 100644 --- a/core/src/main/java/org/acegisecurity/config/AuthenticationRepositoryBeanDefinitionParser.java +++ b/core/src/main/java/org/acegisecurity/config/AuthenticationRepositoryBeanDefinitionParser.java @@ -25,7 +25,7 @@ import org.w3c.dom.NodeList; */ public class AuthenticationRepositoryBeanDefinitionParser extends AbstractBeanDefinitionParser { -// ~ Instance fields ================================================================================================ + // ~ Instance fields ================================================================================================ private static final String REPOSITORY_BEAN_REF = "repositoryBeanRef"; @@ -49,7 +49,7 @@ public class AuthenticationRepositoryBeanDefinitionParser extends AbstractBeanDe -// ~ Method ================================================================================================ + // ~ Method ================================================================================================ /** * TODO: Document Me !!! */ diff --git a/core/src/main/java/org/acegisecurity/config/PrincipalRepositoryBeanDefinitionParser.java b/core/src/main/java/org/acegisecurity/config/PrincipalRepositoryBeanDefinitionParser.java index 93e6395b37..b083352633 100644 --- a/core/src/main/java/org/acegisecurity/config/PrincipalRepositoryBeanDefinitionParser.java +++ b/core/src/main/java/org/acegisecurity/config/PrincipalRepositoryBeanDefinitionParser.java @@ -3,9 +3,22 @@ */ package org.acegisecurity.config; +import java.util.Properties; + +import org.acegisecurity.GrantedAuthorityImpl; +import org.acegisecurity.userdetails.User; +import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.jdbc.JdbcDaoImpl; +import org.acegisecurity.userdetails.memory.InMemoryDaoImpl; +import org.acegisecurity.userdetails.memory.UserAttribute; +import org.acegisecurity.userdetails.memory.UserMap; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +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; @@ -15,44 +28,128 @@ 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 ================================================================================================ + // ~ Static fields/initializers ===================================================================================== + + private static final Log logger = LogFactory.getLog(PrincipalRepositoryBeanDefinitionParser.class); + + // ~ 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"; + + private static final String USERNAME_BASED_PRIMARY_KEY = "usernameBasedPrimaryKey"; + + private static final String PROPERTIES = "properties"; + + private static final String RESOURCE = "resource"; + + private static final String USER_PROPERTIES = "userProperties"; + + private static final String USER_DEFINITION = "user-definition"; + + private static final Object GRANTED_AUTHORITY = "granted-authority"; + + private static final String USERNAME = "username"; + + private static final String PASSWORD = "password"; + + private static final String ENABLED = "enabled"; + + private static final String GRANTED_AUTHORITY_REF = "granted-authority-ref"; + + private static final String AUTHORITY = "authority"; - //authoritiesByUsernameQuery="" rolePrefix="" usernameBasedPrimaryKey="true" usersByUsernameQuery="" - - // ~ Method ================================================================================================ + private static final String AUTHORITY_BEAN_REF="authorityBeanRef"; + + // ~ Method + // ================================================================================================ + /** + * + */ protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { - NodeList userDetailsServiceChildren = element.getChildNodes(); - RootBeanDefinition userDetailsServiceJdbcDefinition = null; + RootBeanDefinition userDetailsServiceDefinition = 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); + userDetailsServiceDefinition = parseUserDetailsServiceJdbcDefinition(ele); + userDetailsServiceDefinition.setSource(parserContext.extractSource(element)); + parserContext.getReaderContext().registerWithGeneratedName(userDetailsServiceDefinition); + } + if (PROPERTIES.equals(userDetailsService.getLocalName()) + && userDetailsService.getNodeType() == Node.ELEMENT_NODE) { + Element ele = (Element) userDetailsService; + + userDetailsServiceDefinition = new RootBeanDefinition(InMemoryDaoImpl.class); + userDetailsServiceDefinition.getPropertyValues().addPropertyValue(USER_PROPERTIES, + new RuntimeBeanReference(createPropertiesBeanDefinition(ele, parserContext))); + userDetailsServiceDefinition.setSource(parserContext.extractSource(element)); + parserContext.getReaderContext().registerWithGeneratedName(userDetailsServiceDefinition); + } + if (USER_DEFINITION.equals(userDetailsService.getLocalName()) + && userDetailsService.getNodeType() == Node.ELEMENT_NODE) { + Element ele = (Element) userDetailsService; + + // create a UserMap which interns uses UserMapEditor + userDetailsServiceDefinition = createUserDefinition(ele, parserContext); } } - return userDetailsServiceJdbcDefinition; + return userDetailsServiceDefinition; } + private RootBeanDefinition createUserDefinition(Element ele, ParserContext parserContext) { + RootBeanDefinition definition = new RootBeanDefinition(InMemoryDaoImpl.class); + + UserAttribute userAttribute = new UserAttribute(); + UserMap userMap = new UserMap(); + + setPassword(ele, userAttribute); + setEnabled(ele, userAttribute); + setAuthorities(ele, userAttribute); + + UserDetails user = new User(ele.getAttribute(USERNAME), userAttribute.getPassword(), userAttribute.isEnabled(), + true, true, true, userAttribute.getAuthorities()); + userMap.addUser(user); + definition.getPropertyValues().addPropertyValue("userMap", userMap); + return definition; + + } + + private String createPropertiesBeanDefinition(Element ele, ParserContext parserContext) { + // properties element + RootBeanDefinition defintion = new RootBeanDefinition(PropertiesFactoryBean.class); + String propertyValue = ele.getAttribute(RESOURCE); + defintion.getPropertyValues().addPropertyValue(RESOURCE, propertyValue); + defintion.setSource(parserContext.extractSource(ele)); + return parserContext.getReaderContext().registerWithGeneratedName(defintion); + } + + /** + * + * @param elementToParse + * @return + */ private RootBeanDefinition parseUserDetailsServiceJdbcDefinition(Element elementToParse) { // parse attributes RootBeanDefinition definition = new RootBeanDefinition(JdbcDaoImpl.class); @@ -63,14 +160,76 @@ public class PrincipalRepositoryBeanDefinitionParser extends AbstractBeanDefinit 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); + + protected void doParseProperties(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + Properties parsedProps = parserContext.getDelegate().parsePropsElement(element); + builder.addPropertyValue(PROPERTIES, parsedProps); + } + + /** + * + * @param element + * @param attribute + * @param property + * @param definition + */ + private void setPropertyIfAvailable(Element element, String attribute, String property, + RootBeanDefinition definition) { + String propertyValue = element.getAttribute(attribute); if (StringUtils.hasText(propertyValue)) { - definition.getPropertyValues().addPropertyValue(property, new RuntimeBeanReference(propertyValue)); + if (propertyValue.equals(DATASOURCE_REF) || propertyValue.equals(JDBCTEMPLATE_REF)) { + definition.getPropertyValues().addPropertyValue(property, new RuntimeBeanReference(propertyValue)); + } + else { + definition.getPropertyValues().addPropertyValue(property, propertyValue); + } } } + private void setPassword(Element element, UserAttribute userAttribute) { + String propertyValue = element.getAttribute(PASSWORD); + if (StringUtils.hasText(propertyValue)) { + userAttribute.setPassword(propertyValue); + } + } + private void setEnabled(Element element, UserAttribute userAttribute) { + String propertyValue = element.getAttribute(ENABLED); + if (StringUtils.hasText(propertyValue)) { + if (propertyValue.equals("true")) { + userAttribute.setEnabled(Boolean.TRUE); + } + else { + userAttribute.setEnabled(Boolean.FALSE); + } + } + } + + private void setAuthorities(Element ele, UserAttribute userAttribute) { + // get authorities + NodeList childNodes = ele.getChildNodes(); + + ManagedList authorities = new ManagedList(); + + for (int i = 0, n = childNodes.getLength(); i < n; i++) { + Node authorityNode = childNodes.item(i); + + if (GRANTED_AUTHORITY.equals(authorityNode.getLocalName()) + && authorityNode.getNodeType() == Element.ELEMENT_NODE) { + Element propertyValue = (Element) authorityNode; + authorities.add(new GrantedAuthorityImpl(propertyValue.getAttribute(AUTHORITY))); + } + + if (GRANTED_AUTHORITY_REF.equals(authorityNode.getLocalName()) + && authorityNode.getNodeType() == Element.ELEMENT_NODE) { + Element propertyValue = (Element) authorityNode; + String attribute = propertyValue.getAttribute(AUTHORITY_BEAN_REF); + if (StringUtils.hasLength(attribute)) { + authorities.add(new RuntimeBeanReference(attribute)); + } + } + } + userAttribute.setAuthorities(authorities); + } } diff --git a/core/src/main/java/org/acegisecurity/config/SecurityNamespaceHandler.java b/core/src/main/java/org/acegisecurity/config/SecurityNamespaceHandler.java index 2b922f8a51..60868dba9e 100644 --- a/core/src/main/java/org/acegisecurity/config/SecurityNamespaceHandler.java +++ b/core/src/main/java/org/acegisecurity/config/SecurityNamespaceHandler.java @@ -25,6 +25,7 @@ public class SecurityNamespaceHandler extends NamespaceHandlerSupport { registerBeanDefinitionParser("authentication-mechanism", new AuthenticationMechanismBeanDefinitionParser()); registerBeanDefinitionParser("authentication-remember-me-services", new RememberMeServicesBeanDefinitionParser()); registerBeanDefinitionParser("authentication-remember-me-filter", new RememberMeFilterBeanDefinitionParser()); + registerBeanDefinitionParser("logout-support", new LogoutFilterBeanDefinitionParser()); } } diff --git a/core/src/main/java/org/acegisecurity/ui/logout/SecurityContextLogoutHandler.java b/core/src/main/java/org/acegisecurity/ui/logout/SecurityContextLogoutHandler.java index 2ae57494ea..d44398e2db 100644 --- a/core/src/main/java/org/acegisecurity/ui/logout/SecurityContextLogoutHandler.java +++ b/core/src/main/java/org/acegisecurity/ui/logout/SecurityContextLogoutHandler.java @@ -18,60 +18,74 @@ package org.acegisecurity.ui.logout; import org.acegisecurity.Authentication; import org.acegisecurity.context.SecurityContextHolder; +import org.springframework.core.Ordered; import org.springframework.util.Assert; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; - /** - * Performs a logout by modifying the {@link org.acegisecurity.context.SecurityContextHolder}. - * - *
Will also invalidate the {@link HttpSession} if {@link #isInvalidateHttpSession()} is
- * true and the session is not null.
- *
+ * Performs a logout by modifying the
+ * {@link org.acegisecurity.context.SecurityContextHolder}.
+ *
+ *
+ * Will also invalidate the {@link HttpSession} if
+ * {@link #isInvalidateHttpSession()} is true and the session is
+ * not null.
+ *
* @author Ben Alex
- * @version $Id$
+ * @version $Id: SecurityContextLogoutHandler.java 1784 2007-02-24 21:00:24Z
+ * luke_t $
*/
-public class SecurityContextLogoutHandler implements LogoutHandler {
- //~ Methods ========================================================================================================
+public class SecurityContextLogoutHandler implements LogoutHandler, Ordered {
+ // ~ Methods
+ // ========================================================================================================
- private boolean invalidateHttpSession = true;
+ private boolean invalidateHttpSession = true;
- /**
- * Requires the request to be passed in.
- *
- * @param request from which to obtain a HTTP session (cannot be null)
- * @param response not used (can be null)
- * @param authentication not used (can be null)
- */
- public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
- Assert.notNull(request, "HttpServletRequest required");
- if (invalidateHttpSession) {
- HttpSession session = request.getSession(false);
- if (session != null) {
- session.invalidate();
- }
- }
+ private int order = Integer.MAX_VALUE; //~ default
- SecurityContextHolder.clearContext();
- }
+ /**
+ * Requires the request to be passed in.
+ *
+ * @param request from which to obtain a HTTP session (cannot be null)
+ * @param response not used (can be null)
+ * @param authentication not used (can be null)
+ */
+ public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
+ Assert.notNull(request, "HttpServletRequest required");
+ if (invalidateHttpSession) {
+ HttpSession session = request.getSession(false);
+ if (session != null) {
+ session.invalidate();
+ }
+ }
- public boolean isInvalidateHttpSession() {
- return invalidateHttpSession;
- }
+ SecurityContextHolder.clearContext();
+ }
- /**
- * Causes the {@link HttpSession} to be invalidated when this
- * {@link LogoutHandler} is invoked. Defaults to true.
- *
- * @param invalidateHttpSession true if you wish the session to be
- * invalidated (default) or false if it should not be
- */
- public void setInvalidateHttpSession(boolean invalidateHttpSession) {
- this.invalidateHttpSession = invalidateHttpSession;
- }
+ public boolean isInvalidateHttpSession() {
+ return invalidateHttpSession;
+ }
+ /**
+ * Causes the {@link HttpSession} to be invalidated when this
+ * {@link LogoutHandler} is invoked. Defaults to true.
+ *
+ * @param invalidateHttpSession true if you wish the session to be
+ * invalidated (default) or false if it should not be
+ */
+ public void setInvalidateHttpSession(boolean invalidateHttpSession) {
+ this.invalidateHttpSession = invalidateHttpSession;
+ }
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int order) {
+ this.order = order;
+ }
}
diff --git a/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java b/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java
index 4edabbad20..d9d5e5424a 100644
--- a/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java
+++ b/core/src/main/java/org/acegisecurity/ui/rememberme/TokenBasedRememberMeServices.java
@@ -15,36 +15,30 @@
package org.acegisecurity.ui.rememberme;
-import org.acegisecurity.Authentication;
-
-import org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken;
-
-import org.acegisecurity.ui.AuthenticationDetailsSource;
-import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
-import org.acegisecurity.ui.logout.LogoutHandler;
-
-import org.acegisecurity.userdetails.UserDetails;
-import org.acegisecurity.userdetails.UserDetailsService;
-import org.acegisecurity.userdetails.UsernameNotFoundException;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.beans.factory.InitializingBean;
-
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-import org.springframework.web.bind.RequestUtils;
-
import java.util.Date;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.acegisecurity.Authentication;
+import org.acegisecurity.providers.rememberme.RememberMeAuthenticationToken;
+import org.acegisecurity.ui.AuthenticationDetailsSource;
+import org.acegisecurity.ui.AuthenticationDetailsSourceImpl;
+import org.acegisecurity.ui.logout.LogoutHandler;
+import org.acegisecurity.userdetails.UserDetails;
+import org.acegisecurity.userdetails.UserDetailsService;
+import org.acegisecurity.userdetails.UsernameNotFoundException;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.Ordered;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.RequestUtils;
+
/**
* Identifies previously remembered users by a Base-64 encoded cookie.
@@ -88,7 +82,7 @@ import javax.servlet.http.HttpServletResponse;
* @author Ben Alex
* @version $Id$
*/
-public class TokenBasedRememberMeServices implements RememberMeServices, InitializingBean, LogoutHandler {
+public class TokenBasedRememberMeServices implements RememberMeServices, InitializingBean, LogoutHandler, Ordered {
//~ Static fields/initializers =====================================================================================
public static final String ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE_KEY = "ACEGI_SECURITY_HASHED_REMEMBER_ME_COOKIE";
@@ -103,6 +97,7 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
private UserDetailsService userDetailsService;
private long tokenValiditySeconds = 1209600; // 14 days
private boolean alwaysRemember = false;
+ private int order = Integer.MAX_VALUE; //~ default
//~ Methods ========================================================================================================
@@ -354,4 +349,13 @@ public class TokenBasedRememberMeServices implements RememberMeServices, Initial
public void setAlwaysRemember(boolean alwaysRemember) {
this.alwaysRemember = alwaysRemember;
}
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int order) {
+ this.order = order;
+ }
+
}
diff --git a/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd b/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd
index 13cd41f94f..23f7bbf986 100644
--- a/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd
+++ b/core/src/main/resources/org/acegisecurity/config/spring-security-2.0.xsd
@@ -3,9 +3,10 @@