cancel
Showing results for 
Search instead for 
Did you mean: 

correct way to provide the ticket

tim-erwin
Champ in-the-making
Champ in-the-making
Hi,

the way I chose to handle authentification  is:
  1. get the ticket from AuthenticationUtils.startSession(username, password); during the first request

  2. in the subsequent requests pass the ticket (saved in the session) to the AuthenticationCallbackHandler; all webservice calls will get the ticket from the latter
That's only 2 steps and with the CallbackHandler quite elegant though "hacky", since I had to write my own one, because the original one has no setTicket()-method. As described in this post that way works only most of the times and moreover causes problems when putting alfresco and my application on different servers (may be sth. different though).

sylvain78 proposed another approach: again using startSession(user, pass), storing the ticket and then providing it by creating the services with it as an argument, e.g.:
repositoryService = (RepositoryServiceSoapBindingStub)locator.getRepositoryService();
repositoryService.setPassword(details.getTicket());

A third approach I found in theses forums was to create and destroy a session for each request. That would be quite easy, however, supposedly not elegant nor fast. Moreover, you have to store the user's password somewhere to re-authenticate and send it over the network over and over again.

What now is the correct way to authenticate? (Perhaps it helps to know that I develop an application running on a tomcat. The user sends requests to my application which then asks alfresco. The ticket is stored in the user's session of my application. So from alfresco's point of view my application is the client which is proud owner of an alfresco ticket…)

Thanks in advance,
Tim-Erwin
4 REPLIES 4

rwetherall
Confirmed Champ
Confirmed Champ
Hi,

I've had a look at this issue and I can see your problem.

At the moment the AuthenticationUtils callback method assumes that the ticket will come from the ThreadLocal held in that class.  If this is not the case it becomes tricky.

I think the correct way to resolve this is to create an interface called TicketProvider with one method getTicket().  The AuthenticationUtils class could then be provided with a ticket provider and it would use that implementation to get the ticket in the callback method. (instead of the method on AuthenticationUtils)

The default ticketProvider would be implemented to retrieve the ticket in the current manner, but if you wanted a different mechanism you could implement the interface and set your implemenation as the ticket provider to be used instead.

I've created a JIRA issue relating to this change.  If you get to it before I do then please feel free to make the change locally and add details of the changes to the JIRA ticket.  This will help to speed up the process of getting the change into the main build.

Cheers,
Roy

PS: You can find the JIRA issue here … http://issues.alfresco.com/browse/AR-2150

mcirwin
Champ in-the-making
Champ in-the-making
Does this mean there is no way to resolve the ticket issue in the current release without modifying Alfresco code?

If so - how can we use the Web Services?

I am struggling with this issue right now.

Thanks.

tim-erwin
Champ in-the-making
Champ in-the-making
Hi McIrwin,

there is a way. It just means to re-implement some code. It's mainly copy and paste, however. As mentioned above there is the way sylvian78 did it. That however means that you have to provide either the ticket or ticketified services throughout your application.

I implemented my own ticket callback handler (again, mainly copy and paste from AuthenticationUtils). Provide the services with the correct  WS_SECURITY_INFO (containing your callback handler and remove the cookie handler) and you are done.

@Roy: Did not have time to fully implement that small thing, started it, but may still take some time…

Regards and good luck,
Tim-Erwin


Hey, I replied to your post before you even wrote it, nice, uh? Smiley Wink

mcirwin
Champ in-the-making
Champ in-the-making
Thanks Tim, I'll give that a try.

One thing I did was implement my own AuthenticationUtils and give that a "setAuthenticationDetails" method.  I then saved my authenticationDetails from a successful login.

If I call that set method immediately before trying anything,it works.
repositoryService = WebServiceFactory.getRepositoryService();
repositoryService.setPassword(m_ticket);

try
{
   Reference spacesStoreRef = new Reference();
   spacesStoreRef.setStore(m_spacesStore);
   spacesStoreRef.setPath("/");

   AuthenticationUtils.setAuthenticationDetails(m_authDetails);
   QueryResult qr = repositoryService.queryChildren(spacesStoreRef);

   return getObjectImp(qr);
}
catch (RemoteException re)
{
   m_log.error("Remote exception", re);
   throw new RException(0,re);
}