FileDocCategorySizeDatePackage
EjbWebServiceServlet.javaAPI DocGlassfish v2 API13871Fri May 04 22:36:10 BST 2007com.sun.enterprise.webservice

EjbWebServiceServlet

public class EjbWebServiceServlet extends HttpServlet
Servlet responsible for invoking EJB webservice endpoint. Most of this code used to be in com.sun.enterprise.webservice.EjbWebServiceValve.
author
Qingqing Ouyang
author
Kenneth Saks
author
Jan Luehe

Fields Summary
private static Logger
logger
private static final org.apache.catalina.util.Base64
base64Helper
private static final String
AUTHORIZATION_HEADER
private static com.sun.enterprise.security.audit.AuditManager
auditManager
Constructors Summary
Methods Summary
private voiddispatchToEjbEndpoint(javax.servlet.http.HttpServletRequest hreq, javax.servlet.http.HttpServletResponse hresp, com.sun.enterprise.webservice.EjbRuntimeEndpointInfo ejbEndpoint)


        String scheme = hreq.getScheme();
        String expectedScheme = ejbEndpoint.getEndpoint().isSecure() ?
            "https" : "http";

        if( !expectedScheme.equalsIgnoreCase(scheme) ) {
            logger.log(Level.WARNING, "Invalid request scheme for Endpoint " +
                       ejbEndpoint.getEndpoint().getEndpointName() + ". " +
                       "Expected " + expectedScheme + " . Received " + scheme);
            return;
        }

        Switch theSwitch = Switch.getSwitch();
        Container container = ejbEndpoint.getContainer();
        
        boolean authenticated = false;
        try {
            // Set context class loader to application class loader
            container.externalPreInvoke();

            // compute realmName
            String realmName = null;
            Application app = ejbEndpoint.getEndpoint().getBundleDescriptor().getApplication();
            if (app != null) {
                realmName = app.getRealm();
            }
            if (realmName == null) {
                realmName = ejbEndpoint.getEndpoint().getRealm();
            }

            if (realmName == null) {
                // use the same logic as BasicAuthenticator
                realmName = hreq.getServerName() + ":" + hreq.getServerPort();
            }
            
            try {
                authenticated = doSecurity(hreq, ejbEndpoint, realmName);
            } catch(Exception e) {
                sendAuthenticationEvents(false, hreq.getRequestURI(), null);
                logger.log(Level.WARNING, "authentication failed for " +
                           ejbEndpoint.getEndpoint().getEndpointName(),
                           e);
            }

   	        if (auditManager.isAuditOn()){

	            auditManager.ejbAsWebServiceInvocation(
                    ejbEndpoint.getEndpoint().getEndpointName(),authenticated);
            }



            if (!authenticated) {
                hresp.setHeader("WWW-Authenticate",
                        "Basic realm=\"" + realmName + "\"");
                hresp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
                return;
            }
            
            // depending on the jaxrpc or jax-ws version, this will return the
            // right dispatcher.
            EjbMessageDispatcher msgDispatcher = ejbEndpoint.getMessageDispatcher();
            msgDispatcher.invoke(hreq, hresp, getServletContext(), ejbEndpoint);
            
        } catch(Throwable t) {
            logger.log(Level.WARNING, "", t);
        } finally {
            if( authenticated ) {
                // remove any security context from the thread before returning
                SecurityContext.setCurrent(null);
            }
            
            // Restore context class loader
            container.externalPostInvoke();
        }
        return;
    
