Version 5

    Securing a service endpoint

     

    First we secure the access to the SLSB as we would do for normal (non web service) invocations.

     

    In ejb-jar.xml, we setup the method permissions for the SLSB endpoint. Note that it is not necessary required for the endpoint to have home/remote interfaces.

      <enterprise-beans>
        <session>
          <ejb-name>SecuredSLSB</ejb-name>
          <remote>com.underworld.crimeportal.ejb.SecuredRemote</remote>
          <home>com.underworld.crimeportal.ejb.SecuredRemoteHome</home>
          <service-endpoint>com.underworld.crimeportal.OrganizationEndpoint</service-endpoint>
          <ejb-class>com.underworld.crimeportal.ejb.SecuredSLSB</ejb-class>
          <session-type>Stateless</session-type>
          <transaction-type>Container</transaction-type>
          <security-role-ref>
            <role-name>friend</role-name>
          </security-role-ref>
        </session>
      </enterprise-beans>
    
      <assembly-descriptor>
        <security-role>
          <role-name>friend</role-name>
        </security-role>
    
        <method-permission>
          <role-name>friend</role-name>
          <method>
            <ejb-name>SecuredSLSB</ejb-name>
            <method-name>*</method-name>
          </method>
        </method-permission>
      </assembly-descriptor>
    

     

    Next, define the security domain for this deployment. The JBossWS security context is configured in login-config.xml and uses the UsersRolesLoginModule.

    <jboss>
      <security-domain>java:/jaas/JBossWS</security-domain>
      <enterprise-beans>
        <session>
          <ejb-name>SecuredSLSB</ejb-name>
          <jndi-name>ejb/SecuredSLSB</jndi-name>
        </session>
      </enterprise-beans>
    </jboss>
    

     

    At last, make sure that your WSDL files point to the right url. Otherwise your webservice client may be redirected to the unsecure HTTP access method. The easiest way is to add "https://" to the SOAP Address entry:

    <soap:address location="https://REPLACE_WITH_ACTUAL_URL"></soap:address>
    

     

    At this point you might want to check that the JRMI access to the SLSB is actually secured.

     

    Use JAXRPC to set principal/credential

     

    A web service client may use the javax.xml.rpc.Stub object to set the username/password combination

     

       public void testWebServiceAccess() throws Exception
       {
          OrganizationEndpoint endpoint = service.getPort(OrganizationEndpoint.class);
    
          Stub stub = (Stub)endpoint;
          stub._setProperty(Stub.USERNAME_PROPERTY, "kermit");
          stub._setProperty(Stub.PASSWORD_PROPERTY, "thefrog");
    
          String info = endpoint.getContactInfo("mafia");
          assertEquals("The 'mafia' boss is currently out of office, please call again.", info);
       }
    

     

    Note, that this approach uses SOAP headers to propagate the pricipal/credential information to the server. The headers themselves are JBoss specific and therefore not interoperable with other Web Services implementations out of the box.

     

    <soapenv:Envelope ...>
     <soapenv:Header xmlns:jbws="http://webservice.jboss.com/ws4ee">
      <jbws:username actor="http://webservice.jboss.com/ws4ee/login">kermit</jbws:username>
      <jbws:password actor="http://webservice.jboss.com/ws4ee/login">dGhlZnJvZw==</jbws:password>
     </soapenv:Header>
     <soapenv:Body>
      <ns1:getContactInfo xmlns:ns1="http://com.underworld.crimeportal">
       <String_1>mafia</String_1>
      </ns1:getContactInfo>
     </soapenv:Body>
    </soapenv:Envelope>
    

     

    Using HTTP Basic Auth for security

     

    An alternative to the SOAP headers, is generic HTTP authentication, which is supported by most Web services toolkits. To enable this you need to add a port-component descriptor to your jboss.xml file, which contains an auth-method tag. We just modify the jboss.xml in the example above to end up with the following result.

     

    <jboss>
      <security-domain>java:/jaas/JBossWS</security-domain>
      <enterprise-beans>
        <session>
          <ejb-name>SecuredSLSB</ejb-name>
          <jndi-name>ejb/SecuredSLSB</jndi-name>
          <port-component>
            <port-component-name>OrganizationEndpoint</port-component-name>
            <port-component-uri>/organization/*</port-component-uri>
            <auth-method>BASIC</auth-method>
          </port-component>
        </session>
      </enterprise-beans>
    </jboss>
    

     

    Requiring SSL

     

    You can also require that all webservice requests use SSL by adding the transport-guarantee tag in your jboss.xml file. We will now modify our HTTP basic auth example jboss.xml file to also require that SSL is used.

    <jboss>
      <security-domain>java:/jaas/JBossWS</security-domain>
      <enterprise-beans>
        <session>
          <ejb-name>SecuredSLSB</ejb-name>
          <jndi-name>ejb/SecuredSLSB</jndi-name>
          <port-component>
            <port-component-name>OrganizationEndpoint</port-component-name>
            <port-component-uri>/orgainization/*</port-component-uri>
            <auth-method>BASIC</auth-method>
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </port-component>
        </session>
      </enterprise-beans>
    </jboss>
    

    Note: If your hostname does not match the ssl certificate name, you have to implement your own

    HostnameVerifier

    and make it the default

    HostnameVerifier

    via

    javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier()

    .

     

    Setting the system property

    org.jboss.security.ignoreHttpsHost

    to true does not work for JBossWS4EE!