%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.commons.jelly.tags.jetty.SecurityHandlerTag |
|
|
1 | /* |
|
2 | * Copyright 2002,2004 The Apache Software Foundation. |
|
3 | * |
|
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 | * you may not use this file except in compliance with the License. |
|
6 | * You may obtain a copy of the License at |
|
7 | * |
|
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 | * |
|
10 | * Unless required by applicable law or agreed to in writing, software |
|
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 | * See the License for the specific language governing permissions and |
|
14 | * limitations under the License. |
|
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,v 1.3 2002/07/14 12:38:22 dion Exp $ |
|
45 | */ |
|
46 | 1 | 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 | 2 | public SecurityHandlerTag() { |
56 | 2 | } |
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 | 2 | HttpContextTag httpContext = (HttpContextTag) findAncestorWithClass( |
97 | HttpContextTag.class); |
|
98 | 2 | if ( httpContext == null ) { |
99 | 0 | throw new JellyTagException( "<securityHandler> tag must be enclosed inside a <httpContext> tag" ); |
100 | } |
|
101 | 2 | SecurityHandler securityHandler = new SecurityHandler(); |
102 | 2 | if (getauthenticationMethod() != null) { |
103 | 0 | securityHandler.setAuthMethod(getauthenticationMethod()); |
104 | } |
|
105 | 2 | httpContext.addHandler(securityHandler); |
106 | ||
107 | // get the security constraints from the body of this tag |
|
108 | // by parsing the body of the parent (so it will be well formed) |
|
109 | 2 | String bodyText = getBodyText(); |
110 | 2 | StringReader reader = new StringReader(bodyText); |
111 | 2 | InputSource inputSource = new InputSource(reader); |
112 | ||
113 | // crate a non-validating parser |
|
114 | 2 | XmlParser xmlParser = new XmlParser(false); |
115 | ||
116 | 2 | XmlParser.Node node = null; |
117 | try { |
|
118 | 2 | node = xmlParser.parse(inputSource); |
119 | 2 | } |
120 | catch (IOException e) { |
|
121 | 0 | throw new JellyTagException(e); |
122 | } |
|
123 | catch (SAXException e) { |
|
124 | 0 | throw new JellyTagException(e); |
125 | } |
|
126 | ||
127 | 2 | Iterator iter=node.iterator(); |
128 | 2 | XmlParser.Node currNode = null; |
129 | 12 | while (iter.hasNext()) |
130 | { |
|
131 | 8 | Object o = iter.next(); |
132 | 8 | if (!(o instanceof XmlParser.Node)) |
133 | 5 | continue; |
134 | ||
135 | 3 | currNode=(XmlParser.Node)o; |
136 | 3 | String name=currNode.getTag(); |
137 | ||
138 | 3 | if ("security-constraint".equals(name)) { |
139 | 2 | initSecurityConstraint(currNode, httpContext); |
140 | 1 | } else if ("login-config".equals(name)) { |
141 | 1 | initLoginConfig(currNode, httpContext); |
142 | } else { |
|
143 | 0 | throw new JellyTagException("Invalid element in <securityHandler> tag. Are you using the <constraints> tag?: " + currNode); |
144 | } |
|
145 | } |
|
146 | ||
147 | 2 | } |
148 | ||
149 | /* ------------------------------------------------------------ |
|
150 | * This is the code from Jetty's WebApplicationContext |
|
151 | * with the HttpContextTag parameter added |
|
152 | * |
|
153 | * Process a parsed xml node to setup the security constraints |
|
154 | * for an http server |
|
155 | * |
|
156 | * @param node the parsed xml starting node of the constraints |
|
157 | * @param httpContext the tag to add the security constraint to |
|
158 | */ |
|
159 | protected void initSecurityConstraint(XmlParser.Node node, |
|
160 | HttpContextTag httpContext) |
|
161 | { |
|
162 | 2 | SecurityConstraint scBase = new SecurityConstraint(); |
163 | ||
164 | 2 | XmlParser.Node auths=node.get("auth-constraint"); |
165 | 2 | if (auths!=null) |
166 | { |
|
167 | 2 | scBase.setAuthenticate(true); |
168 | // auth-constraint |
|
169 | 2 | Iterator iter= auths.iterator("role-name"); |
170 | 5 | while(iter.hasNext()) |
171 | { |
|
172 | 1 | String role=((XmlParser.Node)iter.next()).toString(false,true); |
173 | 1 | scBase.addRole(role); |
174 | } |
|
175 | } |
|
176 | ||
177 | 2 | XmlParser.Node data=node.get("user-data-constraint"); |
178 | 2 | if (data!=null) |
179 | { |
|
180 | 0 | data=data.get("transport-guarantee"); |
181 | 0 | String guarantee = data.toString(false,true).toUpperCase(); |
182 | 0 | if (guarantee==null || guarantee.length()==0 || |
183 | "NONE".equals(guarantee)) |
|
184 | 0 | scBase.setDataConstraint(SecurityConstraint.DC_NONE); |
185 | 0 | else if ("INTEGRAL".equals(guarantee)) |
186 | 0 | scBase.setDataConstraint(SecurityConstraint.DC_INTEGRAL); |
187 | 0 | else if ("CONFIDENTIAL".equals(guarantee)) |
188 | 0 | scBase.setDataConstraint(SecurityConstraint.DC_CONFIDENTIAL); |
189 | else |
|
190 | { |
|
191 | 0 | Code.warning("Unknown user-data-constraint:"+guarantee); |
192 | 0 | scBase.setDataConstraint(SecurityConstraint.DC_CONFIDENTIAL); |
193 | } |
|
194 | } |
|
195 | ||
196 | 2 | Iterator iter= node.iterator("web-resource-collection"); |
197 | 6 | while(iter.hasNext()) |
198 | { |
|
199 | 2 | XmlParser.Node collection=(XmlParser.Node)iter.next(); |
200 | 2 | String name=collection.getString("web-resource-name",false,true); |
201 | 2 | SecurityConstraint sc = (SecurityConstraint)scBase.clone(); |
202 | 2 | sc.setName(name); |
203 | ||
204 | 2 | Iterator iter2= collection.iterator("http-method"); |
205 | 4 | while(iter2.hasNext()) |
206 | 0 | sc.addMethod(((XmlParser.Node)iter2.next()) |
207 | .toString(false,true)); |
|
208 | ||
209 | 2 | iter2= collection.iterator("url-pattern"); |
210 | 6 | while(iter2.hasNext()) |
211 | { |
|
212 | 2 | String url= |
213 | ((XmlParser.Node)iter2.next()).toString(false,true); |
|
214 | 2 | httpContext.addSecurityConstraint(url,sc); |
215 | } |
|
216 | } |
|
217 | 2 | } |
218 | ||
219 | /* ------------------------------------------------------------ |
|
220 | * This is the code from Jetty's WebApplicationContext |
|
221 | * with the HttpContextTag parameter added |
|
222 | * |
|
223 | * |
|
224 | * Process a parsed xml node to setup the authenticator and realm |
|
225 | * for an http server |
|
226 | * |
|
227 | * @param node the parsed xml starting node of the login configuration |
|
228 | * @param httpContext the tag to add the authenticator and realm to |
|
229 | */ |
|
230 | protected void initLoginConfig(XmlParser.Node node, |
|
231 | HttpContextTag httpContext) |
|
232 | { |
|
233 | 1 | XmlParser.Node method=node.get("auth-method"); |
234 | 1 | if (method!=null) |
235 | { |
|
236 | 1 | Authenticator authenticator=null; |
237 | 1 | String m=method.toString(false,true); |
238 | ||
239 | 1 | if (SecurityConstraint.__FORM_AUTH.equals(m)) |
240 | 0 | authenticator=_formAuthenticator=new FormAuthenticator(); |
241 | 1 | else if (SecurityConstraint.__BASIC_AUTH.equals(m)) |
242 | 1 | authenticator=new BasicAuthenticator(); |
243 | 0 | else if (SecurityConstraint.__DIGEST_AUTH.equals(m)) |
244 | 0 | authenticator=new DigestAuthenticator(); |
245 | 0 | else if (SecurityConstraint.__CERT_AUTH.equals(m)) |
246 | 0 | authenticator=new ClientCertAuthenticator(); |
247 | else |
|
248 | 0 | Code.warning("UNKNOWN AUTH METHOD: "+m); |
249 | ||
250 | 1 | httpContext.setAuthenticator(authenticator); |
251 | } |
|
252 | ||
253 | 1 | XmlParser.Node name=node.get("realm-name"); |
254 | 1 | if (name!=null) |
255 | 1 | httpContext.setRealmName(name.toString(false,true)); |
256 | ||
257 | 1 | XmlParser.Node formConfig = node.get("form-login-config"); |
258 | 1 | if(formConfig != null) |
259 | { |
|
260 | 0 | if (_formAuthenticator==null) |
261 | 0 | Code.warning("FORM Authentication miss-configured"); |
262 | else |
|
263 | { |
|
264 | 0 | XmlParser.Node loginPage = formConfig.get("form-login-page"); |
265 | 0 | if (loginPage != null) |
266 | 0 | _formAuthenticator.setLoginPage(loginPage.toString(false,true)); |
267 | 0 | XmlParser.Node errorPage = formConfig.get("form-error-page"); |
268 | 0 | if (errorPage != null) |
269 | 0 | _formAuthenticator.setErrorPage(errorPage.toString(false,true)); |
270 | } |
|
271 | } |
|
272 | 1 | } |
273 | ||
274 | //-------------------------------------------------------------------------- |
|
275 | // Property accessors/mutators |
|
276 | //-------------------------------------------------------------------------- |
|
277 | ||
278 | /** |
|
279 | * Getter for property authenticationMethod. |
|
280 | * |
|
281 | * @return value of property authenticationMethod. |
|
282 | */ |
|
283 | public String getauthenticationMethod() { |
|
284 | 2 | 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 | 0 | _authenticationMethod = authenticationMethod; |
295 | 0 | } |
296 | ||
297 | ||
298 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |