1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jelly.tags.jetty;
18
19 import org.apache.commons.jelly.JellyTagException;
20 import org.apache.commons.jelly.TagSupport;
21 import org.apache.commons.jelly.XMLOutput;
22
23 import org.mortbay.http.BasicAuthenticator;
24 import org.mortbay.http.ClientCertAuthenticator;
25 import org.mortbay.http.DigestAuthenticator;
26 import org.mortbay.http.SecurityConstraint.Authenticator;
27 import org.mortbay.http.SecurityConstraint;
28 import org.mortbay.http.handler.SecurityHandler;
29 import org.mortbay.jetty.servlet.FormAuthenticator;
30 import org.mortbay.util.Code;
31 import org.mortbay.xml.XmlParser;
32
33 import org.xml.sax.InputSource;
34 import org.xml.sax.SAXException;
35
36 import java.io.IOException;
37 import java.io.StringReader;
38 import java.util.Iterator;
39
40 /***
41 * Declare a security handler for a Jetty http server
42 *
43 * @author rtl
44 * @version $Id: SecurityHandlerTag.java 155420 2005-02-26 13:06:03Z dirkv $
45 */
46 public class SecurityHandlerTag extends TagSupport {
47
48 /*** a form authenticator used by this tag */
49 private transient FormAuthenticator _formAuthenticator;
50
51 /*** parameter authentication method, defaults to BASIC in Jetty */
52 private String _authenticationMethod;
53
54 /*** Creates a new instance of SecurityHandlerTag */
55 public SecurityHandlerTag() {
56 }
57
58 /***
59 * Perform the tag functionality. In this case, add a security handler
60 * to the parent context, setting the authentication method if required
61 * The security constraints should be specified as the body of this tag
62 * using the same format as a web.xml file wrapped in a single
63 * <constraints> tag to allow parsing of a well-formed snippet, e.g.
64 *
65 * <constraints>
66 * <security-constraint>
67 * <web-resource-collection>
68 * <web-resource-name>Default</web-resource-name>
69 * <url-pattern>/</url-pattern>
70 * </web-resource-collection>
71 * <auth-constraint/>
72 * </security-constraint>
73 *
74 * <security-constraint>
75 * <web-resource-collection>
76 * <url-pattern>/docRoot/resourceHandlerTest/*</url-pattern>
77 * <http-method>GET</http-method>
78 * <http-method>HEAD</http-method>
79 * </web-resource-collection>
80 * <auth-constraint>
81 * <role-name>*</role-name>
82 * </auth-constraint>
83 * </security-constraint>
84 *
85 * <login-config>
86 * <auth-method>BASIC</auth-method>
87 * <realm-name>Jetty Demo Realm</realm-name>
88 * </login-config>
89 *
90 * </constraints>
91 *
92 * @param xmlOutput where to send output
93 * @throws Exception when an error occurs
94 */
95 public void doTag(XMLOutput xmlOutput) throws JellyTagException {
96 HttpContextTag httpContext = (HttpContextTag) findAncestorWithClass(
97 HttpContextTag.class);
98 if ( httpContext == null ) {
99 throw new JellyTagException( "<securityHandler> tag must be enclosed inside a <httpContext> tag" );
100 }
101 SecurityHandler securityHandler = new SecurityHandler();
102 if (getauthenticationMethod() != null) {
103 securityHandler.setAuthMethod(getauthenticationMethod());
104 }
105 httpContext.addHandler(securityHandler);
106
107
108
109 String bodyText = getBodyText();
110 StringReader reader = new StringReader(bodyText);
111 InputSource inputSource = new InputSource(reader);
112
113
114 XmlParser xmlParser = new XmlParser(false);
115
116 XmlParser.Node node = null;
117 try {
118 node = xmlParser.parse(inputSource);
119 }
120 catch (IOException e) {
121 throw new JellyTagException(e);
122 }
123 catch (SAXException e) {
124 throw new JellyTagException(e);
125 }
126
127 Iterator iter=node.iterator();
128 XmlParser.Node currNode = null;
129 while (iter.hasNext())
130 {
131 Object o = iter.next();
132 if (!(o instanceof XmlParser.Node))
133 continue;
134
135 currNode=(XmlParser.Node)o;
136 String name=currNode.getTag();
137
138 if ("security-constraint".equals(name)) {
139 initSecurityConstraint(currNode, httpContext);
140 } else if ("login-config".equals(name)) {
141 initLoginConfig(currNode, httpContext);
142 } else {
143 throw new JellyTagException("Invalid element in <securityHandler> tag. Are you using the <constraints> tag?: " + currNode);
144 }
145 }
146
147 }
148
149
150
151
152
153
154
155
156
157
158
159 protected void initSecurityConstraint(XmlParser.Node node,
160 HttpContextTag httpContext)
161 {
162 SecurityConstraint scBase = new SecurityConstraint();
163
164 XmlParser.Node auths=node.get("auth-constraint");
165 if (auths!=null)
166 {
167 scBase.setAuthenticate(true);
168
169 Iterator iter= auths.iterator("role-name");
170 while(iter.hasNext())
171 {
172 String role=((XmlParser.Node)iter.next()).toString(false,true);
173 scBase.addRole(role);
174 }
175 }
176
177 XmlParser.Node data=node.get("user-data-constraint");
178 if (data!=null)
179 {
180 data=data.get("transport-guarantee");
181 String guarantee = data.toString(false,true).toUpperCase();
182 if (guarantee==null || guarantee.length()==0 ||
183 "NONE".equals(guarantee))
184 scBase.setDataConstraint(SecurityConstraint.DC_NONE);
185 else if ("INTEGRAL".equals(guarantee))
186 scBase.setDataConstraint(SecurityConstraint.DC_INTEGRAL);
187 else if ("CONFIDENTIAL".equals(guarantee))
188 scBase.setDataConstraint(SecurityConstraint.DC_CONFIDENTIAL);
189 else
190 {
191 Code.warning("Unknown user-data-constraint:"+guarantee);
192 scBase.setDataConstraint(SecurityConstraint.DC_CONFIDENTIAL);
193 }
194 }
195
196 Iterator iter= node.iterator("web-resource-collection");
197 while(iter.hasNext())
198 {
199 XmlParser.Node collection=(XmlParser.Node)iter.next();
200 String name=collection.getString("web-resource-name",false,true);
201 SecurityConstraint sc = (SecurityConstraint)scBase.clone();
202 sc.setName(name);
203
204 Iterator iter2= collection.iterator("http-method");
205 while(iter2.hasNext())
206 sc.addMethod(((XmlParser.Node)iter2.next())
207 .toString(false,true));
208
209 iter2= collection.iterator("url-pattern");
210 while(iter2.hasNext())
211 {
212 String url=
213 ((XmlParser.Node)iter2.next()).toString(false,true);
214 httpContext.addSecurityConstraint(url,sc);
215 }
216 }
217 }
218
219
220
221
222
223
224
225
226
227
228
229
230 protected void initLoginConfig(XmlParser.Node node,
231 HttpContextTag httpContext)
232 {
233 XmlParser.Node method=node.get("auth-method");
234 if (method!=null)
235 {
236 Authenticator authenticator=null;
237 String m=method.toString(false,true);
238
239 if (SecurityConstraint.__FORM_AUTH.equals(m))
240 authenticator=_formAuthenticator=new FormAuthenticator();
241 else if (SecurityConstraint.__BASIC_AUTH.equals(m))
242 authenticator=new BasicAuthenticator();
243 else if (SecurityConstraint.__DIGEST_AUTH.equals(m))
244 authenticator=new DigestAuthenticator();
245 else if (SecurityConstraint.__CERT_AUTH.equals(m))
246 authenticator=new ClientCertAuthenticator();
247 else
248 Code.warning("UNKNOWN AUTH METHOD: "+m);
249
250 httpContext.setAuthenticator(authenticator);
251 }
252
253 XmlParser.Node name=node.get("realm-name");
254 if (name!=null)
255 httpContext.setRealmName(name.toString(false,true));
256
257 XmlParser.Node formConfig = node.get("form-login-config");
258 if(formConfig != null)
259 {
260 if (_formAuthenticator==null)
261 Code.warning("FORM Authentication miss-configured");
262 else
263 {
264 XmlParser.Node loginPage = formConfig.get("form-login-page");
265 if (loginPage != null)
266 _formAuthenticator.setLoginPage(loginPage.toString(false,true));
267 XmlParser.Node errorPage = formConfig.get("form-error-page");
268 if (errorPage != null)
269 _formAuthenticator.setErrorPage(errorPage.toString(false,true));
270 }
271 }
272 }
273
274
275
276
277
278 /***
279 * Getter for property authenticationMethod.
280 *
281 * @return value of property authenticationMethod.
282 */
283 public String getauthenticationMethod() {
284 return _authenticationMethod;
285 }
286
287 /***
288 * Setter for property authenticationMethod.
289 *
290 * @param authenticationMethod Type of authentication (BASIC, FORM, DIGEST, CLIENT-CERT)
291 * Note that only BASIC and CLIENT-CERT are supported by Jetty as of v4.1.1
292 */
293 public void setauthenticationMethod(String authenticationMethod) {
294 _authenticationMethod = authenticationMethod;
295 }
296
297
298 }