6 Replies Latest reply on Feb 4, 2008 10:37 AM by mjhammel

    Accessing USERNAME_PROPERTY from Web Service class

    mjhammel

      In my client I do this to authenticate with BASIC authentication:

      /* Setup to authenticate with the server. */
       bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, subscriberID);
       bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, pw);
      


      I'd like to access the USERNAME_PROPERTY from within my web services class. With JBOSS 4.0.5GA and Axis 1.1 (I think) I did this:

      final MessageContext msgContext = MessageContext.getCurrentContext();
       msgContext.getUsername();
      


      With JBOSS WS 2.0.2 GA (running under JBOSS 4.2.2GA) I've dropped Axis and so I've tried things like this, but none seem to work:

       @Resource
       WebServiceContext wsContext;
      
      ...
      
       MessageContext msgContext = wsContext.getMessageContext();
       String username = (String) msgContext.get(BindingProvider.USERNAME_PROPERTY) ;
      


      What's the correct way to access this message property from the server side?

        • 1. Re: Accessing USERNAME_PROPERTY from Web Service class
          mjhammel

          Okay, I discovered how to do this. Part of the problem was that my BASIC authentication via DatabaseServerLoginModule was not working properly.

          Ignoring the authentication problem, once you have authentication working then the following code should work:

          import javax.xml.ws.WebServiceContext;
          import javax.xml.ws.handler.MessageContext;
          import javax.servlet.http.HttpServletRequest;
          import java.security.Principal;
          ...
          
          @Stateless
          @Remote(SubscriberServices.class)
          @WebService(
           name = "SubscriberWS",
           endpointInterface = "com.cei.crunch.server.ws.SubscriberServices.SubscriberServicesEndpoint"
           )
          @SOAPBinding(style = SOAPBinding.Style.RPC)
          
          public class SubscriberServices implements SubscriberServicesEndpoint {
          
           @Resource
           WebServiceContext wsContext;
          
           private Subscriber getUserInfo() throws CrunchWSException {
          
           MessageContext msgContext = wsContext.getMessageContext();
           HttpServletRequest servletRequest = (HttpServletRequest) msgContext.get(MessageContext.SERVLET_REQUEST);
           Principal p = servletRequest.getUserPrincipal();
           String username = p.getName();
           ....
          


          Alternatively:
           ...
           MessageContext msgContext = wsContext.getMessageContext();
           HttpServletRequest servletRequest = (HttpServletRequest) msgContext.get(MessageContext.SERVLET_REQUEST);
           String username = servletRequest.getRemoteUser();
           ...


          Either method appears to work.

          • 2. Re: Accessing USERNAME_PROPERTY from Web Service class
            mjhammel

            Also: see this article for a little additional help:

            https://jax-ws.dev.java.net/articles/MessageContext.html

            • 3. Re: Accessing USERNAME/PASSWORD_PROPERTY from Web Service cl
              mjhammel

              While finding the username wasn't as hard as first thought, it looks like finding the PASSWORD is. It doesn't seem to be in the HttpServletContext anywhere, nor can I find it in the MessageContext anywhere.

              This piece of code:

              /* Find out who the user is saying they are in the HTTP session. */
               MessageContext msgContext = wsContext.getMessageContext();
               HttpServletRequest servletRequest = (HttpServletRequest) msgContext.get(MessageContext.SERVLET_REQUEST);
               String username = servletRequest.getRemoteUser();
              
               Enumeration hdrs = servletRequest.getHeaderNames();
               for (; hdrs.hasMoreElements() ;)
               System.out.println("Header: " + hdrs.nextElement());
              
               String pathInfo = servletRequest.getPathInfo();
               String queryStr = servletRequest.getQueryString();
               String requestURI = servletRequest.getRequestURI();
               StringBuffer requestURL = servletRequest.getRequestURL();
               Principal p = servletRequest.getUserPrincipal();
               String sessionID = servletRequest.getRequestedSessionId();
              
               System.out.println("Path Info: " + pathInfo);
               System.out.println("Query String: " + queryStr);
               System.out.println("Request URI : " + requestURI);
               System.out.println("Request URL : " + requestURL.toString());
               System.out.println("Principal : " + p.toString());
               System.out.println("Session ID : " + sessionID);
              
               HttpSession session = servletRequest.getSession();
               Enumeration attrs = session.getAttributeNames();
               for (; attrs.hasMoreElements() ;)
               System.out.println("Session Attribute: " + attrs.nextElement());


              produces the following output, which doesn't show any sign of the password property:

              14:49:57,472 INFO [STDOUT] Header: authorization
              14:49:57,472 INFO [STDOUT] Header: soapaction
              14:49:57,472 INFO [STDOUT] Header: content-type
              14:49:57,472 INFO [STDOUT] Header: jboss-remoting-version
              14:49:57,472 INFO [STDOUT] Header: user-agent
              14:49:57,472 INFO [STDOUT] Header: host
              14:49:57,472 INFO [STDOUT] Header: accept
              14:49:57,472 INFO [STDOUT] Header: connection
              14:49:57,472 INFO [STDOUT] Header: content-length
              14:49:57,475 INFO [STDOUT] Path Info: null
              14:49:57,475 INFO [STDOUT] Query String: null
              14:49:57,476 INFO [STDOUT] Request URI : /Crunch/comp/SubscriberServices
              14:49:57,476 INFO [STDOUT] Request URL : https://localhost:8443/Crunch/comp/SubscriberServices
              14:49:57,476 INFO [STDOUT] Principal : admin
              14:49:57,476 INFO [STDOUT] Session ID : null
              


              Note that there doesn't appear to be anything in the HttpSession either, which is probably correct though I'm not sure of that at the moment.

              Does anyone know where the PASSWORD_PROPERTY set by the client is hiding when it gets to the Web Services class?

              • 4. Re: Accessing USERNAME_PROPERTY from Web Service class
                mjhammel

                I've spent all day on this and found nothing. It appears that *maybe* something called handlers or interceptors might be useful here. The password must be sent in the SOAP message but the question is how to pull it out. I think the PASSWORD_PROPERTY as set by the client is received on the server side (proven by the use of BASIC authentication using a database login module) but is not in the APPLICATION scope and therefore I can't get at it the way I've been trying. Which is what leads me to think the handlers or interceptors might have some way to get at it. But I'm still not clear on how to write handlers (and I'm not even sure what interceptors might be, other than they appear to be part of Apache CXF, whatever that is).

                Maybe if I post enough messages in this thread someone at JBOSS will pay attention to it long enough to tell me "You can't get there from here." At least then I'd know I can stop wasting my time on it.

                At this point it feels like I'm wasting my time on Web Services, which feel about as useful as Esperanto. *sigh*

                • 5. Re: Accessing USERNAME_PROPERTY from Web Service class
                  asoldano

                  Unfortunately I don't see a really good way of getting the password from the ws endpoint. An hint I can give you is that if you use BASIC auth your username+password are encoded (base64) and put in the authorization http header you can easily read from a JAX-WS handler.

                  • 6. Re: Accessing USERNAME_PROPERTY from Web Service class
                    mjhammel

                    Thanks alessio. I'll look into handlers and see if I can pull the data out that way. If you have any pointers to online docs on how to write and use handlers please forward them. I'd appreciate it. Thanks.