cancel
Showing results for 
Search instead for 
Did you mean: 

Alfresco login with custom authentication system

signjoy
Confirmed Champ
Confirmed Champ

Hi,

We have customized Alfresco login in order to validate user's credentials against our custom authentication system called AUS.

We have created our own class that extends AbstractAuthenticationComponent. In the authenticateImpl method we are making request to AUS and if the credentials are failed then it will go to check the credentials against Alfresco. 

We have another application that connects to Alfresco using CMIS api. This application keeps the CMIS session object alive for each request. But as each and every request goes through the authenticateImple method we are getting multiple calls to the AUS system. I think it is because the nature of the CMIS (REST).

We want to make the call to the AUS system only once when the first CMIS session created and first request comes to Alfresco or for the first login. In short no matter from where user logs in (Share, CMIS, WebDav, etc) there should be only one call to the AUS for that session.

Thanks you in advance

5 REPLIES 5

afaust
Legendary Innovator
Legendary Innovator

Implementing a custom authentication component is a bit more complex endeavor than can be easily discussed about in this platform. Let's try anyways...

  1. Did you implement your authentication component as a separate subsystem, or did you do it in the global Spring context, potentially overriding some core defaults?
  2. If the CMIS application is using a proper HTTP session (managing cookies), then you should not see any additional call to the authentication component. Bear in mind that keeping the CMIS session alive is not the same as keeping the HTTP session alive. The CMIS session is just a client-side concept, caching configuration + data so that even in HTTP session-less environments the application can continue to work while re-authentication is handled transparently (via the stored auth parameters).
  3. Authentication via the other protocols (Share, WebDAV etc) also relies on whether these use proper HTTP session management. In Share, this should already be the case out of the box, as its connector to the backend uses either a ticket- or session-based "persistence" of the Repository-tier authentication, meaning it only authenticates once (unless either the ticket or session expires or is invalidated). For WebDAV, it depends on the specific WebDAV client and how it handles sessions / authentication persistence. I have seen - in some cases - that the Microsoft Windows WebClient service (which handles most WebDAV interaction if accessing Alfresco via a mounted drive) actually "forgets" to use an already established session for some specific operations, and then re-performs the authentication handshake when requested by Alfresco. There is nothing that can be done in that case, unless you want to try and bugfix a Windows service...

signjoy
Confirmed Champ
Confirmed Champ

Thanks for your reply Axel Faust

We have authentication as a separate subsystem. Below is the authentication chain. 

authentication.chain=ausAuth1:ausAuth,alfrescoNtlm1:alfrescoNtlm

My main issue is, I want to stop the multiple calls to AUS system for each request either via Share or CMIS client.

As each request is going through authenticateImpl method of  org.alfresco.repo.security.authentication.AbstractAuthenticationComponent it makes call to AUS system too, as we have call to the AUS is in this method.

Have I implemented the correct class/way to intercept the login process and go to AUS system? Please suggest

We have below class to handle authentication for AUS.

public class AusAuthenticationComponent extends AbstractAuthenticationComponent implements InitializingBean, ActivateableBean {
{
@Override
protected void authenticateImpl(String userName, char[] password) throws AuthenticationException {

// Make call to AUS to check username and password are correct
AusResponse response = restTemplate.ausRequest(userName, String.valueOf(password));

if (response.error) {
// throw exception and will fall in NTLM authentication
throw new AuthenticationException("Some error message");
}

User user = response.getUser();
setCurrentUser(userName);
LOG.debug("Setting current user to : " + user.getId());
Map<QName, Serializable> personProperties = new HashedMap();
personProperties.put(ContentModel.PROP_FIRSTNAME, user.getFirstName());
personProperties.put(ContentModel.PROP_LASTNAME, user.getLastName());
personProperties.put(ContentModel.PROP_EMAIL, user.getEmail());
PersonService personService = getPersonService();
personService.setPersonProperties(userName, personProperties);
}
}

Thank you once again

afaust
Legendary Innovator
Legendary Innovator

As I said, depending on how the client reuses an already established session / ticket context, you may not be able to completely eliminate multiple calls to authenticateImpl. Generally speaking your code looks ok - the most important thing is the setCurrentUser call. First check if your CMIS application is reusing HTTP sessions, and check your Share configuration.

What you should not be doing is modifying the person properties as part of the authentication call. Ideally, you should probably implement a proper UserRegistry as part of your subsystem, so that Alfresco synchronizes users in a proper separate process.

signjoy
Confirmed Champ
Confirmed Champ

Our clients are using CMIS only and Share is used by the administrator. I am not much worrying about Share as there are hardly few logins from Share. But other apps that are using CMIS that sends numerous documents each day and that makes unnecessary calls to the AUS for already logged in users.

Just wanted to know when the request comes to my method authenticateImpl is there any way to check the ticket? whether it is expired or not? Each request will have ticket? CMIS, Share, WebDav, FTP, etc?

Thank you for your time

afaust
Legendary Innovator
Legendary Innovator

There will be no call to authenticateImpl if the client reuses a valid session or provides a valid ticket - those checks will be done at a higher level of Alfresco before the AuthenticationComponent is involved. Not every request to Alfresco will have a ticket provided by the client. WebDAV and FTP will never use tickets. Share will only use tickets in the default configuration when not using the /alfresco/wcs/ endpoint on the Repository-tier. CMIS will only use a ticket when the client application has been initialised with the user name "ROLE_TICKET" and the password set to the ID of a value ticket.