View Javadoc

1   package org.springframework.security.config;
2   
3   import org.apache.commons.logging.Log;
4   import org.apache.commons.logging.LogFactory;
5   import org.springframework.beans.factory.config.BeanDefinition;
6   import org.springframework.beans.factory.config.RuntimeBeanReference;
7   import org.springframework.beans.factory.support.ManagedList;
8   import org.springframework.beans.factory.support.RootBeanDefinition;
9   import org.springframework.beans.factory.xml.BeanDefinitionParser;
10  import org.springframework.beans.factory.xml.ParserContext;
11  import org.springframework.security.ui.rememberme.JdbcTokenRepositoryImpl;
12  import org.springframework.security.ui.rememberme.PersistentTokenBasedRememberMeServices;
13  import org.springframework.security.ui.rememberme.RememberMeProcessingFilter;
14  import org.springframework.security.ui.rememberme.TokenBasedRememberMeServices;
15  import org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider;
16  import org.springframework.util.StringUtils;
17  import org.w3c.dom.Element;
18  
19  /**
20   * @author Luke Taylor
21   * @author Ben Alex
22   * @version $Id: RememberMeBeanDefinitionParser.java 3194 2008-07-30 11:01:23Z luke_t $
23   */
24  public class RememberMeBeanDefinitionParser implements BeanDefinitionParser {
25      static final String ATT_KEY = "key";
26      static final String DEF_KEY = "SpringSecured";
27  
28      static final String ATT_DATA_SOURCE = "data-source-ref";
29      static final String ATT_SERVICES_REF = "services-ref";
30      static final String ATT_TOKEN_REPOSITORY = "token-repository-ref";
31      static final String ATT_USER_SERVICE_REF = "user-service-ref";
32      static final String ATT_TOKEN_VALIDITY = "token-validity-seconds";
33  
34      protected final Log logger = LogFactory.getLog(getClass());
35      private String servicesName;
36  
37      public BeanDefinition parse(Element element, ParserContext parserContext) {
38          String tokenRepository = null;
39          String dataSource = null;
40          String key = null;
41          Object source = null;
42          String userServiceRef = null;
43          String rememberMeServicesRef = null;
44          String tokenValiditySeconds = null;
45  
46          if (element != null) {
47              tokenRepository = element.getAttribute(ATT_TOKEN_REPOSITORY);
48              dataSource = element.getAttribute(ATT_DATA_SOURCE);
49              key = element.getAttribute(ATT_KEY);
50              userServiceRef = element.getAttribute(ATT_USER_SERVICE_REF);
51              rememberMeServicesRef = element.getAttribute(ATT_SERVICES_REF);
52              tokenValiditySeconds = element.getAttribute(ATT_TOKEN_VALIDITY);
53              source = parserContext.extractSource(element);
54          }
55          
56          if (!StringUtils.hasText(key)) {
57              key = DEF_KEY;
58          }        
59          
60          RootBeanDefinition services = null;
61  
62          boolean dataSourceSet = StringUtils.hasText(dataSource);
63          boolean tokenRepoSet = StringUtils.hasText(tokenRepository);
64          boolean servicesRefSet = StringUtils.hasText(rememberMeServicesRef);
65          boolean userServiceSet = StringUtils.hasText(userServiceRef);
66          boolean tokenValiditySet = StringUtils.hasText(tokenValiditySeconds);
67          
68          if (servicesRefSet && (dataSourceSet || tokenRepoSet || userServiceSet || tokenValiditySet)) {
69              parserContext.getReaderContext().error(ATT_SERVICES_REF + " can't be used in combination with attributes " 
70                      + ATT_TOKEN_REPOSITORY + "," + ATT_DATA_SOURCE + ", " + ATT_USER_SERVICE_REF + " or " + ATT_TOKEN_VALIDITY, source);            
71          }
72          
73          if (dataSourceSet && tokenRepoSet) {
74              parserContext.getReaderContext().error("Specify " + ATT_TOKEN_REPOSITORY + " or " + 
75                      ATT_DATA_SOURCE +" but not both", source);
76          }
77  
78          boolean isPersistent = dataSourceSet | tokenRepoSet;
79  
80          if (isPersistent) {
81              Object tokenRepo;
82              services = new RootBeanDefinition(PersistentTokenBasedRememberMeServices.class);
83  
84              if (tokenRepoSet) {
85                  tokenRepo = new RuntimeBeanReference(tokenRepository);
86              } else {
87                  tokenRepo = new RootBeanDefinition(JdbcTokenRepositoryImpl.class);
88                  ((BeanDefinition)tokenRepo).getPropertyValues().addPropertyValue("dataSource",
89                          new RuntimeBeanReference(dataSource));
90              }
91              services.getPropertyValues().addPropertyValue("tokenRepository", tokenRepo);
92          } else if (!servicesRefSet) {
93              services = new RootBeanDefinition(TokenBasedRememberMeServices.class);
94          }
95  
96          if (services != null) {
97              if (userServiceSet) {
98                  services.getPropertyValues().addPropertyValue("userDetailsService", new RuntimeBeanReference(userServiceRef));
99              }
100             
101             if (tokenValiditySet) {
102                 services.getPropertyValues().addPropertyValue("tokenValiditySeconds", new Integer(tokenValiditySeconds));
103             }
104             services.setSource(source);
105             services.getPropertyValues().addPropertyValue(ATT_KEY, key);
106             parserContext.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_SERVICES, services);
107             servicesName = BeanIds.REMEMBER_ME_SERVICES;
108         } else {
109             servicesName = rememberMeServicesRef;
110             parserContext.getRegistry().registerAlias(rememberMeServicesRef, BeanIds.REMEMBER_ME_SERVICES);
111         }
112         
113         registerProvider(parserContext, source, key);        
114         
115         registerFilter(parserContext, source);
116 
117         return null;
118     }
119     
120     String getServicesName() {
121         return servicesName;
122     }
123 
124     private void registerProvider(ParserContext pc, Object source, String key) {
125         //BeanDefinition authManager = ConfigUtils.registerProviderManagerIfNecessary(pc);
126         RootBeanDefinition provider = new RootBeanDefinition(RememberMeAuthenticationProvider.class);
127         provider.setSource(source);
128         provider.getPropertyValues().addPropertyValue(ATT_KEY, key);
129         pc.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_AUTHENTICATION_PROVIDER, provider);
130         ConfigUtils.addAuthenticationProvider(pc, BeanIds.REMEMBER_ME_AUTHENTICATION_PROVIDER);
131     }
132     
133     private void registerFilter(ParserContext pc, Object source) {
134         RootBeanDefinition filter = new RootBeanDefinition(RememberMeProcessingFilter.class);
135         filter.setSource(source);
136         filter.getPropertyValues().addPropertyValue("authenticationManager",
137                 new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));        
138         
139         filter.getPropertyValues().addPropertyValue("rememberMeServices",
140                 new RuntimeBeanReference(BeanIds.REMEMBER_ME_SERVICES));
141 
142         pc.getRegistry().registerBeanDefinition(BeanIds.REMEMBER_ME_FILTER, filter);
143         ConfigUtils.addHttpFilter(pc, new RuntimeBeanReference(BeanIds.REMEMBER_ME_FILTER));        
144     }
145 }