10 Replies Latest reply on Dec 13, 2010 2:31 AM by Martin Hochstrasser

    EJB3 JBossWS Authentication in 5.1.0 GA not working

    Judes Tumuhairwe Newbie

      Hi

      I've read this [1] and [2] and [3] and a whole bunch of others (including the JBoss In Action book) and they all say the same thing:

      1. Configure a data-source (*-ds.xml file)

      2. Define a domain (conf/login-config.xml)

      3. Tell the app about it:

          a. put the <security-domain> in jboss-web.xml and in the

          b. META-INF/jboss.xml

          c. add a security constraint in web.xml

       

      4. Annotate the EJB/Web-service with the security annotations (@SecurityDomain, @WebContext and @RolesAllowed in addition to @Stateless and @Webservice)

      5. build, package & deploy as an ear

      6. Add the values to the request-context map of the BindingProvider when calling...and everything should work.

       

      But nothing is working for me i.e. I keep getting a 401 error (Unauthorized). (I've been struggling with this for days now) Question is can anyone see what I'm doing wrong.

       

      Environment: Java version: 1.5.0_22, JBoss 5.1.0 GA, JBoss Web Services - Stack Native Core (3.1.2.GA)

       

      conf/login-config.xml (fragment)

       

      <application-policy name="verifiq-domain">  
          <authentication> 
                <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required"> 
                <module-option name="dsJndiName">java:/VerifiqDS</module-option> 
                <module-option name="principalsQuery">SELECT password FROM verifiq.sys204_users_vw WHERE username=?</module-option> 
                <module-option name="rolesQuery">SELECT role, 'Roles' FROM verifiq.sys203_user_role_vw WHERE username=?</module-option> 
                <module-option name="unauthenticatedIdentity">anonymous</module-option>
             </login-module> 
          </authentication> 
         </application-policy>

       

      [still gives a HTTP 401 even if I use the default JBossWS]

       

      The datasource (I've verified that this works)

       

      <datasources>
        <local-tx-datasource>
          <jndi-name>VerifiqDS</jndi-name>
          <connection-url>jdbc:postgresql://localhost:5432/tooro_eipp</connection-url>
          <driver-class>org.postgresql.Driver</driver-class>
          <user-name>THE-USERNAME</user-name>
          <password>THE-PASSWORD</password>
        </local-tx-datasource>
      </datasources>

       

      jboss-web.xml (the article [1] says its only for POJO's but it doesn't make a difference if I remove the <security-domain> tag)

      <?xml version="1.0" encoding="UTF-8"?>
      <jboss-web>
          <class-loading java2ClassLoadingCompliance="false">
              <loader-repository>
                  <loader-repository-config>
                      java2ParentDelegation=false
                  </loader-repository-config>
              </loader-repository>
          </class-loading>
          <context-root>/verifiq</context-root>
          
          <security-domain flushOnSessionInvalidation="false">verifiq-domain</security-domain>
      </jboss-web>
      

       

      jboss.xml (in the ejb jar's META-INF) Same as above i.e. doesn't make a difference if I uncomment.

      <?xml version="1.0" encoding="UTF-8"?>
      <jboss>
          <security-domain>verifiq-domain</security-domain>
          
          <!--
          <webservices>
              <context-root>/service</context-root>
          </webservices>
          <enterprise-beans>
            <session>
                <ejb-name>ExpulsionStatusBean</ejb-name>
                <jndi-name>ExpulsionStatusBean</jndi-name>
                <security-domain>verifiq-domain</security-domain>
      
                <port-component>
                    <port-component-name>ExplusionStatusServicePort</port-component-name>
                    <port-component-uri>/ExplusionStatusBeanPort</port-component-uri>
                    <auth-method>BASIC</auth-method>
                    <transport-guarantee>NONE</transport-guarantee> 
                    <secure-wsdl-access>false</secure-wsdl-access>
                </port-component>
                -->
                <!--
                <resource-ref>
                    <res-ref-name>jdbc/postgresql</res-ref-name>
                    <jndi-name>java:/VerifiqDS</jndi-name>
                </resource-ref>
                -->
                <!--
                <clustered>true</clustered>
                <cluster-config>
                    <partition-name>DefaultPartition</partition-name>
                    <load-balance-policy>org.jboss.ha.framework.interfaces.RandomRobin</load-balance-policy>
                 </cluster-config>
                 -->
                 <!--
              </session>
           </enterprise-beans>
           -->
      </jboss>
      

       

      ExpulsionStatusBean.java [intentionally skipped the contextRoot in @WebContext because:

      1. it puts the context (e.g. /service) outside the app's (/verifiq) i.e. security-constraint definitions in web.xml become useless since we now have localhost:8080/services and localhost:8080/verifiq.

      2. It applies that service to all the web-services in that ejb jar (even though I've explicitly asked for a different contextRoot on another web-service)

       

      Either way, even when I access them at a different location /services/serviceName?wsdl the result is the same i.e. HTTP 401]

      @Stateless
      @WebService
      @Local(ExplusionStatusService.class)
      @SecurityDomain(value="JBossWS")
      @RolesAllowed("friend")
      @WebContext(authMethod="BASIC", transportGuarantee="NONE", secureWSDLAccess=false)
      public class ExplusionStatusBean implements ExplusionStatusService, Serializable {
      
          @Resource
          private SessionContext context;
      
          @WebMethod
          public String expell(@WebParam(name="person") Person person) {
              String retVal = "Expelling " + person.getSchoolAssignedID();
              System.out.println("ExplusionStatusBean.expell(): invoked");
              System.out.println("ExplusionStatusBean.expell(): Student: " + person);
              System.out.println("ExplusionStatusBean.expell(): caller: " + context.getCallerPrincipal());
              System.out.println("ExplusionStatusBean.expell(): returning " + retVal);
              return retVal;
          }
      }
      

       

       

      Expeller.java (snipped just main() )

      public static void main(String[] args) {
              try {
                  log.info("Constructing...");
                  ExplusionStatusBeanService esb = new ExplusionStatusBeanService(new URL("http://127.0.0.1:8080/verifiq-verifiq-ejb/ExplusionStatusBean?wsdl"));
                  ExplusionStatusBean service = esb.getExplusionStatusBeanPort();
                  
                  log.info("Computing password");
                  String password = "thefrog";
                  //password = DigestUtils.md5Hex(password);
                  
                  //String pass =
                  log.info("Setting authentication info");
                  //BindingProvider bp = (BindingProvider)service;
                  //Map<String, Object> authentication = bp.getRequestContext();
                  ((BindingProvider)service).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "kermit");
                  ((BindingProvider)service).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
                  System.out.println("Using username kermit and password=" + password);
      
                  log.info("Invoking...");
                  Person person = getJudes();     // Person is just a regular JPA pojo (mapped) (with name & schoolId)
                  String response = service.expell(person);
                  log.info("Response receieved successfully! " + response);
      
              } catch (Exception ex) {
                  ex.printStackTrace();
                  log.log(Level.SEVERE, null, ex);
              }
          }
      

       

      server.log

      (I'm 100% certain the user kermit->thefrog exists in both the props/jbossws-*.properties file (when I use the default JBossWS) and in the database.)

       

      2010-10-12 01:09:07,797 DEBUG [org.jboss.security.auth.spi.DatabaseServerLoginModule] (http-127.0.0.1-8080-1) Bad password for username=kermit
      2010-10-12 01:09:07,797 DEBUG [org.jboss.security.auth.spi.DatabaseServerLoginModule] (http-127.0.0.1-8080-1) Bad password for username=kermit

       

      Like I said, I'm 100% certain the kermit exists & has the role 'friend' (see attached screenshot)

       

      Is there anything I'm missing?

       

      web.xml (supposedly for POJOs only but I've included a snippet anyway. Doesn't matter if I comment or uncomment it out. Same result "Bad password" error)

       

      <security-constraint>
                <web-resource-collection>
                     <web-resource-name>All webservices</web-resource-name>
                     <description>Protects all webservices</description>
                     <url-pattern>/service</url-pattern>
                </web-resource-collection>
                <auth-constraint>
                     <role-name>admissions-viewer</role-name>
                     <role-name>friend</role-name>
                </auth-constraint>
           </security-constraint>
      
           <security-role>
                <role-name>admissions-viewer</role-name>
           </security-role>
           <security-role>
                <role-name>friend</role-name>
           </security-role>
           <security-role>
               <role-name>admissions-manager</role-name>
           </security-role>
      
           <login-config>
                <auth-method>BASIC</auth-method>
                <realm-name>Verifiq Webservices Realm</realm-name>
           </login-config>
      

       

       

      I've gone over it countless times & I'm just frustrated. It really shouldn't be that hard to get it to work...in theory :-)

       

      Is there anything I'm missing?

      TIA,

       

      Judes Tumuhairwe

       

      References:

      [1] http://community.jboss.org/wiki/JBossWS-Authentication

      [2] http://www.coderanch.com/t/477889/JBoss/Securing-Application-JBoss

      [3] http://thatjavathing.blogspot.com/2009/05/authentication-and-authorization-with_30.html