4 Replies Latest reply on Feb 25, 2008 10:00 PM by Nathan Thompson

    Security, SLSB, Webservice question

    Nathan Thompson Newbie

      Hi All,


      I'm trying to add some web services components to a project I've been working on. The web services themselves have been easy to get going, but the security aspect is giving me some trouble.


      I've implemented a login method in my web service stateless bean.  I've also setup the identity authenticator and referenced it in components.xml.  These both work, in so far as the authentication happens and returns true or false appropriately from the Indentity.instance().login call from my SLSB.


      The problem comes when I make a subsequent call to the SLSB, to a method annotated with

      @Restrict("#{identity.loggedIn}")

      (or using
      @Restrict("#{s:hasRole('Administrator')}")

      ...  I always get a NotLoggedInException.


      Am I supposed to be storing something in the session scope?  I thought the Identity component handled this already?


      Setup is jboss-4.2.2.GA, seam 2.0.1.ga, icefaces 1.7.0dr2.


      Here's component.xml:


      <?xml version="1.0" encoding="UTF-8"?>
      <components xmlns="http://jboss.com/products/seam/components"
       xmlns:core="http://jboss.com/products/seam/core"
       xmlns:security="http://jboss.com/products/seam/security"
       xmlns:transaction="http://jboss.com/products/seam/transaction"
       xmlns:web="http://jboss.com/products/seam/web"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd
                       http://jboss.com/products/seam/transaction http://jboss.com/products/seam/transaction-2.0.xsd
                       http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd
                       http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd
                       http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.0.xsd">
      
       <core:init jndi-pattern="STACS2/#{ejbName}/local" debug="true" />
      
       <!-- conversation-timeout = 30 minutes -->
       <core:manager conversation-timeout="1800000" />
      
       <component name="stacsDatabase"
        class="org.jboss.seam.persistence.ManagedPersistenceContext">
        <property name="persistenceUnitJndiName">
         java:/EntityManagerFactories/stacsData
        </property>
       </component>
       <security:identity authenticate-method="#{authenticator.authenticate}"/>
      
      </components>
      



      Web service remote interface:


      @Remote
      public interface TaskManagerServiceRemote {
          public boolean login(String userName, String password);
          public String restrictedAction();
      }
      



      Web service class:


      @Stateless
      @WebService(name = "TaskManagerService", serviceName = "TaskManagerService")
      @SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL)
      @Name("taskManagerService")
      public class TaskManagerService implements TaskManagerServiceRemote {
          @WebMethod
          public boolean login(
                  @WebParam(mode = Mode.IN, name = "userName") String userName,
                  @WebParam(mode = Mode.IN, name = "password") String password) {
              Identity identity = Identity.instance();
              identity.setUsername(userName);
              identity.setPassword(password);
              identity.login();
              return identity.isLoggedIn();
          }
          
          @WebMethod
          public @WebResult(name = "string") String restrictedAction() {
              StringBuilder sb = new StringBuilder();
              Identity identity = Identity.instance();
              
              sb.append("is security enabled: ");
              sb.append(Identity.isSecurityEnabled());
              sb.append("\r\n");
              sb.append("is remember me: ");
              sb.append(identity.isRememberMe());
              sb.append("\r\n");
              sb.append("is logged in: ");
              sb.append(identity.isLoggedIn());
              sb.append("\r\n");
              sb.append("has admin role: ");
              sb.append(identity.hasRole("Administrator"));
              return sb.toString();
              throw new NotLoggedInException
          }
      
      }
      



      Note that I've removed the @Restrict annotation here in an effort to see what is going on...  The message I always get in my soap client is that security is enabled, but rememberme, loggedin, and has admin role are always false, no matter if I've logged in or not.


      For good measure, hear's my Authenticator class:


      @Name("authenticator")
      public class Authenticator {
          @In
          Identity identity;
          @In(create = true)
          private EntityManager stacsDatabase;
          @Logger
          private Log log;
      
          public boolean authenticate() {       
              try {
                  char[] plainPassword = identity.getPassword().toCharArray();
                  char[] encodedPassword = CommonUtils.encodePassword(plainPassword);
                  User user = (User) stacsDatabase
                          .createQuery(
                                  "from User where lower(userid) = :userid " + 
                                  "and passwd_enc = :password " +  
                                  "and deactivated = false")
                          .setParameter("userid", identity.getUsername().toLowerCase())
                          .setParameter("password", String.valueOf(encodedPassword))
                          .getSingleResult();
                  if (user != null && user.getUserroleses() != null) {
                      for (Userroles userRole : user.getUserroleses()) {
                          Identity.instance().addRole(userRole.getRole().getRolename());
                      }
                  }
                  
                  return true;
              } catch (NoResultException rne) {
                  log.debug("authenticate: NoResultException!");
                  return false;
              } catch (NoSuchAlgorithmException nsae) {
                  log.debug("authenticate: NoSuchAlgorithmException!");
                  return false;
              }
          }
      }
      



      Thanks for your help!


      Nate

        • 1. Re: Security, SLSB, Webservice question
          Shane Bryzak Master

          Does your web service client support cookies?  It needs to have some way to store the session ID.

          • 2. Re: Security, SLSB, Webservice question
            Nathan Thompson Newbie

            Hi Shane,


            Thanks for your response.  On the client side I'm using the pocketSOAP library (the client is running in VB6).  According to the pocketSOAP documentation round-trip session cookies should be handled automatically.


            So I did a capture with Wireshark.  I see no evidence that jboss/seam is setting a cookie.  Here is a capture of the login call.  First the POST:


            POST /STACS2-STACS2/TaskManagerService?wsdl HTTP/1.1
            Host: cimtux:8080
            Accept-Charset: UTF-8, UTF-16;q=0.8, iso-8859-1;q=0.8
            Accept-Encoding: deflate, gzip
            Content-Type: text/xml; charset=UTF-8
            SOAPAction: ""
            User-Agent: PocketSOAP/1.5.4/PocketHTTP/1.2.7
            Content-Length: 367
            
            <S:Envelope
            .xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
            .xmlns:a="http://webservice.stacs.cimconsultants.com/"
            .xmlns:XS="http://www.w3.org/2001/XMLSchema"
            .xmlns:XI="http://www.w3.org/2001/XMLSchema-instance">
            <S:Body><a:login><userName XI:type="XS:string">user</userName><password XI:type="XS:string">password</password></a:login></S:Body></S:Envelope>
            



            And here is the response from the server:


            HTTP/1.1 200 OK
            Server: Apache-Coyote/1.1
            X-Powered-By: Servlet 2.4; JBoss-4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=200710221139)/Tomcat-5.5
            Content-Type: text/xml;charset=UTF-8
            Transfer-Encoding: chunked
            Date: Tue, 19 Feb 2008 14:42:56 GMT
            
            f5
            <env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><env:Header></env:Header><env:Body><ns2:loginResponse xmlns:ns2="http://webservice.stacs.cimconsultants.com/"><return>true</return></ns2:loginResponse></env:Body></env:Envelope>
            
            0
            



            I'm still missing something :(


            Thanks for your help!


            Nate


            • 3. Re: Security, SLSB, Webservice question
              Shane Bryzak Master

              I just tried a similar thing with the seambay example, using Ethereal to capture the packets.  Here's what I got:



              Request:


              POST /jboss-seam-bay-jboss-seam-bay/AuctionService HTTP/1.1
              Host: 192.168.1.211:8080
              User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12
              Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
              Accept-Language: en-us,en;q=0.5
              Accept-Encoding: gzip,deflate
              Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
              Keep-Alive: 300
              Connection: keep-alive
              Content-Type: text/xml
              Referer: http://192.168.1.211:8080/seam-bay/test.seam;jsessionid=5549E19FAD705C858E959258C546D929
              Content-Length: 285
              Cookie: JSESSIONID=5549E19FAD705C858E959258C546D929
              Pragma: no-cache
              Cache-Control: no-cache
              
              <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:sb="http://seambay.example.seam.jboss.org/">
                <soapenv:Header/>
                <soapenv:Body>
                  <sb:login>
                    <arg0>demo</arg0>
                    <arg1>demo</arg1>
                  </sb:login>
                </soapenv:Body>
              </soapenv:Envelope>
              



              Response:



              HTTP/1.1 200 OK
              Server: Apache-Coyote/1.1
              X-Powered-By: Servlet 2.4;
              JBoss-4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=200710221139)/Tomcat-5.5
              Set-Cookie: JSESSIONID=5549E19FAD705C858E959258C546D929; Path=/
              Content-Type: text/xml;charset=UTF-8
              Transfer-Encoding: chunked
              Date: Thu, 21 Feb 2008 01:21:25 GMT
              
              <env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
                <env:Header><seam:conversationId xmlns:seam='http://www.jboss.org/seam/webservice'>25</seam:conversationId></env:Header>
                <env:Body>
                  <ns2:loginResponse xmlns:ns2="http://seambay.example.seam.jboss.org/"><return>true</return></ns2:loginResponse>
                </env:Body>
              </env:Envelope>




              As you can see the session ID cookie is set in both the request and the response.  I'd guess that cookie support isn't turned on by default in your web service client.

              • 4. Re: Security, SLSB, Webservice question
                Nathan Thompson Newbie

                Shane,


                Thanks for your help with looking into this.


                I thought I'd post a follow up in case anyone else runs into the problem that I did.


                JBoss was not setting the session cookie no matter what I did.  Somewhere in the course of trying to get this up and running, I downloaded the new(er) version of seam (I had been using what came with JBossAS 4.2.2.GA, which was, I guess, seam 2.0.0.patch1, or something -- I don't remember anymore).  Anyway, in upgrading seam to 2.0.1.GA, I eventually noticed a small change in the documentation PDF (the seam-reference.pdf file).


                ....Drum roll please.....


                The name of the endpoint config file in the 2.0.0 docs is listed as standard-jax-ws-endpoint-config.xml, while the 2.0.1 docs list it as standard-jaxws-endpoint-config.xml.  Notice the extra dash in the 2.0.0 docs!


                once I changed that, everything started working.  Problem solved!


                just FYI: PocketSOAP seems to be working quite well now that the server is configured correctly ;)


                Again, thanks for your help!


                Nate