cancel
Showing results for 
Search instead for 
Did you mean: 

TICKET problem in Alfresco Session

alexcocia
Champ in-the-making
Champ in-the-making
Hi all,

I want to keep Alfresco session along with my app session, and when navigating through the tree, some times (no reason or patron seen), it shows the following error, when trying to get a node's children

this is how I get the node's children:
queryResult = WebServiceFactory.getRepositoryService().queryChildren(reference);

and it's output:
WSDoAllSender: password callback failed; nested exception is:
org.alfresco.webservice.util.WebServiceException: Ticket could not be found when calling callback handler.

I'm not using clustering in the server…..

Any ideas?
Thanks in advance….
18 REPLIES 18

alexcocia
Champ in-the-making
Champ in-the-making
Having a look at the code, I've seen that AuthenticationUtils uses:

private static ThreadLocal<AuthenticationDetails> authenticationDetails = new ThreadLocal<AuthenticationDetails>();

to store ticket credentials.
I want to use the ticket through my web application's life cycle. My tomcat uses ThreadPool, so I think I cannot use this implementation of the web services client…

Any Idea?, Am I wrong? What can I do…….

sylvain78
Champ in-the-making
Champ in-the-making
I had the same problem.  The user sessions were getting mixed up because of the ThreadPool.

Here is the class I use to work with a ticket.

Basically, I took the startSession, the endSession and the WS_SECURITY_INFO from the AuthenticationUtils class and add them to WebServiceFactory.  I don't use the callbackHandler anymore, I just set the password (ticket, in fact…) right away whenever I call a service.

I had to make a few changes to other class, such as ContentUtils, etc.

This solution doesn't use the CookieHandler.  What do you think the CookieHandler is used for?  All I know is that it works without it!


public final class WebServiceClient
{
    /** Log */
    private static Log logger = LogFactory.getLog(WebServiceClient.class);
   
    /** Property file name */
    private static final String PROPERTY_FILE_NAME = "alfresco/webserviceclient.properties";
    private static final String REPO_LOCATION = "repository.location";
   
    /** Default endpoint address **/
    private static final String DEFAULT_ENDPOINT_ADDRESS = "http://localhost:8080/alfresco/api";
    private static String endPointAddress;
   
    /** Service addresses */
    private static final String AUTHENTICATION_SERVICE_ADDRESS  = "/AuthenticationService";
    private static final String REPOSITORY_SERVICE_ADDRESS      = "/RepositoryService";
    private static final String CONTENT_SERVICE_ADDRESS         = "/ContentService";
    private static final String AUTHORING_SERVICE_ADDRESS       = "/AuthoringService";
    private static final String CLASSIFICATION_SERVICE_ADDRESS  = "/ClassificationService";
    private static final String ACTION_SERVICE_ADDRESS          = "/ActionService";
    private static final String ACCESS_CONTROL_ADDRESS          = "/AccessControlService";
    private static final String ADMINISTRATION_ADDRESS          = "/AdministrationService";
    private static final String DICTIONARY_SERVICE_ADDRESS      = "/DictionaryService";
   
    /** WS security information */
    private static final String WS_SECURITY_INFO =
         "<deployment xmlns='http://xml.apache.org/axis/wsdd/' xmlns:java='http://xml.apache.org/axis/wsdd/providers/java'>" +
         "   <transport name='http' pivot='java:org.apache.axis.transport.http.HTTPSender'/>" +
         "   <globalConfiguration >" +
         "     <requestFlow >" +
         "       <handler type='java:org.apache.ws.axis.security.WSDoAllSender' >" +
         "               <parameter name='action' value='UsernameToken Timestamp'/>" +
         "               <parameter name='user' value='ticket'/>" +
         "               <parameter name='passwordType' value='PasswordText'/>" +
         "           </handler>" +
//         "       <handler name='cookieHandler' type='java:util.CookieHandler' />" +
         "     </requestFlow >" +
         "   </globalConfiguration>" +
         "</deployment>";

    /**
     * Sets the endpoint address manually, overwrites the current value
     *
     * @param endPointAddress   the end point address
     */
    public static void setEndpointAddress(String endPointAddress)
    {
       WebServiceClient.endPointAddress = endPointAddress;
    }
   
