001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.tomcat;
017:
018: import java.io.IOException;
019: import java.io.InputStream;
020: import java.io.OutputStream;
021: import java.net.URI;
022: import java.net.URISyntaxException;
023: import java.util.HashMap;
024: import java.util.Map;
025:
026: import javax.servlet.ServletException;
027: import javax.servlet.http.HttpServlet;
028: import javax.servlet.http.HttpServletRequest;
029: import javax.servlet.http.HttpServletResponse;
030:
031: import org.apache.catalina.Wrapper;
032: import org.apache.catalina.authenticator.BasicAuthenticator;
033: import org.apache.catalina.authenticator.DigestAuthenticator;
034: import org.apache.catalina.authenticator.NonLoginAuthenticator;
035: import org.apache.catalina.authenticator.SSLAuthenticator;
036: import org.apache.catalina.connector.Request;
037: import org.apache.catalina.connector.Response;
038: import org.apache.catalina.core.StandardContext;
039: import org.apache.catalina.deploy.LoginConfig;
040: import org.apache.catalina.deploy.SecurityCollection;
041: import org.apache.catalina.deploy.SecurityConstraint;
042: import org.apache.catalina.valves.ValveBase;
043: import org.apache.commons.logging.Log;
044: import org.apache.commons.logging.LogFactory;
045: import org.apache.geronimo.tomcat.realm.TomcatEJBWSGeronimoRealm;
046: import org.apache.geronimo.webservices.WebServiceContainer;
047:
048: public class TomcatEJBWebServiceContext extends StandardContext {
049:
050: private static final Log log = LogFactory
051: .getLog(TomcatEJBWebServiceContext.class);
052:
053: private final String contextPath;
054: private final WebServiceContainer webServiceContainer;
055: private final boolean isSecureTransportGuarantee;
056: private final ClassLoader classLoader;
057:
058: public TomcatEJBWebServiceContext(String contextPath,
059: WebServiceContainer webServiceContainer,
060: String securityRealmName, String realmName,
061: String transportGuarantee, String authMethod,
062: ClassLoader classLoader) {
063:
064: super ();
065:
066: this .contextPath = contextPath;
067: this .webServiceContainer = webServiceContainer;
068: this .setPath(contextPath);
069: this .setDocBase("");
070: this .setParentClassLoader(classLoader);
071: this .setDelegate(true);
072:
073: log.debug("EJB Webservice Context = " + contextPath);
074: if (securityRealmName != null) {
075:
076: TomcatEJBWSGeronimoRealm realm = new TomcatEJBWSGeronimoRealm();
077: realm.setAppName(securityRealmName);
078: realm
079: .setUserClassNames("org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal");
080: realm
081: .setRoleClassNames("org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal");
082: setRealm(realm);
083: this .realm = realm;
084:
085: if ("NONE".equals(transportGuarantee)) {
086: isSecureTransportGuarantee = false;
087: } else if ("INTEGRAL".equals(transportGuarantee)
088: || "CONFIDENTIAL".equals(transportGuarantee)) {
089: isSecureTransportGuarantee = true;
090: } else {
091: throw new IllegalArgumentException(
092: "Invalid transport-guarantee: "
093: + transportGuarantee);
094: }
095:
096: if ("NONE".equals(authMethod) || "BASIC".equals(authMethod)
097: || "DIGEST".equals(authMethod)
098: || "CLIENT-CERT".equals(authMethod)) {
099:
100: //Setup a login configuration
101: LoginConfig loginConfig = new LoginConfig();
102: loginConfig.setAuthMethod(authMethod);
103: loginConfig.setRealmName(realmName);
104: this .setLoginConfig(loginConfig);
105:
106: //Setup a default Security Constraint
107: SecurityCollection collection = new SecurityCollection();
108: collection.addMethod("GET");
109: collection.addMethod("POST");
110: collection.addPattern("/*");
111: collection.setName("default");
112: SecurityConstraint sc = new SecurityConstraint();
113: sc.addAuthRole("*");
114: sc.addCollection(collection);
115: sc.setAuthConstraint(true);
116: sc.setUserConstraint(transportGuarantee);
117: this .addConstraint(sc);
118: this .addSecurityRole("default");
119:
120: //Set the proper authenticator
121: if ("BASIC".equals(authMethod)) {
122: this .addValve(new BasicAuthenticator());
123: } else if ("DIGEST".equals(authMethod)) {
124: this .addValve(new DigestAuthenticator());
125: } else if ("CLIENT-CERT".equals(authMethod)) {
126: this .addValve(new SSLAuthenticator());
127: } else if ("NONE".equals(authMethod)) {
128: this .addValve(new NonLoginAuthenticator());
129: }
130:
131: } else {
132: throw new IllegalArgumentException(
133: "Invalid authMethod: " + authMethod);
134: }
135: } else {
136: isSecureTransportGuarantee = false;
137: }
138:
139: this .classLoader = classLoader;
140: this .addValve(new EJBWebServiceValve());
141:
142: //Create a dummy wrapper
143: Wrapper wrapper = this .createWrapper();
144: String name = System.currentTimeMillis() + "";
145: wrapper.setName(name);
146: this .addChild(wrapper);
147: this .addServletMapping("/*", name);
148:
149: }
150:
151: public class EJBWebServiceValve extends ValveBase {
152:
153: public void invoke(Request req, Response res)
154: throws IOException, ServletException {
155: res.setContentType("text/xml");
156: RequestAdapter request = new RequestAdapter(req);
157: ResponseAdapter response = new ResponseAdapter(res);
158:
159: request.setAttribute(WebServiceContainer.SERVLET_REQUEST,
160: (HttpServletRequest) req);
161: request.setAttribute(WebServiceContainer.SERVLET_RESPONSE,
162: (HttpServletResponse) res);
163: // TODO: add support for context
164: request.setAttribute(WebServiceContainer.SERVLET_CONTEXT,
165: null);
166:
167: req.finishRequest();
168: if (req.getParameter("wsdl") != null) {
169: try {
170: webServiceContainer.getWsdl(request, response);
171: //WHO IS RESPONSIBLE FOR CLOSING OUT?
172: } catch (IOException e) {
173: throw e;
174: } catch (Exception e) {
175: log.error(e);
176: res.sendError(500, "Could not fetch wsdl!");
177: return;
178: }
179: } else {
180: if (isSecureTransportGuarantee) {
181: if (!req.isSecure()) {
182: res.sendError(403);
183: return;
184: }
185: }
186: Thread currentThread = Thread.currentThread();
187: ClassLoader oldClassLoader = currentThread
188: .getContextClassLoader();
189: currentThread.setContextClassLoader(classLoader);
190: try {
191: try {
192: webServiceContainer.invoke(request, response);
193: req.finishRequest();
194: } catch (IOException e) {
195: throw e;
196: } catch (Exception e) {
197: res
198: .sendError(500,
199: "Could not process message!");
200: }
201: } finally {
202: currentThread.setContextClassLoader(oldClassLoader);
203: }
204: }
205: }
206:
207: }
208:
209: public static class RequestAdapter implements
210: WebServiceContainer.Request {
211: private final Request request;
212: private URI uri;
213:
214: public RequestAdapter(Request request) {
215: this .request = request;
216: }
217:
218: public String getHeader(String name) {
219: return request.getHeader(name);
220: }
221:
222: public java.net.URI getURI() {
223: if (uri == null) {
224: try {
225: //String uriString = request.getScheme() + "://" + request.getServerName() + ":" + request.getLocalPort() + request.getRequestURI();
226: //return new java.net.URI(uri.getScheme(),uri.getHost(),uri.getPath(),uri.);
227: uri = new java.net.URI(request.getScheme(), null,
228: request.getServerName(), request
229: .getServerPort(), request
230: .getRequestURI(), request
231: .getQueryString(), null);
232: } catch (URISyntaxException e) {
233: throw new IllegalStateException(e.getMessage(), e);
234: }
235: }
236: return uri;
237: }
238:
239: public int getContentLength() {
240: return request.getContentLength();
241: }
242:
243: public String getContentType() {
244: return request.getContentType();
245: }
246:
247: public InputStream getInputStream() throws IOException {
248: return request.getInputStream();
249: }
250:
251: public int getMethod() {
252: Integer method = (Integer) methods.get(request.getMethod());
253: return method == null ? UNSUPPORTED : method.intValue();
254: }
255:
256: public String getParameter(String name) {
257: return request.getParameter(name);
258: }
259:
260: public Map getParameters() {
261: return request.getParameterMap();
262: }
263:
264: public Object getAttribute(String name) {
265: return request.getAttribute(name);
266: }
267:
268: public void setAttribute(String name, Object value) {
269: request.setAttribute(name, value);
270: }
271:
272: public String getRemoteAddr() {
273: return request.getRemoteAddr();
274: }
275:
276: public String getContextPath() {
277: return request.getContextPath();
278: }
279:
280: private static final Map methods = new HashMap();
281:
282: static {
283: methods.put("OPTIONS", new Integer(OPTIONS));
284: methods.put("GET", new Integer(GET));
285: methods.put("HEAD", new Integer(HEAD));
286: methods.put("POST", new Integer(POST));
287: methods.put("PUT", new Integer(PUT));
288: methods.put("DELETE", new Integer(DELETE));
289: methods.put("TRACE", new Integer(TRACE));
290: methods.put("CONNECT", new Integer(CONNECT));
291: }
292:
293: }
294:
295: public static class ResponseAdapter implements
296: WebServiceContainer.Response {
297: private final Response response;
298:
299: public ResponseAdapter(Response response) {
300: this .response = response;
301: }
302:
303: public void setHeader(String name, String value) {
304: response.setHeader(name, value);
305: }
306:
307: public String getHeader(String name) {
308: return response.getHeader(name);
309: }
310:
311: public OutputStream getOutputStream() {
312: return response.getStream();
313: }
314:
315: public void setStatusCode(int code) {
316: response.setStatus(code);
317: }
318:
319: public int getStatusCode() {
320: return response.getStatus();
321: }
322:
323: public void setContentType(String type) {
324: response.setContentType(type);
325: }
326:
327: public String getContentType() {
328: return response.getContentType();
329: }
330:
331: public void setStatusMessage(String responseString) {
332: response.setStatus(response.getStatus(), responseString);
333: }
334:
335: public void flushBuffer() throws java.io.IOException {
336: response.flushBuffer();
337: }
338:
339: }
340:
341: }
|