3 Replies Latest reply on Jan 2, 2007 6:45 PM by James Barker

    Basic Auth Security with DII and Stub Clients

    Suman Grandhi Newbie

      I initially had a bunch of services working with the AXIS stack and now I have switched to JBOSSWS with the new 4.0.4GA release. I had secured web services configured with basic authentication working with Axis and after reading through the JBOSSWS user guide I still seem to be stuck in authenticating properly with the hosted and secured web service with the JBossWS stack.

      Below are the following steps that I took.

      #1) I used wstools to compile & autogenerate a WSDL, Mapping, and webservices.xml

      <configuration>
       <java-wsdl>
       <service name="LicensingWebServices" style="rpc"
       endpoint="com.myco.webservices.secure.licensing.LicensingServices"/>
       <namespaces target-namespace="http://com.myco.webservices.secure.licensing/MyWebServices"
       type-namespace="http://com.myco.webservices.secure.licensing/MyWebServices/types"/>
       <mapping file="LicensingServices_Mapping.xml"/>
       <webservices servlet-link="LicensingServicesServlet"/>
       </java-wsdl>
      </configuration>
      


      #2) I copied the wsdl, mapping and webservices.xml files into a war and deployed the webservices successfully. For testing purposes, my implementation just returns "Hello World"

      #3) I ran wstools again to generate the client artifacts using the following config file by pointing to the locally generated wsdl file in step 1.
      <configuration>
       <wsdl-java file="/root/mywsproject/webservicegen-jbossws/licensing/server/wsdl/LicensingWebServices.wsdl">
       <mapping file="LicensingServices_Mapping.xml" />
       </wsdl-java>
      </configuration>
      


      #4) I got back two autogenerated classes LicensingServices.java and LicensingWebServices.java which have the following code below.
      LicensingServices.java
      package com.myco.webservices.secure.licensing.MyWebServices;
      public interface LicensingServices extends java.rmi.Remote
      {
       public java.lang.String verifyClientLicenseInfo(java.lang.String string_1) throws java.rmi.RemoteException;
      }
      

      LicensingWebServices.java
      package com.myco.webservices.secure.licensing.MyWebServices;
      import javax.xml.rpc.*;
      public interface LicensingWebServices extends javax.xml.rpc.Service
      {
       public com.myco.webservices.secure.licensing.MyWebServices.LicensingServices getLicensingServicesPort() throws ServiceException;
      }
      


      #5) I compiled and packaged these two classes into a jar file and have it referenced from my client code shown in step 7.

      #6) I initally changed the servlet for the web services so that it is public and doesn't require any authentication.

      #7) Using the JBOSSWS User Guide I wrote a simple DII client like below.
      QName SERVICE_NAME = new QName(namespace, servicename);
      ServiceFactory serviceFactory = ServiceFactory.newInstance();
      Service service = serviceFactory.createService(new URL(wsdl), SERVICE_NAME);
      LicensingServices ws = (LicensingServices) service.getPort(LicensingServices.class);
      System.out.println(ws.verifyClientLicenseInfo(args));
      


      This successfully returned "Hello World!" Great. Now to securing the service.

      #8) I changed the servlet path on the webservice so that it is now secured with basic authentication (simple username and password). I ran the same client code as above and I got back an HTTP 401 error. Correct!!! This is a secured service and I should get back an HTTP 401 Unauthorized since I haven't provided and credentials.

      Questions:
      1) How do I pass username and password credentials using the DII format.
      2) If the question to number 1 is that DII doesn't support authentication and to use Stubs instead then I tried the following and was still unsuccessful.


      I initially had this secured web service working with the client using the following AXIS client code.
      LicensingWebServices_Impl lic = new LicensingWebServices_Impl();
      Stub stub = (Stub)(lic.getLicensingServicesPort());
      stub._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, username);
      stub._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, password);
      stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY, wsdl);
      LicensingServices licws = (LicensingServices)stub;
      return licws.verifyClientLicenseInfo(args);
      

      However, when using this method, wscompile from jwsdp1.6 generated a bunch of classes, more than WSTools.
      LicensingServices - similar in both WSTools and WSCompile
      LicensingWebServices - similar in both WSTools and WSCompile
      WSCompile also generated some classes like LicensingWebServices_Impl above which extends LicensingWebServices containing the getLicensingServicesPort() method.

      As a result, using WSTools I only have interfaces and cannot perform the first line where the new is called.

      Am I missing something here on how to generate client-side stubs using the new JBossWS stack?
      Do I still use wscompile to generate the client side stubs?


      Any help is appreciated. Thanks.

        • 1. Re: Basic Auth Security with DII and Stub Clients
          Suman Grandhi Newbie

          Ok... got a little further with the RPC sample code. However there is still one problem. Just as a note, use the StubExt and ServiceImpl, and ServiceFactoryImpl classes that come in the org.jboss.ws.jaxrpc package. When trying this code earlier I was running into a lot of ClassCastExceptions when using the jaxrpc (Service, ServiceFActory, etc) classes.

          //STUB JBOSS WS METHOD
          QName SERVICE_NAME = new QName(namespace, servicename);
          ServiceFactoryImpl serviceFactory = (ServiceFactoryImpl) ServiceFactoryImpl.newInstance();
          ServiceImpl service = (ServiceImpl) serviceFactory.createService(new URL(wsdl), SERVICE_NAME);
          
          Stub stub = (Stub)(service.getPort(LicensingServices.class));
          stub._setProperty(StubExt.USERNAME_PROPERTY, username);
          stub._setProperty(StubExt.PASSWORD_PROPERTY, password);
          stub._setProperty(StubExt.ENDPOINT_ADDRESS_PROPERTY, wsdl);
          LicensingServices licws = (LicensingServices)stub;
          return licws.verifyClientLicenseInfo(args);
          


          So where this code is failing is in the line where it retrieves the wsdl which is also protected with the basic auth. ServiceImpl service = (ServiceImpl) serviceFactory.createService(new URL(wsdl), SERVICE_NAME);

          Do I need to make the wsdl public? If so, how is the best way to do this since the difference between the service and the wsdl is just ?wsdl in the url.

          • 2. Re: Basic Auth Security with DII and Stub Clients
            Suman Grandhi Newbie

            I have a solution with Stubs that will connect to a JAAS secured endpoint. Again the Stub client code in my previous posting works great with rpc literal services that are unsecured. However, as stated in my previous post, after securing the web service I could only get it to work by making a copy of the wsdl and hosting it in a public space and then overriding the url using the stub properties. Is this the only way? It does not seem like a clean implementation to do this.

            The code is the same as above except when the createService is called it points to an identical copy of the wsdl that I put into a publicly hosted space within my war.

            QName SERVICE_NAME = new QName(namespace, servicename);
            ServiceFactoryImpl serviceFactory = (ServiceFactoryImpl) ServiceFactoryImpl.newInstance();
            ServiceImpl service = (ServiceImpl) serviceFactory.createService(new URL(publicwsdl), SERVICE_NAME);
            Stub stub = (Stub)(service.getPort(LicensingServices.class));
            stub._setProperty(StubExt.USERNAME_PROPERTY, username);
            stub._setProperty(StubExt.PASSWORD_PROPERTY, password);
            stub._setProperty(StubExt.ENDPOINT_ADDRESS_PROPERTY, wsdl);
            LicensingServices licws = (LicensingServices)stub;
            return licws.verifyClientLicenseInfo(args);
            


            Looking through the other methods provided by ServiceFactoryImpl I also noticed the loadService() function that has identical parameters like createService() but also takes in Property arguments.

            As a result I tried the following:
            QName SERVICE_NAME = new QName(namespace, servicename);
            ServiceFactoryImpl serviceFactory = (ServiceFactoryImpl) ServiceFactoryImpl.newInstance();
            Properties props = new Properties();
            props.setProperty(StubExt.USERNAME_PROPERTY, username);
            props.setProperty(StubExt.PASSWORD_PROPERTY, password);
            props.setProperty(StubExt.PROPERTY_AUTH_TYPE, StubExt.PROPERTY_AUTH_TYPE_BASIC);
            ServiceImpl service = (ServiceImpl) serviceFactory.loadService(new URL(wsdl), LicensingWebServices.class, props);
            
            Stub stub = (Stub)(service.getPort(LicensingServices.class));
            stub._setProperty(StubExt.USERNAME_PROPERTY, username);
            stub._setProperty(StubExt.PASSWORD_PROPERTY, password);
            stub._setProperty(StubExt.ENDPOINT_ADDRESS_PROPERTY, wsdl);
            LicensingServices licws = (LicensingServices)stub;
            return licws.verifyClientLicenseInfo(args);
            


            But it turns out that these loadService() methods are not implemented and just return a NotImplementedException in both jbossws-client.jar packaged with both jbossWS 1.0.0 and with jboss 4.0.4GA release

            Questions:

            1) Is publicly hositng the service the only way?
            2) Is the loadService method actually implemented in other packages or distributions of jbossWS? If not, when will it be available?


            As a reference to others these are all of the packages that I included into my client code:
            $JBOSS_HOME/client:
            commons-logging.jar
            jbossall-client.jar
            jboss-jaxrpc.jar
            wsdl4j.jar
            activation.jar
            jboss-saaj.jar
            xmlsec.jar
            mail.jar
            jbossws-client.jar

            $JBOSS_HOME/lib/endorsed/xercesImpl.jar

            And of course the two interfaces that are generated out of wstools for the client from step 4 of my original post.

            Any help would be greatly appreciated.

            • 3. Re: Basic Auth Security with DII and Stub Clients
              James Barker Newbie

              Was there ever a resolution to this problem? I'm having the same one, and I can't believe that having to publicly host the WSDL is the best solution.