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
In Sugar 126.96.36.199 (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 refresh 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 local storage, it will automatically regenerate a new access token, create/update database entry on the relevant table and a new PHP session, without the user even noticing (aside 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 user interface will automatically try to refresh the token using the refresh token stored on the browser’s local storage, and if successful it 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_*. This action will invalidate all current PHP sessions for the server. If the system leverages Memcache(d) or Redis as PHP session storage layer, the equivalent action should be performed.
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 removed only from the database table (containing refresh tokens), the system will not logout the users immediately. The system will fail to re-generate the next access token as soon as one of the following conditions is applicable:
- the current access token expires
- the 120 seconds maximum session/database cross check elapses (defined on include/SugarOAuth2/SugarOAuth2Storage.php with TOKEN_CHECK_TIME = 120)
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.