    /**
     * Get the current endpoints host
     *
     * @return  the current endpoint host name
     */
    public static String getHost()
    {
        try
        {
            URL url = new URL(getEndpointAddress());
            return url.getHost();
        }
        catch (MalformedURLException exception)
        {
            throw new RuntimeException("Unable to get host string", exception);
        }
    }
   
    /**
     * Get the current endpoints port
     *
     * @return  the current endpoint port number
     */
    public static int getPort()
    {
        try
        {
            URL url = new URL(getEndpointAddress());
            return url.getPort();
        }
        catch (MalformedURLException exception)
        {
            throw new RuntimeException("Unable to get host string", exception);
        }
    }
   
    public static AuthenticationDetails startSession(String username, String password)
       throws AuthenticationFault
   {
      AuthenticationDetails details = null;
       try
       {
           // Start the session
          AuthenticationResult result = getAuthenticationService().startSession(username, password);
          details = new AuthenticationDetails(result.getUsername(), result.getTicket(), result.getSessionid());
       }
       catch (RemoteException exception)
       {
           if (exception instanceof AuthenticationFault)
           {
               // Rethrow the authentication exception
               throw (AuthenticationFault)exception;
           }
           else
           {
               // Throw the exception as a wrapped runtime exception
               throw new WebServiceException("Error starting session.", exception);
           }
       }
       return details;
   }

    public static void endSession(AuthenticationDetails details)
    {
        if (details != null)
        {
            try
            {
                getAuthenticationService().endSession(details.getTicket());
            }
            catch (RemoteException exception)
            {
                throw new WebServiceException("Error ending session.", exception);
            }
        }
    }

    /**
     * Get the authentication service
     *
     * @return
     */
    public static AuthenticationServiceSoapBindingStub getAuthenticationService()
    {
       AuthenticationServiceSoapBindingStub authenticationService = null;
        try
        {
            // Get the authentication service
            AuthenticationServiceLocator locator = new AuthenticationServiceLocator();
            locator.setAuthenticationServiceEndpointAddress(getEndpointAddress() + AUTHENTICATION_SERVICE_ADDRESS);               
            authenticationService = (AuthenticationServiceSoapBindingStub)locator.getAuthenticationService();
        }
        catch (ServiceException jre)
        {
           if (logger.isDebugEnabled() == true)
            {
              if (jre.getLinkedCause() != null)
                {
                 jre.getLinkedCause().printStackTrace();
                }
            }
  
            throw new WebServiceException("Error creating authentication service: " + jre.getMessage(), jre);
        }       
       
        // Time out after a minute
        authenticationService.setTimeout(60000);
       
        return authenticationService;
    }
   
    public static RepositoryServiceSoapBindingStub getRepositoryService(AuthenticationDetails details)
    {
       return getRepositoryService(details, getEndpointAddress());
    }
   
    /**
     * Get the repository service
     *
     * @return
     */
    public static RepositoryServiceSoapBindingStub getRepositoryService(AuthenticationDetails details, String endpointAddress)
    {
       RepositoryServiceSoapBindingStub repositoryService = null;          
      try
      {
          // Get the repository service
          RepositoryServiceLocator locator = new RepositoryServiceLocator(getEngineConfiguration());
          locator.setRepositoryServiceEndpointAddress(endpointAddress + REPOSITORY_SERVICE_ADDRESS);               
          repositoryService = (RepositoryServiceSoapBindingStub)locator.getRepositoryService();
          repositoryService.setPassword(details.getTicket());
            repositoryService.setMaintainSession(true);
       }
       catch (ServiceException jre)
       {
          if (logger.isDebugEnabled() == true)
           {
                if (jre.getLinkedCause() != null)
                {
                    jre.getLinkedCause().printStackTrace();
                }
           }
        
          throw new WebServiceException("Error creating repositoryService service: " + jre.getMessage(), jre);
      }       
   
      // Time out after a minute
      repositoryService.setTimeout(60000);     
       
        return repositoryService;
    }
   
    public static AuthoringServiceSoapBindingStub getAuthoringService(AuthenticationDetails details)
    {
       return getAuthoringService(details, getEndpointAddress());
    }
   
