5 Replies Latest reply on Aug 17, 2008 6:53 AM by skajotde

    Web Service URL pattern

      Hello,

      I have a war file that publishes a POJO web service in JBoss (using the native stack in JBoss AS 4.2.2, which is probably JBossWS 2.0.1). I am trying to restrict access to the web service to authenticated users only. Adding a security-constraint in the deployment descriptor of the war with the * (asterisk) wild-character gets the job done. However, it also restricts access to the auto-generated WSDL published by JBoss.

      This is because JBoss publishes the WSDL under the servlet prefix, adding a ?wsdl parameter. For instance:

      <servlet>
       <servlet-name>MyTestWS</servlet-name>
       <servlet-class>...servlet-class>
       </servlet>
       <servlet-mapping>
       <servlet-name>MyTestWS</servlet-name>
       <url-pattern>/MyTestWS</url-pattern>
       </servlet-mapping>
       <security-constraint>
       <web-resource-collection>
       <web-resource-name>...</web-resource-name>
       <url-pattern>/MyTestWS/*</url-pattern>
       </web-resource-collection>
       ...
       </security-constraint>


      The above causes the web service to be published under:
      http://localhost:8080/MyTestWS

      and the WSDL is published under
      http://localhost:8080/MyTestWS?wsdl


      As a result, clients that try to access the stub generated with wsimport have a problem accessing the WSDL and fail. I need to keep a copy of the WSDL on the client for things to work as follows:

      URL wsdlURL = Launcher.class.getResource("MyTestWS.wsdl");
      // URL wsdlURL = new URL("http://localhost:8080/MyTestWS?wsdl"); // does not work
       QName serviceName = new QName("...",
       "...");
       MyTestWSService rss = new MyTestWSService(wsdlURL,
       serviceName);
       MyTestWS rs = rss.getMyTestWSPort();
      
       BindingProvider bp = (BindingProvider) rs;
       bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY,
       "xxx");
       bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY,
       "yyy");
      
       String t = rs.secureHello();

      The client is able to log in and access the MyTestWS web service when using a local copy of the WSDL only. How can I avoid this? I would like to have the client access the WSDL from the server. I need a way to either:

      1) publish the WSDL in another URL
      2) restrict access to the web service URL but put an exception for URL?wsdl
      3) set the login credentials earlier (as I do with BindingProvider) so that the WSDL can be accessed to construct the stub.

      I don't know how to do any of the above....



        • 1. Re: Web Service URL pattern
          peterj

          The WSDL is requested via a GET and the actual services are requested via POST. So you could limit security to POST requests:

          <security-constraint>
           <web-resource-collection>
           <web-resource-name>...</web-resource-name>
           <url-pattern>/MyTestWS/*</url-pattern>
           <http-method>POST</http-method>
           </web-resource-collection>
           ...
          </security-constraint>


          • 2. Re: Web Service URL pattern

            Hello,

            Thank you for that. It works indeed.

            However, it is an all-or-nothing method. Is it possible to control access to individual operations of the web service? In other words, can I have some methods in the POJO require authorization and others be accessible by all?

            The simple workaround would be to have two web services (one for public use and one for authorized-only use), but that would not be elegant in my case (there's just two operations that need to be public).

            • 3. Re: Web Service URL pattern
              peterj

              That is not possible within web.xml because all requests for a single web service use the same URL, so there is no way to differentiate between requests.

              • 4. Re: Web Service URL pattern

                Ok then. At least it's good to know it's actually not possible and not something I am unaware of.

                • 5. Re: Web Service URL pattern
                  skajotde

                  You can apply annotation @RolesAllowed, eg.:

                  holder for auth roles constant:

                  public class Roles {
                  private static final XXX = "033";
                  
                  }


                  and in Webservice:

                  @WebMethod
                  @RolesAllowed(Roles.XXX)
                  public void youMethod(....


                  This annotation is same as in EJB and use JAAS to configuration.