13 Replies Latest reply on Apr 16, 2010 8:10 AM by Alessio Soldano

    JbossWS username authentication not working

    Bonnie Kenison Newbie

      I am having trouble getting my webservice to authenticate the username/password sent in the wsse header.  I am using Pramod's example code.  The service works just fine, it returns the expected "Hello: Pramod" string.  However, it works regardless of what username/password is sent.  So obviously, the authentication is not happening.  I have looked all over for a solution and can't figure out where the problem is.  Any suggestions would be greatly appreciated as I need to put some level of security on this webservice.  The users of this service aren't very techo-savvy, so I'd prefer not to require them to use a certificate.  Username/password is just what we want.

       

      Using Jboss 4.2.3.GA

       

      login-config.xml    (located in jboss/server/default/conf):

       

          <application-policy name="JBossWS">
            <authentication>
              <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
                flag="required">
                <module-option name="usersProperties">props/jbossws-users.properties</module-option>
                <module-option name="rolesProperties">props/jbossws-roles.properties</module-option>
                <module-option name="unauthenticatedIdentity">anonymous</module-option> 
              </login-module>
            </authentication>
          </application-policy>

       

      jbossws-users.properties  (located in jboss/server/default/conf/props):


      # A sample users.properties file for use with the UsersRolesLoginModule
      kermit=thefrog

       


      jboss-wsse-server.xml:

       

      <jboss-ws-security xmlns="http://www.jboss.com/ws-security/config"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.jboss.com/ws-security/config
      http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">
          <config>
              <timestamp ttl="300"/>
              <requires>
                  <username/>
              </requires>
          </config>
      </jboss-ws-security>

       


      Service:

       

      @Stateless
      @WebService
      (name="TestWSEJB",
      targetNamespace = "http://localhost:8080/uttestservice",
      serviceName = "TestWSEJBService")
      @SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
      @EndpointConfig(configName = "Standard WSSecurity Endpoint")
      @SecurityDomain("JBossWS")

       

      public class TestWSEJB {
          @Resource
          WebServiceContext wsContext;

       

      @WebMethod
      public String ping (String name)
      {

       

         
          MessageContext msgCtx = (MessageContext)wsContext.getMessageContext();
          try
          {
              System.out.println(msgCtx);
              SOAPMessage soapMessage = ((SOAPMessageContext)msgCtx).getMessage();
              soapMessage.writeTo(System.out);
              System.out.println("");
          } catch (Exception se) { se.printStackTrace();} 

       

         
      return "Hello : " + name;
      }
      }

       


      jboss-wsse-client.xml:

       

      <?xml version="1.0" encoding="UTF-8"?>
      <jboss-ws-security xmlns="http://www.jboss.com/ws-security/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jboss.com/ws-security/config http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">
          <config>
              <username />
          </config>
      </jboss-ws-security>

       


      Client Interface:

       


      /**
      * This class was generated by the JAX-WS RI.
      * JAX-WS RI 2.1.1-b03-
      * Generated source version: 2.0
      *
      */
      @WebService(name = "TestWSEJB", targetNamespace = "http://localhost:8080/uttestservice")
      public interface TestWSEJB {

       


      /**
      *
      * @param arg0
      * @return
      * returns java.lang.String
      */
      @WebMethod
      @WebResult(targetNamespace = "")
      @RequestWrapper(localName = "ping", targetNamespace = "http://localhost:8080/uttestservice", className = "test.Ping")
      @ResponseWrapper(localName = "pingResponse", targetNamespace = "http://localhost:8080/uttestservice", className = "test.PingResponse")
      public String ping(
      @WebParam(name = "arg0", targetNamespace = "")
      String arg0);

       

      }

       


      Client Test:

       

      public class TestWSClient {

       

      public static void main(String[] args) {
      try {
      TestWSClient client = new TestWSClient();
      client.doTest(args);
      } catch(Exception e) {
      e.printStackTrace();
      }
      }

       

      public void doTest(String[] args) {
      try {
      URL url = new URL("http://localhost:8080/uttestservice?wsdl");
      QName qn = new QName("http://localhost:8080/uttestservice","TestWSEJBService");
      Service s = Service.create(url, qn);
      TestWSEJB port = s.getPort(TestWSEJB.class);
      URL securityURL = new File("jboss-wsse-client.xml").toURL();
      ((StubExt)port).setSecurityConfig(securityURL.toExternalForm());
      ((StubExt)port).setConfigName("Standard WSSecurity Client");
      ((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "kermitabc");;
      ((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "thefrogdef");;
      System.out.println("Invoking the sayHello operation on the port.");
      String response = port.ping("Pramod") ;
      System.out.println(response);
      } catch(Exception e) {
      e.printStackTrace();
      }
      }
      }

        • 1. Re: JbossWS username authentication not working
          Peter Johnson Master
          Looks like you are mixing some thinsg from WS-Security from some things from web app security. Which one do you really want to use? If the latter, add a <security-role> entry in the web.xml file (and you can drop the jboss-wsse-*.xml files, you don't need them).
          • 2. Re: JbossWS username authentication not working
            Bonnie Kenison Newbie

            I really just want to secure the web service, ie., require that the soap to the service includes the wsse:security header and that something on the server side verifies that this is the correct username/password.  The webservice will run under a web app that does not need to be secured. 

             

            This is the webservice request that gets generated:

             

            <env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>

            <env:Header>

            <wsse:Security env:mustUnderstand='1' xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
            xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'>

                 <wsse:UsernameToken wsu:Id='token-1-1267205890331-29812760'>

                 <wsse:Username>kermitabcd</wsse:Username>

                 <wsse:Password Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0#PasswordText'>thefrogefg</wsse:Password>

                 </wsse:UsernameToken></wsse:Security>

            </env:Header>

            <env:Body>

                 <ns2:ping xmlns:ns2="http://localhost:8080/uttestservice"><arg0>Pramod</arg0></ns2:ping>

            </env:Body>

            </env:Envelope>

             

            I just want something that says - username: kermitabcd and password:thefrogefg is not correct.  Right now, the webmethod is being executed regardless of the username/password being sent in.

             

            Bonnie

            • 3. Re: JbossWS username authentication not working
              Peter Johnson Master
              Then try adding the <security-role> entry in the web.xml file like I suggested and see if that gets you what you want. I haven't monitored the soap message when using the <security-role>, so I am not sure if it does exactly what you are asking for. Have monitored the message when using a public/private key combination to sign the messages, but I don't think that is what you are looking for.
              • 4. Re: JbossWS username authentication not working
                Bonnie Kenison Newbie

                I added the following to my web.xml file.  I wasn't sure if order was important, I put it at the end.  After <servlet>, <servlet-mapping>, and <welcome-file-list>

                 

                web.xml:

                   
                    <security-role>
                        <role-name>friend</role-name>
                    </security-role>

                 

                No change.  Still was able to run the web method regardless of password values.

                • 5. Re: JbossWS username authentication not working
                  Peter Johnson Master

                  Sorry, I forgot a step. You also need a <security-contarint> section to restrict access to the web service URL. Here is an example from one of my apps:

                   

                    <security-constraint>
                      <web-resource-collection>
                        <web-resource-name>Secure Sales Tax</web-resource-name>
                        <url-pattern>/tax</url-pattern>
                        <http-method>POST</http-method>
                      </web-resource-collection>
                      <auth-constraint>
                        <role-name>merchant</role-name>
                      </auth-constraint>
                    </security-constraint>

                  • 6. Re: JbossWS username authentication not working
                    Bonnie Kenison Newbie

                    Well, something new at least....

                     

                    Now I am failing on all attempts, regardless of the username/password combination.  Here is the exception produced:

                     

                    c:\>java com.xxx.testClient.TestWSClient test
                    Invoking the sayHello operation on the port.
                    javax.xml.ws.WebServiceException: java.io.IOException: Could not transmit message
                            at org.jboss.ws.core.jaxws.client.ClientImpl.handleRemoteException(ClientImpl.java:397)
                            at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:303)
                            at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:170)
                            at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:150)
                            at $Proxy15.ping(Unknown Source)
                            at com.utah.webservice.testClient.TestWSClient.doTest(TestWSClient.java:47)
                            at com.utah.webservice.testClient.TestWSClient.main(TestWSClient.java:19)
                    Caused by: java.io.IOException: Could not transmit message
                            at org.jboss.ws.core.client.HTTPRemotingConnection.invoke(HTTPRemotingConnection.java:264)
                            at org.jboss.ws.core.client.SOAPProtocolConnectionHTTP.invoke(SOAPProtocolConnectionHTTP.java:71)
                            at org.jboss.ws.core.CommonClient.invoke(CommonClient.java:340)
                            at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:291)
                            ... 5 more
                    Caused by: org.jboss.remoting.CannotConnectException: Can not connect http client invoker. Invalid HTTP server response
                    [403] - Access to the requested resource has been denied. Response: Access to the requested resource has been denied/403
                    .
                            at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:348)
                            at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:137)
                            at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:122)
                            at org.jboss.remoting.Client.invoke(Client.java:1634)
                            at org.jboss.remoting.Client.invoke(Client.java:548)
                            at org.jboss.ws.core.client.HTTPRemotingConnection.invoke(HTTPRemotingConnection.java:242)
                            ... 8 more
                    Caused by: org.jboss.ws.WSException: Invalid HTTP server response [403] - Access to the requested resource has been deni
                    ed
                            at org.jboss.ws.core.soap.SOAPMessageUnMarshallerHTTP.read(SOAPMessageUnMarshallerHTTP.java:75)
                            at org.jboss.remoting.transport.http.HTTPClientInvoker.readResponse(HTTPClientInvoker.java:518)
                            at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:307)
                            ... 13 more

                     

                     

                    Here is my jbossws-roles.properties file:

                     

                    # A sample roles.properties file for use with the UsersRolesLoginModule
                    kermit=friend
                    wstest=friend

                     

                    jbossws-users.properties:

                    # A sample users.properties file for use with the UsersRolesLoginModule
                    kermit=thefrog

                     

                    Do I need to define the role in the webservice java file somewhere?

                     

                    Bonnie

                    • 7. Re: JbossWS username authentication not working
                      Peter Johnson Master

                      This configuration information:

                       

                      jbossws-users.properties:

                      # A sample users.properties file for  use with the UsersRolesLoginModule
                      kermit=thefrog

                       

                      is inconsistent with this code:

                       

                      ((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY,  "kermitabc");;
                      ((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY,  "thefrogdef");;

                      • 8. Re: JbossWS username authentication not working
                        Bonnie Kenison Newbie

                        Yes, I know.  The issue originally was that sending in bad username/passwords was not being stopped.  The webservice was being invoked anyway.  I made some of the configuration changes you recommended, then everything stopped working, even the good username/passwords.

                         

                        I'm not sure exactly what I changed that worked but, I have gotten the authentication working now.  Here is my new code:

                         

                        Using Jboss 4.2.3.GA

                         

                        login-config.xml    (located in jboss/server/default/conf):

                         

                            <application-policy name="JBossWS">
                              <authentication>
                                <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
                                  flag="required">
                                  <module-option name="usersProperties">props/jbossws-users.properties</module-option>
                                  <module-option name="rolesProperties">props/jbossws-roles.properties</module-option>
                                  <module-option name="unauthenticatedIdentity">anonymous</module-option> 
                                </login-module>
                              </authentication>
                            </application-policy>

                         


                        jbossws-users.properties  (located in jboss/server/default/conf/props):
                        # A sample users.properties file for use with the UsersRolesLoginModule
                        kermit=thefrog

                         


                        jboss-wsse-server.xml:

                         

                        <jboss-ws-security xmlns="http://www.jboss.com/ws-security/config"
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xsi:schemaLocation="http://www.jboss.com/ws-security/config
                        http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">
                            <config>
                                <timestamp ttl="300"/>
                                <requires/>                         ** removed requires username
                            </config>
                        </jboss-ws-security>

                         


                        Service:

                         

                        @Stateless
                        @WebService
                        (name="TestWSEJB",
                        targetNamespace = "http://localhost:8080/uttestservice",
                        serviceName = "TestWSEJBService")
                        @SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
                        @EndpointConfig(configName = "Standard WSSecurity Endpoint")
                        @SecurityDomain("JBossWS")
                        @RolesAllowed("friend")
                        @WebContext(contextRoot="/uttestservice", urlPattern="/*", authMethod="BASIC", transportGuarantee="NONE", secureWSDLAccess=false)
                        public class TestWSEJB implements com.utah.webservice.testClient.TestWSEJB {
                            @Resource
                            WebServiceContext wsContext;

                         

                        @WebMethod
                        public String ping (String name)
                        {

                         

                           
                            MessageContext msgCtx = (MessageContext)wsContext.getMessageContext();
                            try
                            {
                                System.out.println(msgCtx);
                                SOAPMessage soapMessage = ((SOAPMessageContext)msgCtx).getMessage();
                                soapMessage.writeTo(System.out);
                                System.out.println("");
                            } catch (Exception se) { se.printStackTrace();} 

                         

                           
                        return "Hello : " + name;
                        }
                        }

                         

                        jboss-wsse-client.xml:

                         

                        <?xml version="1.0" encoding="UTF-8"?>
                        <jboss-ws-security xmlns="http://www.jboss.com/ws-security/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.jboss.com/ws-security/config http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">
                            <config>
                                <username />
                            </config>
                        </jboss-ws-security>

                         


                        Client Interface:

                         


                        /**
                        * This class was generated by the JAX-WS RI.
                        * JAX-WS RI 2.1.1-b03-
                        * Generated source version: 2.0
                        *
                        */
                        @WebService(name = "TestWSEJB", targetNamespace = "http://localhost:8080/uttestservice")
                        public interface TestWSEJB {

                         


                        /**
                        *
                        * @param arg0
                        * @return
                        * returns java.lang.String
                        */
                        @WebMethod
                        @WebResult(targetNamespace = "")
                        @RequestWrapper(localName = "ping", targetNamespace = "http://localhost:8080/uttestservice", className = "test.Ping")
                        @ResponseWrapper(localName = "pingResponse", targetNamespace = "http://localhost:8080/uttestservice", className = "test.PingResponse")
                        public String ping(
                        @WebParam(name = "arg0", targetNamespace = "")
                        String arg0);

                         

                        }

                         

                        Client Test:

                         

                        public class TestWSClient {

                         

                        public static void main(String[] args) {
                        try {
                        TestWSClient client = new TestWSClient();
                        client.doTest(args);
                        } catch(Exception e) {
                        e.printStackTrace();
                        }
                        }

                         

                        public void doTest(String[] args) {

                         

                        try {
                        URL url = new URL("http://localhost:8080/uttestservice?wsdl");
                        QName qn = new QName("http://localhost:8080/uttestservice","TestWSEJBService");
                        Service s = Service.create(url, qn);
                        TestWSEJB port = s.getPort(TestWSEJB.class);
                        URL securityURL = new File("jboss-wsse-client.xml").toURL();
                        ((StubExt)port).setSecurityConfig(securityURL.toExternalForm());
                        ((StubExt)port).setConfigName("Standard WSSecurity Client");
                        ((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "kermitabcd");
                        ((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "thefrogefg");
                        System.out.println("Invoking the sayHello operation on the port.");
                        String response = port.ping("Pramod") ;
                        System.out.println(response);
                        } catch(Exception e) {
                        e.printStackTrace();
                        }
                        }
                        }

                         

                        This code now allows calling of the webservice with "kermit/thefrog" and fails on "kermitabcd/thefrogefg".   Thanks for assisting.

                        • 9. Re: JbossWS username authentication not working
                          Erick Jeronimo Diaz Newbie

                          Bonnie, i'd like to thank you for your post, i implemented jaas security without problems (http://community.jboss.org/docs/DOC-13533) but when i try to use WS-Security using  @EndpointConfig(configName = "Standard WSSecurity Endpoint")  in server side etcetc etc , just what you did in your post i received a java.lang.ClassCastException: $Proxy24 console message, what does it means????

                           

                          In facts, if you use only jaas method, WITHOUT @EndpointConfig(configName = "Standard WSSecurity Endpoint")
                          server side annotation, you can see in console:

                           

                          16:15:46,837 INFO  [STDOUT] org.jboss.ws.core.jaxws.handler.SOAPMessageContextJAXWS@5ddffa
                          16:15:46,837 INFO  [STDOUT] <S:Envelope xmlns:S='http://schemas.xmlsoap.org/soap/envelope/'><S:Body><ns2:sayHello xmlns:ns2="http://hello.test/"><arg0>titos</arg0></ns2:sayHello></S:Body></S:Envelope>

                           

                          (i use sayHello instead of ping), and this type of security implementation works fine,

                           

                           

                          thanks in advance

                          • 10. Re: JbossWS username authentication not working
                            Viacheslav Garmash Newbie

                            Hi, Guys. I am having the same issues: I am trying to connect to secured webservice which needs login and password.

                            I am using JBoss Portal 2.6.3, JDK 1.6, jax-ws jars copied to lib/endorsed as described here: https://jira.jboss.org/jira/browse/JBWS-1439

                             

                            I've tried this code as Bonny provided:

                             

                            ((StubExt)port).setConfigName("Standard WSSecurity Client");
                            ((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY,  "kermitabc");;
                            ((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY,  "thefrogdef");;

                             

                            But I just getting back this exception again and again:

                             

                            javax.xml.ws.soap.SOAPFaultException: Security requirements are not satisfied because the security header is not present in the incoming message.

                             

                            I spent about a day readin all wiki pages about WS-Security at Jboss.org but I didn't find any other way to provide password from the client. Maybe somebody know where we can get some real working example?

                            • 11. Re: JbossWS username authentication not working
                              Erick Jeronimo Diaz Newbie

                              I had not explored jboss portal but following this topic: http://community.jboss.org/docs/DOC-13533 , are'u using "JBossWS" security domain (look for it in login-config.xml), there're others application-policy, check it using @SecurityDomain("JBossWS") annotation in your server EJB or POJO class, besides you can specify the access roles roles using this annotation: @RolesAllowed("friend") , by default kermit=thefrog comes with jbossws cofiguration  (/conf/props/jbossws-users.properties, and ..../jbossws-roles.properties)

                              To enable HTTP basic auth for security you can use @WebContext, (Ex: @WebContext(contextRoot="/my-cxt", urlPattern="/*", authMethod="BASIC", transportGuarantee="NONE", secureWSDLAccess=false)

                              • 12. Re: JbossWS username authentication not working
                                Viacheslav Garmash Newbie

                                And this is a catch! You just gave me information for server side which I don't need at all because I am writing a client application that deloyed into JBoss server and it is consuming remote WS-Security protected webservice deployed somewhere in the interned on unknown server. And everybody who is in my position is confused with JBoss documentation because there is a lot of information about how to configure server side for web service, but only couple lines about how to create a client application. On the page you provided it is only 1 section "Use BindingProvider to set principal/credential" that describes quick and dirty way of setting password (don't think it should be used in production) but it is ommiting all steps that required before those lines start working and there is no information about different ways to configure client application.

                                So my question is still open...

                                • 13. Re: JbossWS username authentication not working
                                  Alessio Soldano Master

                                  Did you verify the message that actually goes to the wire, to see if ws-security is actually being used? Did you provide the proper descriptor (http://community.jboss.org/wiki/JBossWS-NativeUserGuide#Client_side_WSSE_declaration_jbosswsseclientxml) for configuring that?

                                  There're many working examples in the sources, take a look at the org.jboss.test.ws.jaxws.samples.wssecurity package for instance.

                                  There's also an "advanced" example described step by step on the wiki on this topic, see http://community.jboss.org/wiki/JBossWS-Securityandattachmentssample