    /**
     * Get the authoring service
     *
     * @return
     */
    public static AuthoringServiceSoapBindingStub getAuthoringService(AuthenticationDetails details, String endpointAddress)
    {
       AuthoringServiceSoapBindingStub authoringService = null;
                 
        try
        {
            // Get the authoring service
            AuthoringServiceLocator locator = new AuthoringServiceLocator(getEngineConfiguration());
            locator.setAuthoringServiceEndpointAddress(endpointAddress + AUTHORING_SERVICE_ADDRESS);               
            authoringService = (AuthoringServiceSoapBindingStub)locator.getAuthoringService();
            authoringService.setPassword(details.getTicket());
            authoringService.setMaintainSession(true);
        }
        catch (ServiceException jre)
        {
            if (logger.isDebugEnabled() == true)
            {
                if (jre.getLinkedCause() != null)
                {
                    jre.getLinkedCause().printStackTrace();
                }
            }
  
            throw new WebServiceException("Error creating authoring service: " + jre.getMessage(), jre);
        }       
       
        // Time out after a minute
        authoringService.setTimeout(60000);      
       
        return authoringService;
    }
   
    public static ClassificationServiceSoapBindingStub getClassificationService(AuthenticationDetails details)
    {
       return getClassificationService(details, getEndpointAddress());
    }
   
    /**
     * Get the classification service
     *
     * @return
     */
    public static ClassificationServiceSoapBindingStub getClassificationService(AuthenticationDetails details, String endpointAddress)
    {
       ClassificationServiceSoapBindingStub classificationService = null;
           
        try
        {
            // Get the classification service
            ClassificationServiceLocator locator = new ClassificationServiceLocator(getEngineConfiguration());
            locator.setClassificationServiceEndpointAddress(endpointAddress + CLASSIFICATION_SERVICE_ADDRESS);               
            classificationService = (ClassificationServiceSoapBindingStub)locator.getClassificationService();
            classificationService.setPassword(details.getTicket());
            classificationService.setMaintainSession(true);
        }
        catch (ServiceException jre)
        {
            if (logger.isDebugEnabled() == true)
            {
                if (jre.getLinkedCause() != null)
                {
                    jre.getLinkedCause().printStackTrace();
                }
            }
  
            throw new WebServiceException("Error creating classification service: " + jre.getMessage(), jre);
        }       
       
        // Time out after a minute
        classificationService.setTimeout(60000);       
       
        return classificationService;
    }
   
    public static ActionServiceSoapBindingStub getActionService(AuthenticationDetails details)
    {
       return getActionService(details, getEndpointAddress());
    }
   
    /**
     * Get the action service
     *
     * @return
     */
    public static ActionServiceSoapBindingStub getActionService(AuthenticationDetails details, String endpointAddress)
    {
       ActionServiceSoapBindingStub actionService = null;
           
        try
        {
            // Get the action service
            ActionServiceLocator locator = new ActionServiceLocator(getEngineConfiguration());
            locator.setActionServiceEndpointAddress(endpointAddress + ACTION_SERVICE_ADDRESS);               
            actionService = (ActionServiceSoapBindingStub)locator.getActionService();
            actionService.setPassword(details.getTicket());
            actionService.setMaintainSession(true);
        }
        catch (ServiceException jre)
        {
            if (logger.isDebugEnabled() == true)
            {
                if (jre.getLinkedCause() != null)
                {
                    jre.getLinkedCause().printStackTrace();
                }
            }
  
            throw new WebServiceException("Error creating action service: " + jre.getMessage(), jre);
        }       
           
        // Time out after a minute
        actionService.setTimeout(60000);     
       
        return actionService;
    }
   
    public static ContentServiceSoapBindingStub getContentService(AuthenticationDetails details)
    {
       return getContentService(details, getEndpointAddress());
    }
   
    /**
     * Get the content service
     *
     * @return  the content service
     */
    public static ContentServiceSoapBindingStub getContentService(AuthenticationDetails details, String endpointAddress)
    {
       ContentServiceSoapBindingStub contentService = null;          
        try
        {
            // Get the content service
            ContentServiceLocator locator = new ContentServiceLocator(getEngineConfiguration());
            locator.setContentServiceEndpointAddress(endpointAddress + CONTENT_SERVICE_ADDRESS);               
            contentService = (ContentServiceSoapBindingStub)locator.getContentService();
            contentService.setPassword(details.getTicket());
            contentService.setMaintainSession(true);
        }
        catch (ServiceException jre)
        {
            if (logger.isDebugEnabled() == true)
            {
                if (jre.getLinkedCause() != null)
                {
                    jre.getLinkedCause().printStackTrace();
                }
            }
  
            throw new WebServiceException("Error creating content service: " + jre.getMessage(), jre);
        }       
       
        // Time out after a minute
        contentService.setTimeout(60000);      
       
        return contentService;
    }
   