private booleandoSecurity(javax.servlet.http.HttpServletRequest hreq, com.sun.enterprise.webservice.EjbRuntimeEndpointInfo epInfo, java.lang.String realmName)


        //BUG2263 - Clear the value of UserPrincipal from previous request
        //If authentication succeeds, the proper value will be set later in
        //this method.
        WebServiceContextImpl context = (WebServiceContextImpl)
                ((EjbRuntimeEndpointInfo)epInfo).getWebServiceContext();
        if (context != null) {
            context.setUserPrincipal(null);        
        }
        
        WebServiceEndpoint endpoint = epInfo.getEndpoint();
        boolean authenticated = false;
        
        String method = hreq.getMethod();
        if( method.equals("GET") || !endpoint.hasAuthMethod() ) {
            return true;
        }
        
        WebPrincipal webPrincipal = null;
        String endpointName = endpoint.getEndpointName();
        
        if( endpoint.hasBasicAuth() ) {
            String rawAuthInfo = hreq.getHeader(AUTHORIZATION_HEADER);
            if (rawAuthInfo==null) {
                sendAuthenticationEvents(false, hreq.getRequestURI(), null);
                return false;
            }
            
            String[] usernamePassword =
                    parseUsernameAndPassword(rawAuthInfo);
            if( usernamePassword != null ) {
                webPrincipal = new WebPrincipal
                        (usernamePassword[0], usernamePassword[1], SecurityContext.init());
            } else {
                logger.log(Level.WARNING, "BASIC AUTH username/password " +
                           "http header parsing error for " + endpointName);
            }
        } else {

            X509Certificate certs[] =  (X509Certificate[]) hreq.getAttribute(Globals.CERTIFICATES_ATTR);
            if ((certs == null) || (certs.length < 1)) {
                certs = (X509Certificate[])
                    hreq.getAttribute(Globals.SSL_CERTIFICATE_ATTR);
            }

            if( certs != null ) {
                webPrincipal = new WebPrincipal(certs, SecurityContext.init());
            } else {
                logger.log(Level.WARNING, "CLIENT CERT authentication error for " + endpointName);
            }

        }

        if (webPrincipal==null) {
            sendAuthenticationEvents(false, hreq.getRequestURI(), null);           
            return authenticated;
        }
        
        RealmAdapter ra = new RealmAdapter(realmName);
        authenticated = ra.authenticate(webPrincipal);
        if( authenticated == false ) {
            sendAuthenticationEvents(false, hreq.getRequestURI(), webPrincipal);
            logger.fine("authentication failed for " +  endpointName);
        }

        sendAuthenticationEvents(true, hreq.getRequestURI(), webPrincipal);
        if(epInfo instanceof Ejb2RuntimeEndpointInfo) {
            // For JAXRPC based EJb endpoints the rest of the steps are not needed
            return authenticated;
        }
        //Setting if userPrincipal in WSCtxt applies for JAXWS endpoints only
        epInfo.prepareInvocation(false);
        WebServiceContextImpl ctxt = (WebServiceContextImpl)
                ((EjbRuntimeEndpointInfo)epInfo).getWebServiceContext();
        ctxt.setUserPrincipal(webPrincipal);
        return authenticated;
    
private java.lang.String[]parseUsernameAndPassword(java.lang.String rawAuthInfo)


        String[] usernamePassword = null;
        if ( (rawAuthInfo != null) && 
             (rawAuthInfo.startsWith("Basic ")) ) {
            String authString = rawAuthInfo.substring(6).trim();
            // Decode and parse the authorization credentials
            String unencoded =
                new String(base64Helper.decode(authString.getBytes()));
            int colon = unencoded.indexOf(':");
            if (colon > 0) {
                usernamePassword = new String[2];
                usernamePassword[0] = unencoded.substring(0, colon).trim();
                usernamePassword[1] = unencoded.substring(colon + 1).trim();
            }
        }
        return usernamePassword;
    
private voidsendAuthenticationEvents(boolean success, java.lang.String url, com.sun.web.security.WebPrincipal principal)

        
        Endpoint endpoint = WebServiceEngineImpl.getInstance().getEndpoint(url);
        if (endpoint==null) {
            return;
        }
        
        for (AuthenticationListener listener : WebServiceEngineImpl.getInstance().getAuthListeners()) {
            if (success) {
                listener.authSucess(endpoint.getDescriptor().getBundleDescriptor(),
                        endpoint, principal);
            } else {
                listener.authFailure(endpoint.getDescriptor().getBundleDescriptor(),
                        endpoint, principal);
            }
        }
    
protected voidservice(javax.servlet.http.HttpServletRequest hreq, javax.servlet.http.HttpServletResponse hresp)


         
               

        boolean dispatch = true;

        String requestUriRaw = hreq.getRequestURI();
        String requestUri = (requestUriRaw.charAt(0) == '/") ?
            requestUriRaw.substring(1) : requestUriRaw;
        String query = hreq.getQueryString();

        // check if it is a tester servlet invocation
        if ("Tester".equalsIgnoreCase(query)) {
            Endpoint endpoint = WebServiceEngineImpl.getInstance().getEndpoint(hreq.getRequestURI());
            if((endpoint.getDescriptor().isSecure()) ||
               (endpoint.getDescriptor().getMessageSecurityBinding() != null)) {
                String message = endpoint.getDescriptor().getWebService().getName() +
                    "is a secured web service; Tester feature is not supported for secured services";
                (new WsUtil()).writeInvalidMethodType(hresp, message);                
                return;
            }            
            if (endpoint!=null && Boolean.parseBoolean(endpoint.getDescriptor().getDebugging())) {
                dispatch = false;
                WebServiceTesterServlet.invoke(hreq, hresp,
                                               endpoint.getDescriptor());
            }
        }

        if (dispatch) {
            EjbRuntimeEndpointInfo ejbEndpoint = 
                WebServiceEjbEndpointRegistry.getRegistry().getEjbWebServiceEndpoint(requestUri, hreq.getMethod(), query);

            if (ejbEndpoint != null) {
                /*
                 * We can actually assert that ejbEndpoint is != null,
                 * because this EjbWebServiceServlet would not have been
                 * invoked otherwise
                 */
                dispatchToEjbEndpoint(hreq, hresp, ejbEndpoint);
            }
        }