1 /**
2 *
3 * Copyright 2003-2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.geronimo.tomcat;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.OutputStream;
22 import java.net.URI;
23 import java.net.URISyntaxException;
24 import java.util.HashMap;
25 import java.util.Map;
26
27 import javax.servlet.ServletException;
28
29 import org.apache.catalina.authenticator.BasicAuthenticator;
30 import org.apache.catalina.authenticator.DigestAuthenticator;
31 import org.apache.catalina.authenticator.SSLAuthenticator;
32 import org.apache.catalina.connector.Request;
33 import org.apache.catalina.connector.Response;
34 import org.apache.catalina.core.StandardContext;
35 import org.apache.catalina.deploy.LoginConfig;
36 import org.apache.catalina.deploy.SecurityCollection;
37 import org.apache.catalina.deploy.SecurityConstraint;
38 import org.apache.catalina.valves.ValveBase;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.apache.geronimo.tomcat.realm.TomcatJAASRealm;
42 import org.apache.geronimo.tomcat.realm.TomcatGeronimoRealm;
43 import org.apache.geronimo.tomcat.realm.TomcatEJBWSGeronimoRealm;
44 import org.apache.geronimo.webservices.WebServiceContainer;
45
46 public class TomcatEJBWebServiceContext extends StandardContext{
47
48 private static final Log log = LogFactory.getLog(TomcatEJBWebServiceContext.class);
49
50 private final String contextPath;
51 private final WebServiceContainer webServiceContainer;
52 private final boolean isSecureTransportGuarantee;
53 private final ClassLoader classLoader;
54
55 public TomcatEJBWebServiceContext(String contextPath, WebServiceContainer webServiceContainer, String securityRealmName, String realmName, String transportGuarantee, String authMethod, ClassLoader classLoader) {
56
57 super();
58
59 this.contextPath = contextPath;
60 this.webServiceContainer = webServiceContainer;
61 this.setPath(contextPath);
62 this.setDocBase("");
63 this.setParentClassLoader(classLoader);
64 this.setDelegate(true);
65
66 log.debug("EJB Webservice Context = " + contextPath);
67 if (securityRealmName != null) {
68
69 TomcatEJBWSGeronimoRealm realm = new TomcatEJBWSGeronimoRealm();
70 realm.setAppName(securityRealmName);
71 realm.setUserClassNames("org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal");
72 realm.setRoleClassNames("org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal");
73 setRealm(realm);
74 this.realm = realm;
75
76 if ("NONE".equals(transportGuarantee)) {
77 isSecureTransportGuarantee = false;
78 } else if ("INTEGRAL".equals(transportGuarantee) ||
79 "CONFIDENTIAL".equals(transportGuarantee)) {
80 isSecureTransportGuarantee = true;
81 } else {
82 throw new IllegalArgumentException("Invalid transport-guarantee: " + transportGuarantee);
83 }
84
85 if ("BASIC".equals(authMethod) ||
86 "DIGEST".equals(authMethod) ||
87 "CLIENT-CERT".equals(authMethod)) {
88
89
90 LoginConfig loginConfig = new LoginConfig();
91 loginConfig.setAuthMethod(authMethod);
92 loginConfig.setRealmName(realmName);
93 this.setLoginConfig(loginConfig);
94
95
96 SecurityCollection collection = new SecurityCollection();
97 collection.addMethod("GET");
98 collection.addMethod("POST");
99 collection.addPattern("/*");
100 collection.setName("default");
101 SecurityConstraint sc = new SecurityConstraint();
102 sc.addAuthRole("*");
103 sc.addCollection(collection);
104 sc.setAuthConstraint(true);
105 sc.setUserConstraint(transportGuarantee);
106 this.addConstraint(sc);
107 this.addSecurityRole("default");
108
109
110 if ("BASIC".equals(authMethod) ){
111 this.addValve(new BasicAuthenticator());
112 } else if ("DIGEST".equals(authMethod) ){
113 this.addValve(new DigestAuthenticator());
114 } else if ("CLIENT-CERT".equals(authMethod) ){
115 this.addValve(new SSLAuthenticator());
116 }
117
118 } else {
119 throw new IllegalArgumentException("Invalid authMethod: " + authMethod);
120 }
121 } else {
122 isSecureTransportGuarantee = false;
123 }
124 this.classLoader = classLoader;
125 this.addValve(new EJBWebServiceValve());
126
127 }
128
129 public class EJBWebServiceValve extends ValveBase{
130
131 public void invoke(Request req, Response res) throws IOException, ServletException {
132 req.setContentType("text/xml");
133 RequestAdapter request = new RequestAdapter(req);
134 ResponseAdapter response = new ResponseAdapter(res);
135 req.finishRequest();
136 if (req.getParameter("wsdl") != null) {
137 try {
138 webServiceContainer.getWsdl(request, response);
139
140 } catch (IOException e) {
141 throw e;
142 } catch (Exception e) {
143 log.error(e);
144 res.sendError(500,"Could not fetch wsdl!");
145 return;
146 }
147 } else {
148 if (isSecureTransportGuarantee) {
149 if (!req.isSecure()) {
150 res.sendError(403);
151 return;
152 }
153 }
154 Thread currentThread = Thread.currentThread();
155 ClassLoader oldClassLoader = currentThread.getContextClassLoader();
156 currentThread.setContextClassLoader(classLoader);
157 try {
158 try {
159 webServiceContainer.invoke(request, response);
160 req.finishRequest();
161 } catch (IOException e) {
162 throw e;
163 } catch (Exception e) {
164 res.sendError(500, "Could not process message!");
165 }
166 } finally {
167 currentThread.setContextClassLoader(oldClassLoader);
168 }
169 }
170 }
171
172 }
173
174 public static class RequestAdapter implements WebServiceContainer.Request {
175 private final Request request;
176 private URI uri;
177
178 public RequestAdapter(Request request) {
179 this.request = request;
180 }
181
182 public String getHeader(String name) {
183 return request.getHeader(name);
184 }
185
186 public java.net.URI getURI() {
187 if (uri == null) {
188 try {
189 String uriString = request.getScheme() + "://" + request.getServerName() + ":" + request.getLocalPort() + request.getRequestURI();
190
191 uri = new java.net.URI(uriString);
192 } catch (URISyntaxException e) {
193 throw new IllegalStateException(e.getMessage());
194 }
195 }
196 return uri;
197 }
198
199 public int getContentLength() {
200 return request.getContentLength();
201 }
202
203 public String getContentType() {
204 return request.getContentType();
205 }
206
207 public InputStream getInputStream() throws IOException {
208 return request.getInputStream();
209 }
210
211 public int getMethod() {
212 Integer method = (Integer) methods.get(request.getMethod());
213 return method == null ? UNSUPPORTED : method.intValue();
214 }
215
216 public String getParameter(String name) {
217 return request.getParameter(name);
218 }
219
220 public Map getParameters() {
221 return request.getParameterMap();
222 }
223
224 public Object getAttribute(String name) {
225 return request.getAttribute(name);
226 }
227
228 public void setAttribute(String name, Object value) {
229 request.setAttribute(name, value);
230 }
231
232
233 private static final Map methods = new HashMap();
234
235 static {
236 methods.put("OPTIONS", new Integer(OPTIONS));
237 methods.put("GET", new Integer(GET));
238 methods.put("HEAD", new Integer(HEAD));
239 methods.put("POST", new Integer(POST));
240 methods.put("PUT", new Integer(PUT));
241 methods.put("DELETE", new Integer(DELETE));
242 methods.put("TRACE", new Integer(TRACE));
243 methods.put("CONNECT", new Integer(CONNECT));
244 }
245
246 }
247
248 public static class ResponseAdapter implements WebServiceContainer.Response {
249 private final Response response;
250
251 public ResponseAdapter(Response response) {
252 this.response = response;
253 }
254
255 public void setHeader(String name, String value) {
256 response.setHeader(name, value);
257 }
258
259 public String getHeader(String name) {
260 return response.getHeader(name);
261 }
262
263 public OutputStream getOutputStream() {
264 return response.getStream();
265 }
266
267 public void setStatusCode(int code) {
268 response.setStatus(code);
269 }
270
271 public int getStatusCode() {
272 return response.getStatus();
273 }
274
275 public void setContentType(String type) {
276 response.setContentType(type);
277 }
278
279 public String getContentType() {
280 return response.getContentType();
281 }
282
283 public void setStatusMessage(String responseString) {
284 response.setStatus(response.getStatus(), responseString);
285 }
286 }
287
288 }