    public static AccessControlServiceSoapBindingStub getAccessControlService(AuthenticationDetails details)
    {
       return getAccessControlService(details, getEndpointAddress());
    }
   
    /**
     * Get the access control service
     *
     * @return  the access control service
     */
    public static AccessControlServiceSoapBindingStub getAccessControlService(AuthenticationDetails details, String enpointAddress)
    {
       AccessControlServiceSoapBindingStub accessControlService = null;          
        try
        {
            // Get the access control service
            AccessControlServiceLocator locator = new AccessControlServiceLocator(getEngineConfiguration());
            locator.setAccessControlServiceEndpointAddress(enpointAddress + ACCESS_CONTROL_ADDRESS);               
            accessControlService = (AccessControlServiceSoapBindingStub)locator.getAccessControlService();
            accessControlService.setPassword(details.getTicket());
            accessControlService.setMaintainSession(true);
        }
        catch (ServiceException jre)
        {
            if (logger.isDebugEnabled() == true)
            {
                if (jre.getLinkedCause() != null)
                {
                    jre.getLinkedCause().printStackTrace();
                }
            }
  
            throw new WebServiceException("Error creating access control service: " + jre.getMessage(), jre);
        }       
           
        // Time out after a minute
        accessControlService.setTimeout(60000);
       
        return accessControlService;
    }
   
    public static AdministrationServiceSoapBindingStub getAdministrationService(AuthenticationDetails details)
    {
       return getAdministrationService(details, getEndpointAddress());
    }
   
    /**
     * Get the administation service
     *
     * @return  the administration service
     */
    public static AdministrationServiceSoapBindingStub getAdministrationService(AuthenticationDetails details, String endpointAddress)
    {
       AdministrationServiceSoapBindingStub administrationService = null;
           
        try
        {
            // Get the adminstration service
            AdministrationServiceLocator locator = new AdministrationServiceLocator(getEngineConfiguration());
            locator.setAdministrationServiceEndpointAddress(endpointAddress + ADMINISTRATION_ADDRESS);               
            administrationService = (AdministrationServiceSoapBindingStub)locator.getAdministrationService();
            administrationService.setPassword(details.getTicket());
            administrationService.setMaintainSession(true);
        }
        catch (ServiceException jre)
        {
            if (logger.isDebugEnabled() == true)
            {
                if (jre.getLinkedCause() != null)
                {
                    jre.getLinkedCause().printStackTrace();
                }
            }
  
            throw new WebServiceException("Error creating administration service: " + jre.getMessage(), jre);
        }       
       
        // Time out after a minute
        administrationService.setTimeout(60000);      
       
        return administrationService;
    }
   
    public static DictionaryServiceSoapBindingStub getDictionaryService(AuthenticationDetails details)
    {
       return getDictionaryService(details, getEndpointAddress());
    }

    /**
     * Get the dictionary service
     *
     * @return  the dictionary service
     */
    public static DictionaryServiceSoapBindingStub getDictionaryService(AuthenticationDetails details, String endpointAddress)
    {
       DictionaryServiceSoapBindingStub dictionaryService = null;
          
        try
        {
            // Get the dictionary service
            DictionaryServiceLocator locator = new DictionaryServiceLocator(getEngineConfiguration());
            locator.setDictionaryServiceEndpointAddress(endpointAddress + DICTIONARY_SERVICE_ADDRESS);               
            dictionaryService = (DictionaryServiceSoapBindingStub)locator.getDictionaryService();
            dictionaryService.setPassword(details.getTicket());
            dictionaryService.setMaintainSession(true);
        }
        catch (ServiceException jre)
        {
            if (logger.isDebugEnabled() == true)
            {
                if (jre.getLinkedCause() != null)
                {
                    jre.getLinkedCause().printStackTrace();
                }
            }
  
            throw new WebServiceException("Error creating dictionary service: " + jre.getMessage(), jre);
        }       
       
        // Time out after a minute
        dictionaryService.setTimeout(60000);

        return dictionaryService;
    }
   
