How does authentication work in Sugar 7?

Different application’s approach: Sugar 7 framework

For whoever is reading this article and is not familiar with Sugar on the most recent version 7.x of the product, it is important to note that the application’s core is now a RESTful based API.

The presentation layer is based on SugarCRM’s framework “Sidecar”, that uses quite a few Open Source libraries (including Bootstrap, jQuery, Handlebar and Backbone.js).

The framework’s MVC layer is cached/stored within the browser at the first application’s load and interacts with the REST API on every subsequent call, creating a more powerful experience as a Single Page Application.

The great concept around the newer application’s framework is that everything can now be achieved interacting with the application via API calls, if it can be done in the application by using the interface (except BWC functionality).

By doing so, the framework provides extreme flexibility and huge integration capabilities, and therefore it allows customers to build any business process around the application.

Local authentication in Sugar 7

Sugar 7 - Login Page
Sugar 7 – Login Page

In Sugar 7.5.0.1 (current version of Sugar) there are quite a few moving parts in regards to the authentication and session management.

When using the standard application’s interface, the application completes an OAuth token request passing the user’s credentials at login.

From that point onwards the OAuth token is passed through every authenticated HTTP request’s header (it is vital to use SSL to guarantee security).

The OAuth token, the refresh token (used to obtain an additional token when the current one expires) and the download token (used to download files from the API) are stored on the browser’s local storage, easily retrieved and used by Sidecar.

Let’s answer some questions

Now the functionality is pretty straight forward, but let’s answer some questions that will highlight the application’s behaviour.

What happens on the backend at login?

At first, the system invalidates any previously active token for the user (oauth_tokens database table), and then adds a new entry on that database table, containing the refresh_token as record id, the download_token, the expiry date and quite a few other info.
The system will then create a PHP session (on whatever is the PHP session storage of choice. By default on a vanilla linux PHP install, the file will be on /var/lib/php/sess_<session_id>) containing all the required info to run the application.

What happens when the PHP session expires?

If the browser contains a valid refresh_token on its cache, it will automatically regenerate a new token, create a new database entry on the relevant table and a new PHP session, without the user even noticing (apart from a HTTP 401 error on the browser’s console). If the refresh_token is no longer valid or non-existent, it will redirect the user to the login page.

What happens when the OAuth token expires?

This is basically the same as “What happens when the PHP session expires?”. When the system receives a HTTP 401 error (stating that the access token provided is invalid) the interface will automatically try to refresh the token using the refresh_token stored on the browser’s cache, and if successful will complete the action requested, otherwise the application will redirect the user to the login page.

How do I enforce a token revalidation for every user?

If using the standard PHP session storage, and the server is running only Sugar (making sure not to affect any other application running on the server) it is just a matter of deleting any active session file located usually in /var/lib/php/sess_*

How do I forcefully log out every user from the application?

You would need to remove every entry from the database table “oauth_tokens” and in addition to that, complete the same action as “How do I enforce a token revalidation for every user?”. We would basically be telling the application to expire the current re-validation tokens available to the users and also to invalidate any current access token in use.
If the entries are only removed from the database table, it will only fail to re-generate the next token as soon as the current one expires, but it will not logout the users right away.

Are there any settings that can help tweak the duration of the tokens?

Yes! You can add/modify some parameters within the file config_override.php of the application, that will let you change some parameters:

  • You can change the duration of the access token (default 1 hour):
     $sugar_config['oauth2']['access_token_lifetime'] = <seconds>;
  • You can change the duration of the refresh token (default 2 weeks):
     $sugar_config['oauth2']['refresh_token_lifetime'] = <seconds>;
  • Optionally you can set the MAXIMUM time that a user can be logged in for (default not set) before triggering a logout:
     $sugar_config['oauth2']['max_session_lifetime'] = <seconds>;

Where is the standard PHP session cookie? Is it gone?

No, at least not yet! It is currently generated/used only for functionality in backward compatibility mode (BWC).
As soon as a page in backward compatibility is loaded, it will automatically store the PHP session cookie (if not yet existing) on the browser and then proceed with loading the requested page. The session id on the PHP session cookie has the same value as the OAuth token.

 

That’s all for today! I hope this post helps you understand more about how authentication works when using the local user management in Sugar.

If you have additional questions please let me know and I will try to find an answer for you.

6 thoughts on “How does authentication work in Sugar 7?

  1. Enrico, a nice introduction. I’m keen to look at the code to get to know it better. Thanks for the blog.

  2. Enrico,

    How does it know that the PHP session has ended? Does it receive a 401 on the API request, and it assumes that the PHPSESSION is expired?

    Is there any way I can ask you to shed light on the refresh token? What is it? When is it needed? Why do we need a refresh token?

  3. Hi Michael,

    Access tokens, and refresh tokens are standards on the OAuth authorisation framework (https://tools.ietf.org/html/rfc6749#section-1.4 and https://tools.ietf.org/html/rfc6749#section-1.5).
    Access tokens are used to access a system, refresh tokens are used to gain a new access token on expiration.

    If the PHP session expires or if your access token expires, you would receive a 401 HTTP error code on your browser. The Sugar UI would automatically obtain a new access token (using the refresh token) and re-connect to the last accessed page. If the refresh token (stored within the database) is no longer valid, it would instead redirect you to the login page.

    Hope it helps!

  4. Is it possible to force a login of a particular user with a known user who passed in headers to the application by security middleware sitting between user and server?

    the headers are never seen by the client side. the problem is getting the UI side to recognize it is logged via the custom authenticator on the backend. on page load to trigger based on the ‘authenticated_user_id’ in the $_SESSION.

  5. Hi Max,

    This is a really interesting question and I actually had to solve the problem myself recently for an Enterprise Sugar implementation.

    You could setup natively SAML if you do have the option on your environment/infrastructure as that would be the easiest way for you to move forward and supported out of the box.

    If you do need to follow a custom solution you have two approaches that you could try to leverage:

    • Extend the current SAML authentication classes/methods/behaviours. You should be able to have your custom logic and read the headers, similarly to what currently happens with SAML authentication
    • Extend sidecar javascript routing. You should be able to identify that the user needs a token, call an additional api that then on the server side completes the custom logic with your headers and eventually returns a valid token that is stored into your brower’s storage by your sidecar customisation

    I would try with the first approach, and then if it does not allow you to fulfil 100% your requirements move on to the second one.

Leave a Comment