Source code: org/securityfilter/config/SecurityConfig.java
1 /*
2 * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/config/SecurityConfig.java,v 1.13 2003/10/25 11:58:55 maxcooper Exp $
3 * $Revision: 1.13 $
4 * $Date: 2003/10/25 11:58:55 $
5 *
6 * ====================================================================
7 * The SecurityFilter Software License, Version 1.1
8 *
9 * (this license is derived and fully compatible with the Apache Software
10 * License - see http://www.apache.org/LICENSE.txt)
11 *
12 * Copyright (c) 2002 SecurityFilter.org. All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in
23 * the documentation and/or other materials provided with the
24 * distribution.
25 *
26 * 3. The end-user documentation included with the redistribution,
27 * if any, must include the following acknowledgment:
28 * "This product includes software developed by
29 * SecurityFilter.org (http://www.securityfilter.org/)."
30 * Alternately, this acknowledgment may appear in the software itself,
31 * if and wherever such third-party acknowledgments normally appear.
32 *
33 * 4. The name "SecurityFilter" must not be used to endorse or promote
34 * products derived from this software without prior written permission.
35 * For written permission, please contact license@securityfilter.org .
36 *
37 * 5. Products derived from this software may not be called "SecurityFilter",
38 * nor may "SecurityFilter" appear in their name, without prior written
39 * permission of SecurityFilter.org.
40 *
41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 * DISCLAIMED. IN NO EVENT SHALL THE SECURITY FILTER PROJECT OR
45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 * SUCH DAMAGE.
53 * ====================================================================
54 */
55
56 package org.securityfilter.config;
57
58 import org.apache.commons.digester.Digester;
59 import org.securityfilter.realm.SecurityRealmInterface;
60 import org.xml.sax.InputSource;
61 import org.xml.sax.SAXException;
62
63 import java.io.IOException;
64 import java.lang.reflect.InvocationTargetException;
65 import java.lang.reflect.Method;
66 import java.net.URL;
67 import java.util.ArrayList;
68 import java.util.List;
69
70 /**
71 * SecurityConfig gathers information from the security-config.xml file to be used by the filter.
72 *
73 * @author Torgeir Veimo (torgeir@pobox.com)
74 * @author Max Cooper (max@maxcooper.com)
75 * @author Daya Sharma (iamdaya@yahoo.com, billydaya@sbcglobal.net)
76 * @version $Revision: 1.13 $ $Date: 2003/10/25 11:58:55 $
77 */
78 public class SecurityConfig {
79
80 private String loginPage = null;
81 private String errorPage = null;
82 private String defaultPage = null;
83 private ArrayList securityConstraints = null;
84 private SecurityRealmInterface realm = null;
85 private Object lastRealm = null;
86 private boolean validating;
87 private String authMethod;
88 private String realmName;
89
90 /**
91 * Constructor that takes the validating flag and debug level to be used while parsing.
92 *
93 * @param validating validate the input file, true = validate, false = don't validate
94 */
95 public SecurityConfig(boolean validating) {
96 this.validating = validating;
97 }
98
99 /**
100 * Return the login page URL.
101 */
102 public String getLoginPage() {
103 return loginPage;
104 }
105
106 /**
107 * Set the login page URL. This is the page the user will be sent to to log in (i.e. the login form).
108 *
109 * @param loginPage The login page url (relative to site root)
110 */
111 public void setLoginPage(String loginPage) {
112 this.loginPage = loginPage;
113 }
114
115 /**
116 * Return the error page URL.
117 */
118 public String getErrorPage() {
119 return errorPage;
120 }
121
122 /**
123 * Set the error page URL. This is the page the user will be sent to if login request fails.
124 *
125 * @param errorPage The login page URL (relative to site root)
126 */
127 public void setErrorPage(String errorPage) {
128 this.errorPage = errorPage;
129 }
130
131 /**
132 * Return the default page URL.
133 */
134 public String getDefaultPage() {
135 return defaultPage;
136 }
137
138 /**
139 * Set the default page URL. This is the page the user will be sent to if they submit a login request without
140 * being forced to the login page by the filter.
141 *
142 * @param defaultPage The default page URL (relative to site root)
143 */
144 public void setDefaultPage(String defaultPage) {
145 this.defaultPage = defaultPage;
146 }
147
148 /**
149 * Get the authentication method being used to challenge the user.
150 * Currently, only BASIC and FORM based are supported.
151 *
152 * @return BASIC or FORM
153 */
154 public String getAuthMethod() {
155 return authMethod;
156 }
157
158 /**
159 * Set the authentication method being used to challenge the user.
160 * Currently, only BASIC and FORM based are supported.
161 *
162 * @param authMethod The authentication method to be used by the filter
163 */
164 public void setAuthMethod(String authMethod) {
165 this.authMethod = authMethod;
166 }
167
168 /**
169 * Get the authentication realm name.
170 * This is used for BASIC authentication.
171 *
172 * @return the realm-name configured by the application developer
173 */
174 public String getRealmName() {
175 return realmName;
176 }
177
178 /**
179 * Set the authentication realm name.
180 * This is used for BASIC authentication.
181 *
182 * @param realmName the realm name to be used for BASIC authentication
183 */
184 public void setRealmName(String realmName) {
185 this.realmName = realmName;
186 }
187
188 /**
189 * Return the realm to use for authentication. This is the outer-most realm if nested realms are used.
190 * The outer-most realm must be listed first in the configuration file.
191 */
192 public SecurityRealmInterface getRealm() {
193 return realm;
194 }
195
196 /**
197 * Adds a realm to use for authentication.
198 *
199 * The first time this method is called, the realm must implement SecurityRealmInterface.
200 * Subsequent calls can be any kind of object, and setRealm(realm) will be called on the
201 * last realm passed to this method. This allows nesting of realms for caching or when a
202 * realm adapter is used.
203 *
204 * @param realm The realm to use, or nest in deeper realm
205 */
206 public synchronized void addRealm(
207 Object realm
208 ) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
209 if (this.realm == null) {
210 this.realm = (SecurityRealmInterface) realm;
211 lastRealm = realm;
212 } else {
213 // TODO: allow addRealm signaure to take types besides Object -- will commons-beanutils help?
214 // call lastRealm.setRealm(realm)
215 Method addMethod = lastRealm.getClass().getMethod("setRealm", new Class[] { Object.class });
216 addMethod.invoke(lastRealm, new Object[] { realm });
217 lastRealm = realm;
218 }
219 }
220
221 /**
222 * Return the configured SecurityConstraints.
223 */
224 public List getSecurityConstraints() {
225 return this.securityConstraints;
226 }
227
228 /**
229 * Adds a SecurityConstraint.
230 *
231 * @param constraint The SecurityConstraint to add
232 */
233 public void addSecurityConstraint(SecurityConstraint constraint) {
234 securityConstraints.add(constraint);
235 }
236
237 /**
238 * Loads configuration from the specifued configURL.
239 *
240 * @param configURL The url to load.
241 *
242 * @exception IOException if an input/output error occurs
243 * @exception SAXException if the file has invalid xml syntax
244 */
245 public void loadConfig(URL configURL) throws IOException, SAXException {
246
247 securityConstraints = new ArrayList();
248
249 Digester digester = new Digester();
250
251 // only register the DTDs if we will be validating
252 registerLocalDTDs(digester);
253
254 digester.push(this);
255 digester.setUseContextClassLoader(true);
256 digester.setValidating(validating);
257
258 // realms
259 digester.addObjectCreate("securityfilter-config/realm", null, "className");
260 digester.addSetProperty("securityfilter-config/realm/realm-param", "name", "value");
261 digester.addSetNext("securityfilter-config/realm", "addRealm", "java.lang.Object");
262
263 // login and error pages
264 digester.addCallMethod("securityfilter-config/login-config/auth-method", "setAuthMethod", 0);
265 digester.addCallMethod("securityfilter-config/login-config/realm-name", "setRealmName", 0);
266 digester.addCallMethod("securityfilter-config/login-config/form-login-config/form-login-page", "setLoginPage", 0);
267 digester.addCallMethod("securityfilter-config/login-config/form-login-config/form-error-page", "setErrorPage", 0);
268 digester.addCallMethod(
269 "securityfilter-config/login-config/form-login-config/form-default-page",
270 "setDefaultPage",
271 0
272 );
273
274 // security-constraint
275 digester.addObjectCreate(
276 "securityfilter-config/security-constraint",
277 "org.securityfilter.config.SecurityConstraint"
278 );
279 digester.addSetNext(
280 "securityfilter-config/security-constraint",
281 "addSecurityConstraint",
282 "org.securityfilter.config.SecurityConstraint"
283 );
284
285 // auth-constraint
286 digester.addObjectCreate(
287 "securityfilter-config/security-constraint/auth-constraint",
288 "org.securityfilter.config.AuthConstraint"
289 );
290 digester.addSetNext(
291 "securityfilter-config/security-constraint/auth-constraint",
292 "setAuthConstraint",
293 "org.securityfilter.config.AuthConstraint"
294 );
295 digester.addCallMethod(
296 "securityfilter-config/security-constraint/auth-constraint/role-name",
297 "addRole",
298 0
299 );
300
301 // web-resource-collection
302 digester.addObjectCreate(
303 "securityfilter-config/security-constraint/web-resource-collection",
304 "org.securityfilter.config.WebResourceCollection"
305 );
306 digester.addSetNext(
307 "securityfilter-config/security-constraint/web-resource-collection",
308 "addWebResourceCollection",
309 "org.securityfilter.config.WebResourceCollection"
310 );
311 digester.addCallMethod(
312 "securityfilter-config/security-constraint/web-resource-collection/url-pattern",
313 "addURLPattern",
314 0
315 );
316 digester.addCallMethod(
317 "securityfilter-config/security-constraint/web-resource-collection/http-method",
318 "addHttpMethod",
319 0
320 );
321
322 InputSource input = new InputSource(configURL.openStream());
323 digester.parse(input);
324 }
325
326 /**
327 * Register local copies of the SecurityFilter DTD files.
328 *
329 * @param digester
330 */
331 protected void registerLocalDTDs(Digester digester) {
332 // register the local version of the 1.0 DTD, if it is available
333 URL dtd1_0 = this.getClass().getResource("/org/securityfilter/resources/securityfilter-config_1_0.dtd");
334 if (dtd1_0 != null) {
335 digester.register("-//SecurityFilter.org//DTD Security Filter Configuration 1.0//EN", dtd1_0.toString());
336 }
337
338 // register the local version of the 1.1 DTD, if it is available
339 URL dtd1_1 = this.getClass().getResource("/org/securityfilter/resources/securityfilter-config_1_1.dtd");
340 if (dtd1_1 != null) {
341 digester.register("-//SecurityFilter.org//DTD Security Filter Configuration 1.1//EN", dtd1_1.toString());
342 }
343 }
344 }
345
346 // ------------------------------------------------------------------------
347 // EOF