1 23 24 package com.sun.enterprise.webservice; 25 26 import java.io.IOException ; 27 import java.util.logging.Logger ; 28 import java.util.logging.Level ; 29 import java.security.cert.X509Certificate ; 30 31 import javax.servlet.ServletException ; 32 import javax.servlet.http.HttpServlet ; 33 import javax.servlet.http.HttpServletRequest ; 34 import javax.servlet.http.HttpServletResponse ; 35 36 import com.sun.enterprise.Switch; 37 import com.sun.ejb.Container; 38 import com.sun.enterprise.security.SecurityContext; 39 import com.sun.enterprise.deployment.Application; 40 import com.sun.enterprise.deployment.WebServiceEndpoint; 41 import com.sun.enterprise.webservice.EjbWebServiceDispatcher; 42 import com.sun.enterprise.webservice.EjbRuntimeEndpointInfo; 43 import com.sun.enterprise.webservice.WebServiceEjbEndpointRegistry; 44 import com.sun.enterprise.webservice.monitoring.WebServiceTesterServlet; 45 import com.sun.enterprise.webservice.monitoring.Endpoint; 46 import com.sun.enterprise.webservice.monitoring.EndpointType; 47 import com.sun.enterprise.webservice.monitoring.AuthenticationListener; 48 import com.sun.enterprise.webservice.monitoring.WebServiceEngineImpl; 49 import com.sun.web.security.WebPrincipal; 50 import com.sun.web.security.RealmAdapter; 51 import com.sun.logging.LogDomains; 52 import com.sun.enterprise.security.audit.AuditManager; 53 import com.sun.enterprise.security.audit.AuditManagerFactory; 54 55 import org.apache.catalina.Loader; 56 import org.apache.catalina.Globals; 57 import org.apache.catalina.util.Base64; 58 59 69 public class EjbWebServiceServlet extends HttpServlet { 70 71 private static Logger logger 72 = LogDomains.getLogger(LogDomains.EJB_LOGGER); 73 private static final Base64 base64Helper = new Base64(); 74 private static final String AUTHORIZATION_HEADER = "authorization"; 75 76 private static AuditManager auditManager = 77 AuditManagerFactory.getAuditManagerInstance(); 78 79 protected void service(HttpServletRequest hreq, HttpServletResponse hresp) 80 throws ServletException , IOException { 81 82 boolean dispatch = true; 83 84 String requestUriRaw = hreq.getRequestURI(); 85 String requestUri = (requestUriRaw.charAt(0) == '/') ? 86 requestUriRaw.substring(1) : requestUriRaw; 87 String query = hreq.getQueryString(); 88 89 if ("Tester".equalsIgnoreCase(query)) { 91 Endpoint endpoint = WebServiceEngineImpl.getInstance().getEndpoint(hreq.getRequestURL().toString()); 92 if( (endpoint.getDescriptor().isSecure()) || 93 (endpoint.getDescriptor().getMessageSecurityBinding() != null) ) { 94 String message = endpoint.getDescriptor().getWebService().getName() + 96 " is a secured webservice; Tester feature is not supported for secured services"; 97 (new WsUtil()).writeInvalidMethodType(hresp, message); 98 return; 99 } 100 if (endpoint!=null && Boolean.parseBoolean(endpoint.getDescriptor().getDebugging())) { 101 dispatch = false; 102 WebServiceTesterServlet.invoke(hreq, hresp, 103 endpoint.getDescriptor()); 104 } 105 } 106 107 if (dispatch) { 108 EjbRuntimeEndpointInfo ejbEndpoint = 109 WebServiceEjbEndpointRegistry.getRegistry().getEjbWebServiceEndpoint(requestUri, hreq.getMethod(), query); 110 111 if (ejbEndpoint != null) { 112 117 dispatchToEjbEndpoint(hreq, hresp, ejbEndpoint); 118 } 119 } 120 } 121 122 123 private void dispatchToEjbEndpoint(HttpServletRequest hreq, 124 HttpServletResponse hresp, 125 EjbRuntimeEndpointInfo ejbEndpoint) { 126 127 String scheme = hreq.getScheme(); 128 String expectedScheme = ejbEndpoint.getEndpoint().isSecure() ? 129 "https" : "http"; 130 131 if( !expectedScheme.equalsIgnoreCase(scheme) ) { 132 logger.log(Level.WARNING, "Invalid request scheme for Endpoint " + 133 ejbEndpoint.getEndpoint().getEndpointName() + ". " + 134 "Expected " + expectedScheme + " . Received " + scheme); 135 return; 136 } 137 138 Switch theSwitch = Switch.getSwitch(); 139 Container container = ejbEndpoint.getContainer(); 140 141 boolean authenticated = false; 142 try { 143 container.externalPreInvoke(); 145 146 String realmName = ejbEndpoint.getEndpoint().getRealm(); 148 if (realmName == null) { 149 Application app = ejbEndpoint.getEndpoint().getBundleDescriptor().getApplication(); 150 if (app != null) { 151 realmName = app.getRealm(); 152 } 153 } 154 if (realmName == null) { 155 realmName = hreq.getServerName() + ":" + hreq.getServerPort(); 157 } 158 159 try { 160 authenticated = doSecurity(hreq, ejbEndpoint, realmName); 161 } catch(Exception e) { 162 sendAuthenticationEvents(false, hreq.getRequestURL().toString(), null); 163 logger.log(Level.WARNING, "authentication failed for " + 164 ejbEndpoint.getEndpoint().getEndpointName(), 165 e); 166 } 167 168 if (auditManager.isAuditOn()){ 169 170 auditManager.ejbAsWebServiceInvocation( 171 ejbEndpoint.getEndpoint().getEndpointName(),authenticated); 172 } 173 174 175 176 if (!authenticated) { 177 hresp.setHeader("WWW-Authenticate", 178 "Basic realm=\"" + realmName + "\""); 179 hresp.sendError(HttpServletResponse.SC_UNAUTHORIZED); 180 return; 181 } 182 183 EjbMessageDispatcher msgDispatcher = ejbEndpoint.getMessageDispatcher(); 186 msgDispatcher.invoke(hreq, hresp, ejbEndpoint); 187 188 } catch(Throwable t) { 189 logger.log(Level.WARNING, "", t); 190 } finally { 191 if( authenticated ) { 192 SecurityContext.setCurrent(null); 194 } 195 196 container.externalPostInvoke(); 198 } 199 return; 200 } 201 202 private boolean doSecurity(HttpServletRequest hreq, 203 EjbRuntimeEndpointInfo epInfo, 204 String realmName) throws Exception { 205 206 WebServiceEndpoint endpoint = epInfo.getEndpoint(); 207 boolean authenticated = false; 208 209 String method = hreq.getMethod(); 210 if( method.equals("GET") || !endpoint.hasAuthMethod() ) { 211 return true; 212 } 213 214 WebPrincipal webPrincipal = null; 215 String endpointName = endpoint.getEndpointName(); 216 217 if( endpoint.hasBasicAuth() ) { 218 String rawAuthInfo = hreq.getHeader(AUTHORIZATION_HEADER); 219 if (rawAuthInfo==null) { 220 sendAuthenticationEvents(false, hreq.getRequestURL().toString(), null); 221 return false; 222 } 223 224 String [] usernamePassword = 225 parseUsernameAndPassword(rawAuthInfo); 226 if( usernamePassword != null ) { 227 webPrincipal = new WebPrincipal 228 (usernamePassword[0], usernamePassword[1], SecurityContext.init()); 229 } else { 230 logger.log(Level.WARNING, "BASIC AUTH username/password " + 231 "http header parsing error for " + endpointName); 232 } 233 } else { 234 235 X509Certificate certs[] = (X509Certificate []) hreq.getAttribute(Globals.CERTIFICATES_ATTR); 236 if ((certs == null) || (certs.length < 1)) { 237 certs = (X509Certificate []) 238 hreq.getAttribute(Globals.SSL_CERTIFICATE_ATTR); 239 } 240 241 if( certs != null ) { 242 webPrincipal = new WebPrincipal(certs, SecurityContext.init()); 243 } else { 244 logger.log(Level.WARNING, "CLIENT CERT authentication error for " + endpointName); 245 } 246 247 } 248 249 if (webPrincipal==null) { 250 sendAuthenticationEvents(false, hreq.getRequestURL().toString(), null); 251 return authenticated; 252 } 253 254 RealmAdapter ra = new RealmAdapter(realmName); 255 authenticated = ra.authenticate(webPrincipal); 256 if( authenticated == false ) { 257 sendAuthenticationEvents(false, hreq.getRequestURL().toString(), webPrincipal); 258 logger.fine("authentication failed for " + endpointName); 259 } 260 261 sendAuthenticationEvents(true, hreq.getRequestURL().toString(), webPrincipal); 262 if(!(epInfo instanceof Ejb2RuntimeEndpointInfo)) { 264 WebServiceContextImpl ctxt = (WebServiceContextImpl) 265 epInfo.prepareInvocation(false).getWebServiceContext(); 266 ctxt.setUserPrincipal(webPrincipal); 267 } 268 return authenticated; 269 } 270 271 private String [] parseUsernameAndPassword(String rawAuthInfo) { 272 273 String [] usernamePassword = null; 274 if ( (rawAuthInfo != null) && 275 (rawAuthInfo.startsWith("Basic ")) ) { 276 String authString = rawAuthInfo.substring(6).trim(); 277 String unencoded = 279 new String (base64Helper.decode(authString.getBytes())); 280 int colon = unencoded.indexOf(':'); 281 if (colon > 0) { 282 usernamePassword = new String [2]; 283 usernamePassword[0] = unencoded.substring(0, colon).trim(); 284 usernamePassword[1] = unencoded.substring(colon + 1).trim(); 285 } 286 } 287 return usernamePassword; 288 } 289 290 private void sendAuthenticationEvents(boolean success, 291 String url, WebPrincipal principal) { 292 293 Endpoint endpoint = WebServiceEngineImpl.getInstance().getEndpoint(url); 294 if (endpoint==null) { 295 return; 296 } 297 298 for (AuthenticationListener listener : WebServiceEngineImpl.getInstance().getAuthListeners()) { 299 if (success) { 300 listener.authSucess(endpoint.getDescriptor().getBundleDescriptor(), 301 endpoint, principal); 302 } else { 303 listener.authFailure(endpoint.getDescriptor().getBundleDescriptor(), 304 endpoint, principal); 305 } 306 } 307 } 308 } 309 | Popular Tags |