View Javadoc

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                  //Setup a login configuration
90                  LoginConfig loginConfig = new LoginConfig();
91                  loginConfig.setAuthMethod(authMethod);
92                  loginConfig.setRealmName(realmName);
93                  this.setLoginConfig(loginConfig);
94  
95                  //Setup a default Security Constraint
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                 //Set the proper authenticator
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                     //WHO IS RESPONSIBLE FOR CLOSING OUT?
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                     //return new java.net.URI(uri.getScheme(),uri.getHost(),uri.getPath(),uri.);
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 }