6 Replies Latest reply on Dec 2, 2009 4:50 AM by Matthew Cheng

    Trying to use jboss.xml instead of @WebContext

    Alexandros Karypidis Novice

      Hello,

      I'm trying to secure a web service with basic http authentication, but I want to keep all JBoss-specific configuration out of my code. Therefore, I need some pointers as to how to express the @WebContext annotation (used to specify BASIC http authentication) in the jboss.xml deployment descriptor.

      In more detail:

      I have my service implemented as a stateless session bean. I have found the following code works perfectly to require authorization, but uses JBoss-specific annotations (marked in bold font):

      @Stateless
      @WebService@SecurityDomain("JBossWS")@RolesAllowed("someRole")@WebContext(authMethod = "BASIC", transportGuarantee = "NONE", secureWSDLAccess = false)public class MyWSBean {
      //...
      }
      

      I therefore remove the @SecurityDomain and @WebContext annotations and added a jboss.xml deployment descriptor as follows:

      <?xml version="1.0" encoding="UTF-8"?>
      <jboss> <security-domain>java:/jaas/JBossWS</security-domain> <enterprise-beans>
       <session>
       <ejb-name>MyWSBean</ejb-name>
       <port-component>
       <port-component-name>MyWSBean</port-component-name> <auth-method>BASIC</auth-method> </port-component>
       </session>
       </enterprise-beans>
      </jboss>

      However, the configuration is not picked up for some reason. All attempts to access the web service fail due to an authorization failure. I can tell that the jboss.xml file is pared because if I mistype something (e.g. use <ejb-name>MyWSBeanWILLNOTMATCH</ejb-name>, or <security-domain>ThisDoesNotExist</security-domain>) then JBoss complains during deployment that the bean / realm does not exist.

      Specifically, I verified that my jboss.xml works for replacing the @SecurityDomain annotation by leaving @WebContext in the code and specifying the domain with the <security-domain> tag in jboss.xml: this works.

      Can anybody help me out with the proper deployment descriptor content for replacing the @WebContext?

      P.S. No other deployment descriptors exists (no webservices.xml and the ejb-jar.xml is empty).


        • 1. Re: Trying to use jboss.xml instead of @WebContext
          Alessio Soldano Master

          Which version of JBoss Application Server are you using? If it's 4.2.2.GA please try moving to 4.2.3.GA as this might be due to an already fixed bug.

          • 2. Re: Trying to use jboss.xml instead of @WebContext
            Alexandros Karypidis Novice

            Hello,

            I am using the very latest: JBossAS 4.2.3.GA and JBossWS-Native 3.0.3.GA.

            When my EJB is coded as follows:

            @Stateless
            @WebService(
             serviceName="MyBasicWS", portName = "MyBasicWSSOAP",
             targetNamespace = "http://www.example.org/MyBasicWS/",
             endpointInterface = "org.example.mybasicws.MyBasicWS")
            @WebContext(authMethod="BASIC")
            @RolesAllowed("friend")
            public class MyBasicWSImpl {
             public String echo(String in) {
             System.out.println("RECEIVED: " + in);
             return in;
             }
            }


            I use the following jboss.xml to set the security domain:

            <!DOCTYPE jboss PUBLIC
             "-//JBoss//DTD JBOSS 4.2//EN"
             "http://www.jboss.org/j2ee/dtd/jboss_4_2.dtd">
            <jboss>
             <security-domain>java:/jaas/JBossWS</security-domain>
             <webservices>
             <context-root>myBasicWS</context-root>
             </webservices>
            </jboss>


            Everything works like a charm with the combination above (I must access the EJB as kermit/thefrog from the default jbossws-xxxx.properties files). However, I want to get rid of the @WebContext annotation. My idea (which does not work) is the following combination:

            @Stateless
            @WebService(
             serviceName="MyBasicWS", portName = "MyBasicWSSOAP",
             targetNamespace = "http://www.example.org/MyBasicWS/",
             endpointInterface = "org.example.mybasicws.MyBasicWS")
            //@WebContext(authMethod="BASIC")
             //Undesirable
             //The above should be picked up from jboss.xml
            @RolesAllowed("friend")
            public class MyBasicWSImpl {
             public String echo(String in) {
             System.out.println("RECEIVED: " + in);
             return in;
             }
            }


            Then, I try to express that the EJB must use BASIC authentication method as follows:

            <!DOCTYPE jboss PUBLIC
             "-//JBoss//DTD JBOSS 4.2//EN"
             "http://www.jboss.org/j2ee/dtd/jboss_4_2.dtd">
            <jboss>
             <security-domain>java:/jaas/JBossWS</security-domain>
             <webservices>
             <context-root>myBasicWS</context-root>
             </webservices>
             <enterprise-beans>
             <session>
             <ejb-name>MyBasicWSImpl</ejb-name>
             <port-component>
             <port-component-name>MyBasicWSSOAP</port-component-name>
             <auth-method>BASIC</auth-method>
             </port-component>
             </session>
             </enterprise-beans>
            </jboss>


            In this case however, the client throws an authorization failure exception:

            javax.xml.ws.soap.SOAPFaultException: Authorization failure
             at org.jboss.ws.core.jaxws.SOAPFaultHelperJAXWS.getSOAPFaultException(SOAPFaultHelperJAXWS.java:77)
             at org.jboss.ws.core.jaxws.binding.SOAP11BindingJAXWS.throwFaultException(SOAP11BindingJAXWS.java:107)
             at org.jboss.ws.core.CommonSOAPBinding.unbindResponseMessage(CommonSOAPBinding.java:577)
             at org.jboss.ws.core.CommonClient.invoke(CommonClient.java:381)
             at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:291)
             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 $Proxy19.echo(Unknown Source)
             at test.TestBasicWS.basicAuthTest(TestBasicWS.java:41)


            On the server side, I see this:

            15:41:47,349 ERROR [RoleBasedAuthorizationInterceptor] Insufficient permissions, principal=null, requiredRoles=[friend], principalRoles=[]
            15:41:47,349 ERROR [SOAPFaultHelperJAXWS] SOAP request exception
            javax.ejb.EJBAccessException: Authorization failure
             at org.jboss.ejb3.security.RoleBasedAuthorizationInterceptor.invoke(RoleBasedAuthorizationInterceptor.java:120


            Apparently, JBoss disregards the BASIC-auth and does NOT assign a principal to the session. Therefore the role-based authenticator denies access to the method (as it should).

            Apparently, my jboss.xml does not tell JBoss to associate basic-auth with the published web service. I was suspicious of what I should put in the "port-component-name" value. Supposedly, the documentation says: Maps to the port-component-name in the webservices.xml descriptor. However, I do not use a webservices.xml file but use the @WebService annotation instead.

            In the code above I use the value for the "portName" attribute of @WebService but I also tried the ejb-name (MyBasicWSImpl) and the serviceName (MyBasicWS) with no luck.

            Any clues as to how I can achieve this while keeping the code JBoss-clear?


            • 3. Re: Trying to use jboss.xml instead of @WebContext
              Matt Meola Newbie

              Have you been able to get this working at all? I, too, cannot get JBoss to recognize the webservices/context-root element of jboss.xml. Since we won't do container-specific code, it means that EJB-based web services are a no go.

              I've tested this on JBoss AS 4.2.2.GA, 4.2.3.GA and 5.0.0.CR1; all no joy.

              • 4. Re: Trying to use jboss.xml instead of @WebContext
                Alexandros Karypidis Novice

                Sorry, still no joy.

                Since there is a valid interest in this, I suggest we open a feature request in JIRA. I have located http://jira.jboss.org/jira/browse/JBWS-1309 which seems relevant, but was closed as "outdated".

                If you need this as well, please watch that issue and comment to support having it re-opened.

                • 5. Re: Trying to use jboss.xml instead of @WebContext
                  Alessio Soldano Master

                  Please read my last comments on JBWS-1309 issue on Jira. This should work since August 2008, on AS 5 or later only. I've added 2 testcases showing that:
                  http://fisheye.jboss.org/changelog/JBossWS/?cs=9612
                  http://fisheye.jboss.org/changelog/JBossWS/?cs=9609

                  • 6. Re: Trying to use jboss.xml instead of @WebContext
                    Matthew Cheng Newbie

                    alessio.soldano, I did a test as your jboss.xml in http://fisheye.jboss.org/changelog/JBossWS/?cs=9609, the tag "auth-method" does work, but if I set it as null(<auth-method></auth-method>), JBoss prompts "Cannot configure an authenticator for method", my web services jar can not be deployed successfully. And since I want to secure the web services transport by HTTPS/SSL, I set the tag "transport-guarantee" to "CONFIDENTIAL" in the file jboss.xml, but it does not work, the WSDL published still has the soap adrress with "http" leading. I use jboss-5.1.0.GA.
                    This is the jboss.xml file I used:
                    <?xml version="1.0"?>
                    <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.2//EN" "http://www.jboss.org/j2ee/dtd/jboss_4_2.dtd">

                    <security-domain>java:/jaas/JBossWS</security-domain>

                    <context-root>/myservice</context-root>

                    <enterprise-beans>

                    <ejb-name>SendUpCommandBean</ejb-name>
                    <port-component>
                    <port-component-name>SendUpCommandBeanPort</port-component-name>
                    <port-component-uri>/*</port-component-uri>
                    <auth-method>BASIC</auth-method>
                    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
                    <secure-wsdl-access>false</secure-wsdl-access>
                    </port-component>

                    </enterprise-beans>