Adding Azure Active Directory Authentication to your UI5 application
Introduction
For the first time in nearly 3 years of working with UI5 I was recently tasked with using UI5 completely outside of SAP, a fact also highlighted by my recent post on exporting to excel using openUI5. This means that my backend isn't SAP but actually a MS .NET service and that this app won't even be deployed near an SAP landscape and will instead be a standalone application running the latest version of OpenUI5.
I mention all of this so you know why I'm doing the azure AD authentication inside of our UI5 application directly and this isn't going to be a post about implementing azure AD on your Fiori Launch Pad.
In this blog I will cover the creation/ configuration of our azure side/ portal as well as our front-end/ UI5 bits, my aim is simply to get Azure AD authentication on our application quickly and easily but not go much further than that.
Prerequisites
An Azure account with access to Azure Active Directory, which luckily for us and for the purposes of this blog is free and something we can just get by signing up over here.
Please note that they will (at least for me they did) ask for verification of a phone number as well as to take a debit card against your account. Your millage might vary if you're using an account already associated with Microsoft.
Register your application
First of all we want to goto the Azure portal , login and in the dashboard on the lefthand side you should see a section called "Azure Active Directory" click on that to come to the AD screen/ configuration.
Next you'll see a sort of 'sub menu' and an item called 'app registrations':
then simply click 'new application registration' as seen towards the top of your screen and fill out the information as appropriate:
I'm going to be using localhost for this application (as i've not deployed it) and so I'm going to make use of http://localhost:8080 for my applications sign-on URL.
Once created quickly click on 'manifest' and set "oauth2AllowImplicitFlow" to true as seen below:
Your UI5 application setup
As always we're going to start from a blank application with nothing really setup in it, I make use of ExpressUI5 (disclaimer I made this) to quickly create my new UI5 applications.
Similar to lots of my other blogs I'm once again going to make a folder called util and in that util folder we're going to place adal.js which stands for Active Directory Azure Library and I simply downloaded the minified version to place into my adal.js file.
We need to import this into our UI5 application, I've covered this before but here is a reminder below for importing via our manifest.json
Importing via the manifest
Our manifest.json as we know is the configuration of our application, this is typically where we'd define our ODATA model, other local JSON models, our routing etc but we can also import other JS files to load at the start of our application. This looks something like the following:
So inside of the 'resources' section create a new section called 'js' and then populate that with an array of our files to load which in this case is just out xlsx.js.
Implementing AD Authentication
The ADAL needs two main things for our authentication our tenant and our clientId both of which we can get from the portal. So our tenant will typically be our domain so in the case of my fresh and not domain connected up tenant/ setup it's my email (minus the @) .onmicrosoft.com and you can see this in the azude AD authentication section of the portal as seen below (name marked out):
Again your millage may vary with the tennant name, especially if you're doing this on your live azure system and it might instead read as something like your primary domain name.
And for the clientId this is actually the Application ID which we should have copied earlier from when we first registered the application but you can see them in the list again as below:
NOTE: you can click through to that and there's an easy 'copy to clipboard' functionality.
ADAL setup
So as listed above I've deiced to include adal.js inside of my manifest.json and for the purposes of this blog I'm going to just throw everything in the controller and use the onInit function of my primary controller.
We want to return our AuthenticationContext as defined in adal I made a type of function you're likely familiar with in structure that looks like this:
returnAuthContext: function () {
if (!this._authContext) {
var config = {
tenant: "yourorgurl.onmicrosoft.com",
clientId: "your Client ID",
postLogoutRedirectUri: window.location.origin,
cacheLocation: 'localStorage'
};
this._authContext = new AuthenticationContext(config);
}
return this._authContext;
},
So this is a lazy way of defining our auth context and it means that we don't re-define it each time we use it and is straight up copied from how we define similar things like fragments.
Logging into Azure
authenticateOnAzure: function(){
var authContext = this.returnAuthContext();
var user = authContext.getCachedUser();
if (user) {
//set user data to a model maybe?
} else {
this.loginAndSetToken()
}
},
loginAndSetToken: function(){
var authContext = this.returnAuthContext();
if (authContext.isCallback(window.location.hash)) {
authContext.handleWindowCallback();
}
var user = authContext.getCachedUser();
if (user) {
authContext.acquireToken(authContext.config.clientId, function (error, token) {
if (error) {
if (isCallback && !authContext.getLoginError()) {
window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
}
} else {
//Tokens are often required for secure API calls
localStorage.setItem("token", token);
}
});
} else {
authContext.login();
}
},
That's it! that's how easy logging into Azure really is with UI5, with the user object we get quite a bit of information back that might hold group information, their level of access/ setup in the AD etc which has many useful applications.
Logging out of Azure
Just to test this with lots of users (if you've set them up in your tenant) you can also implement a logout with is as simple as calling the function logout on your auth context as below:
var authContext = this.returnAuthContext();
authContext.logOut();
Conclusion
Azure AD was actually very easy to implement both on the front end and the azure portal which seemed a breeze to use over some other server providers that I've used in the past. Azure is quickly shaping up to be one of my favorite platforms and how easy this was to implement is one of the reasons why.
Do you want me to get more in-depth with Azure? let me know what sort of posts you'd like me to write about in the comments as I'm sure I'll look to do more with them in the future.
UPDATE:
I came back to this and updated it on the 5th of December due to a login loop and made my example project public here: GitHub Project
···