    /**
     * Gets the end point address from the properties file
     *
     * @return
     */
    private static String getEndpointAddress()
    {
       if (endPointAddress == null)
       {
          endPointAddress = DEFAULT_ENDPOINT_ADDRESS;
   
           InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(PROPERTY_FILE_NAME);
           if (is != null)
           {
               Properties props = new Properties();
               try
               {
                   props.load(is);           
                   endPointAddress = props.getProperty(REPO_LOCATION);
                  
                   if (logger.isDebugEnabled() == true)
                   {
                       logger.debug("Using endpoint " + endPointAddress);
                   }
               }
               catch (Exception e)
               {
                   // Do nothing, just use the default endpoint
                   if (logger.isDebugEnabled() == true)
                   {
                       logger.debug("Unable to file web service client proerties file.  Using default.");
                   }
               }
           }
       }
       
        return endPointAddress;
    }

    /**
     * Gets the engine configuration used to create the web service references
     *
     * @return
     */
    public static EngineConfiguration getEngineConfiguration()
    {
        return new FileProvider(new ByteArrayInputStream(WS_SECURITY_INFO.getBytes()));
    }
}

Hope this helps

sylvain78
Champ in-the-making
Champ in-the-making
I may have forgotten to mention that I keep the authenticationDetails (not only the ticket) from the startSession and keep it in my webapp user session.

Whenever I call a web service, I send it along.

alexcocia
Champ in-the-making
Champ in-the-making
Hi sylvain,

I did a little test, and it seems to be working correctly… I think I have to change a bit of my code, but it will be ok, finally….

Thanks for the post!!!!

Alex

karkaletsis
Champ in-the-making
Champ in-the-making
I made the changes you refer to. But how do I pass the ticket from the session to the web service?

nuga
Champ in-the-making
Champ in-the-making
since i didn't want to modify their code.  i used an aspect to connect and disconnect each time i wanted to make a service call.  that way every time i connected to the service, it would start and stop a fresh session i didn't have to worry about invalid tickets
and i can just create service methods, and using the right selector in the aspect, it will automatically connect me so i dont' have to worry about including that logic in my service

public String connect() throws Exception {

      
      try {
         AuthenticationUtils.startSession(userName, password);
         AuthenticationDetails details = AuthenticationUtils.getAuthenticationDetails();
         EngineConfiguration config = AuthenticationUtils.getEngineConfiguration();
      
         return AuthenticationUtils.getTicket();
      } catch (AuthenticationFault e) {
         log
               .fatal(
                     "Caught Authentication Exception trying to start the session.",
                     e);

         throw e;
      }
   }

   public void disconnect() {
   
      AuthenticationUtils.endSession();

   }

sylvain78
Champ in-the-making
Champ in-the-making
The main concern with creating a new session each time you call the web service is that you send the username and password on the network every time.  You can see them clearly using tcpmon.

Anybody succeeded in encrypting the username and password in the SOAP envelope?

This is why I managed to reuse the ticket : WebServiceClient.getRepositoryService(authenticationDetails).get…

karkaletsis
Champ in-the-making
Champ in-the-making
thanks for your answer. I managed it. I store the Authentication details in the session and pass it to the web service.

hanoi
Champ in-the-making
Champ in-the-making
Hi, I'm facing a similar issue using web service client.
Let me describe my scenario: userX performes a login on alfresco system and tries to retrieve a content list using the given ticketid, 'ticketid_X'.
After 3/4 calls to the same method, the same user, using the same ticket, gets the following error while retrieving content list:
WSSecurityEngine: Callback supplied no password for: ticket

Just to be precise: I print the ticketid value for each call done to alfresco system: the ticketid is always set with the correct value 'ticketid_X'.

These are my configuration parameters:
- Alfresco'web.xml: session timeout is set to 60 minutes;
- Alfresco'configuration: ticket expiring time (expires_ticket) is set to false;
Could this the matter be related to cache-context.xml, (max cache size, which is set to 10)?
Any clues? How can I solve it?