001: /**
002: *
003: */package org.acegisecurity.config;
004:
005: import org.acegisecurity.providers.dao.DaoAuthenticationProvider;
006: import org.acegisecurity.providers.dao.salt.ReflectionSaltSource;
007: import org.acegisecurity.providers.dao.salt.SystemWideSaltSource;
008: import org.acegisecurity.providers.encoding.Md5PasswordEncoder;
009: import org.springframework.beans.factory.config.BeanDefinitionHolder;
010: import org.springframework.beans.factory.config.RuntimeBeanReference;
011: import org.springframework.beans.factory.support.AbstractBeanDefinition;
012: import org.springframework.beans.factory.support.ManagedList;
013: import org.springframework.beans.factory.support.RootBeanDefinition;
014: import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
015: import org.springframework.beans.factory.xml.ParserContext;
016: import org.springframework.util.Assert;
017: import org.springframework.util.StringUtils;
018: import org.springframework.util.xml.DomUtils;
019: import org.w3c.dom.Element;
020: import org.w3c.dom.Node;
021: import org.w3c.dom.NodeList;
022:
023: /**
024: * @author vpuri
025: *
026: */
027: public class AuthenticationRepositoryBeanDefinitionParser extends
028: AbstractBeanDefinitionParser {
029:
030: // ~ Static fields
031: // =====================================================================================
032:
033: private static final String REPOSITORY_BEAN_REF = "repositoryBeanRef";
034:
035: private static final String USER_DETAILS_SERVICE = "userDetailsService";
036:
037: private static final String SALT_SOURCE_ELEMENT = "salt-source";
038:
039: private static final String SALT_SOURCE_REF = "saltSourceBeanRef";
040:
041: private static final String SYSTEM_WIDE_SALT_SOURCE = "system-wide";
042:
043: private static final String REFLECTION_SALT_SOURCE = "reflection";
044:
045: private static final String PASSWORD_ENCODER_ELEMENT = "password-encoder";
046:
047: private static final String PASSWORD_ENCODER_REF = "encoderBeanRef";
048:
049: private static final String PASSWORD_ENCODER = "encoder";
050:
051: // ~ Method
052: // ================================================================================================
053:
054: public AbstractBeanDefinition parseInternal(Element element,
055: ParserContext parserContext) {
056: Assert.notNull(parserContext, "ParserContext must not be null");
057:
058: RootBeanDefinition repositoryBeanDef = new RootBeanDefinition(
059: DaoAuthenticationProvider.class);
060:
061: // check if saltSource is defined
062: Element saltSourceEle = DomUtils.getChildElementByTagName(
063: element, SALT_SOURCE_ELEMENT);
064: setSaltSourceProperty(repositoryBeanDef, saltSourceEle);
065:
066: Element passwordEncoderEle = DomUtils.getChildElementByTagName(
067: element, PASSWORD_ENCODER_ELEMENT);
068: setPasswordEncoderProperty(repositoryBeanDef,
069: passwordEncoderEle);
070:
071: // if repositoryBeanRef is specified use its referred bean
072: String userDetailsRef = element
073: .getAttribute(REPOSITORY_BEAN_REF);
074: if (StringUtils.hasLength(userDetailsRef)) {
075: repositoryBeanDef.getPropertyValues().addPropertyValue(
076: USER_DETAILS_SERVICE,
077: new RuntimeBeanReference(userDetailsRef));
078: }
079: return repositoryBeanDef;
080: }
081:
082: /**
083: *
084: * @param repositoryBeanDef
085: * @param element
086: */
087: private void setSaltSourceProperty(
088: RootBeanDefinition repositoryBeanDef, Element element) {
089: if (element != null) {
090: setBeanReferenceOrInnerBeanDefinitions(repositoryBeanDef,
091: element, "saltSource", element
092: .getAttribute(SALT_SOURCE_REF));
093: }
094: }
095:
096: /**
097: *
098: * @param repositoryBeanDef
099: * @param element
100: */
101: private void setPasswordEncoderProperty(
102: RootBeanDefinition repositoryBeanDef, Element element) {
103: if (element != null) {
104: setBeanReferenceOrInnerBeanDefinitions(repositoryBeanDef,
105: element, "passwordEncoder", element
106: .getAttribute(PASSWORD_ENCODER_REF));
107: }
108: }
109:
110: /**
111: *
112: * @param repositoryBeanDef
113: * @param element
114: * @param property
115: * @param reference
116: */
117: private void setBeanReferenceOrInnerBeanDefinitions(
118: RootBeanDefinition repositoryBeanDef, Element element,
119: String property, String reference) {
120: // check for encoderBeanRef attribute
121: if (StringUtils.hasLength(reference)) {
122: repositoryBeanDef.getPropertyValues().addPropertyValue(
123: property, new RuntimeBeanReference(reference));
124: } else {
125: doSetInnerBeanDefinitions(repositoryBeanDef, element,
126: property);
127: }
128: }
129:
130: /**
131: *
132: * @param repositoryBeanDef
133: * @param element
134: * @param property
135: */
136: private void doSetInnerBeanDefinitions(
137: RootBeanDefinition repositoryBeanDef, Element element,
138: String property) {
139: NodeList children = element.getChildNodes();
140: for (int i = 0, n = children.getLength(); i < n; i++) {
141: Node node = children.item(i);
142:
143: if (node.getNodeType() == Node.ELEMENT_NODE) {
144: Element childElement = (Element) node;
145: RootBeanDefinition innerBeanDefinition = null;
146:
147: if (SYSTEM_WIDE_SALT_SOURCE.equals(node.getLocalName())) {
148: innerBeanDefinition = createSystemWideSaltSource(childElement);
149: repositoryBeanDef.getPropertyValues()
150: .addPropertyValue(property,
151: innerBeanDefinition);
152: } else if (REFLECTION_SALT_SOURCE.equals(node
153: .getLocalName())) {
154: innerBeanDefinition = createReflectionSaltSource(childElement);
155: repositoryBeanDef.getPropertyValues()
156: .addPropertyValue(property,
157: innerBeanDefinition);
158: }
159: if (PASSWORD_ENCODER.equals(node.getLocalName())) {
160: RootBeanDefinition passwordEncoderInnerBeanDefinition = createPasswordEncoder(childElement);
161: repositoryBeanDef.getPropertyValues()
162: .addPropertyValue(property,
163: passwordEncoderInnerBeanDefinition);
164: }
165: }
166: }
167: }
168:
169: /**
170: *
171: * @param childElement
172: * @return
173: */
174: private RootBeanDefinition createPasswordEncoder(
175: Element childElement) {
176: String attributeValue = childElement.getAttribute("method");
177: RootBeanDefinition definition = null;
178: // TODO: add other encoders support
179: if (attributeValue.equals("md5")) {
180: definition = new RootBeanDefinition(
181: Md5PasswordEncoder.class);
182: }
183: return definition;
184: }
185:
186: /**
187: *
188: * @param saltSourceTypeElement
189: * @return
190: */
191: private RootBeanDefinition createReflectionSaltSource(
192: Element saltSourceTypeElement) {
193: RootBeanDefinition definition = new RootBeanDefinition(
194: ReflectionSaltSource.class);
195: definition.getPropertyValues()
196: .addPropertyValue(
197: "userPropertyToUse",
198: saltSourceTypeElement
199: .getAttribute("userPropertyToUse"));
200: return definition;
201: }
202:
203: /**
204: *
205: * @param saltSourceTypeElement
206: * @return
207: */
208: private RootBeanDefinition createSystemWideSaltSource(
209: Element saltSourceTypeElement) {
210: RootBeanDefinition definition = new RootBeanDefinition(
211: SystemWideSaltSource.class);
212: definition.getPropertyValues().addPropertyValue(
213: "systemWideSalt",
214: saltSourceTypeElement.getAttribute("systemWideSalt"));
215: return definition;
216: }
217:
218: protected static RootBeanDefinition createBeanDefinitionWithDefaults() {
219: RootBeanDefinition repositoryBeanDef = new RootBeanDefinition(
220: DaoAuthenticationProvider.class);
221: return repositoryBeanDef;
222: }
223:
224: }
|