Office 365 is becoming the attention centre of many companies those days. Integration of Office 365 in their portal become needed to add features like registering to an event in your Calendar, creating a contact directory from Azure AD or showing a message from a specific Teams. The Microsoft documentation explains well how to use the Microsoft Graph API with many technologies, but when it’s time to make it work in a java web application it can be challenging. Adding Liferay portal in the stack become a quest. The most complex part is authenticating your user with OAuth 2.0.
There are several pieces to put together for everything to work well for your users:
configuration is a configuration object that contains the definition of our application in Azure
The scope is the requested access to the Microsoft graph api, openid is required to do the authentication, offline_access give access to the api even if the user isn’t active, this gives us access to the refresh token that is useful to reduce the number of redirection the user has to do when he comme back.
The callbackURL is the URL of your application where the user will be redirected after authentication, we will see how to use it later.
Once we have our azureAuthService there are three useful calls that we can make.
Get the authorization URL:
We use the response_mode = form_post that will send a POST request to our application callbackURL. This is more secure than using a GET request and also cleaner for the users.
The state will be sent back to our callbackUrl unchanged, we will use it to know where to send the user after the completed authentication.
The prompt let us configure the Microsoft login prompt, more about it soon.
We can then send our users to the authorizationUrl and receive an id_token after a successful authentication.
Get the access token:
The ID_token received must then be validated and used to get an accessToken that will be usable to sign our following request to the Graph API.
Get a new access token when it’s expired:
The access token is valid for a short time, usually less than an hour. With the refresh token, we can get a new one without having to send the user to the authorizationUrl again. The refresh token is usually valid for at least a month but can be revoked from the Azure side.
The next step is to integrate the user redirection flow needed to authenticate the user. There is a good explanation of the flow in the Microsoft documentation. To summarize, we need to :
To process the authentication in a web application, we need to have complete control of the request, using a filter is all designed (this filter could easily be reworked to work outside Liferay). The filter needs to listen to your callbackURL :
The parameter code contains the id_token when the user successfully authenticate.
We use only one filter to handle the whole process. We need to first send the user to this filter, as no code will be received at that time, we process to step 0.
To keep the authentication the less intrusive possible to the user, we check if we already have a valid accessToken. authenticationService.isConnected does this verification and if needed will try to get a new accessToken from the refreshToken automatically.
If we do have a valid accessToken, we directly redirect the user to his destination page. If we do not, we continue to step 1.
We need to redirect the user to the authenticationURL. This URL is customized considering the actual user situation. In the best case, the user is already logged in Office 365, which is a high probability in an corporate setup. We first try to authenticate him without prompt on the Microsoft side, this only shows a blank page to the user while he is redirected. If that fail, we receive an interaction_required error, we can then redirect again the user with a login prompt that time, in that case, the user will see a blank page for a short time then the Microsoft login prompt, beside the URL change he wouldn’t notice being redirected 4 times. There are still two particular error cases, consent_required which happen if we ask more authorization than the user already consented, in this case we redirect the user to the authenticationURL with the PROMPT_CONSENT parameter, Microsoft login will directly show the consent form instead of going through the login form. The other case is access_denied, in this case, the user, or his admin, didn’t accept the required authorization, there is nothing we can do about it, except notify the user, so we redirect him to his destination page and handle the feedback from the API usage.
The second step happens when the user successfully login to the Microsoft side and accept all authorization requested. We then trigger the token validation which will persist the authentication detail. We then redirect the user to his destination page.
The MsGraph SDK for java already has a good usage documentation. The only missing part is how to provide the authentication coming from ScribeJava to the MsGraph SDK. We have to write an AuthenticationProvider that will be used to add the authentication to every request sent from the SDK. Here is the implementation of the AuthenticationProvider:
And we can finally register an event in our calendar:
I’ve shown here how to set up an OAuth 2.0 authentication with office 365 in a java web application. This setup could be used to access any OAuth 2.0 available api and although some Liferay tools were used in it, they are easy to replace with more common tool if your use case is outside of Liferay. The full working code is available here : https://github.com/savoirfairelinux/office-365-integration
As I said at the beginning, integrating this workflow in Liferay has some more gotcha. I’ll look at them in a next blog post.
Since 2010, we have been training, coaching and accompanying a range of enterprises and organizations in their digital transformation based on Liferay Portal solutions. Having received a number of awards and observed the rising success of our clients, today, we have unreserved confidence in what we can offer and […]
Montreal, QC – (October 11, 2017) – Savoir-faire Linux – a Canadian leader in providing expertise on a range of open source technologies to enable digital transformation strategies – announces today its participation as a Gold Sponsor at this year’s Liferay Symposium North America, hosted by Liferay. Liferay makes software that helps companies create digital experiences on […]
The Thumbnail Generator aims to improve and facilitate the generation of thumbnails provided by Liferay. This plugin was created during a project requiring a large number of thumbnails with precise dimensions in order to minimize the loading time of the web pages. Currently, Liferay is only capable of generating two different sizes of thumbnails, when […]
When it comes to deploying a common Java server on a common cloud infrastructure, a range of possibilities crosses one’s mind. This article presents some feedback on a particular, real-life, case of deploying Liferay Digital Experience (DXP, aka. Liferay 7 EE) on Microsoft’s Azure cloud platform. Initial Shopping List Liferay DXP, with Enterprise Subscription, fitting […]
I’m writing this note in response to Dwight Fischer’s post on ERP trends for Education. Dwight is CIO at Dalhousie University, and IT leader among his Canadian peers. There have been conversations, also largely led by ERP vendors such as Ellucian and Oracle, about the cloudification of ERP systems (or so-called Student Information Systems). Software […]