Azure OAuth2.0 User Authentication
I’ve been working on an internal site with some collab and other widgets that come in handy and got to the point where I needed to lock it down to appropriate users. In the spirit of common credentials I chose to connect to our MS Azure AD and authenticate users out of that. Benefits in that there are common users and credentials and I don’t have to worry with maintaining a credentials database.
So I started googling “PHP with Azure AD” and came across some “easy” methods that resulted in me getting nowhere in a day. I’m not an everyday programmer so managing libraries and composer and all that other stuff tends to be more complicated that it should be. I often prefer to just build stuff out and that way I know what’s happening. As another obstacle, the documentation in Azure isn’t always the most up to date. Articles edited last month show buttons that don’t exist anymore etc. So here goes the first functional swing of MS OAuth with PHP “the easy way” – without libraries.
Process Flow: The official doc with its pretty flow charts can be found here, but we’ll break it down (hopefully) a little easier and track that flow at each step with what we need to do for that part to work.
Azure Config: First we need to register the Application in Azure AD under “App Registration.” Then we can start building out the rest. Things to note for later at this point is the Application (client) ID and the Directory (tenant) ID.
Next we need to create the redirect URL. This is the URL that MS will send the user to after the login is complete. When they are redirected MS will tack on some additional information in the form of a GET request that we can pull the good stuff out of. In this case I’m pointing it back to my login.php script that will handle most of the login process for me.
Step 1 – Get a Token: You recognize that the user isn’t logged on and you redirect them to MS sign-on page via a location header. The redirect URL contains your tenant ID as well as some other stuff.
- response_code=codec <- mandatory and always “code”
- client_id=<Application (client) ID <- the Application ID from Azure
- redirect_url=https://acme.com/login.php <- the redirect URL you want the user sent to after they authenticate
- resource=https://graph.microsoft.com <- Allows the app access to the graph API which lets us access the users AD profile
When the user is redirected they are greeted with the standard Office365 login portal for them to do all the normal login type stuff.
When they complete the login the browser will send or “redirect” the user to your redirect URL and add some values to the string in the “GET” variable type fashion. This is when we start actually doing stuff, but no fear, it’s actually not that much stuff.
Step 2 – Trade that Token for an Access Key: Here we need our script to pull the “code” variable out of the MS redirect string. Then we’ll use cURL to send some POST data back to MS. This POST data will have our Application (client) ID, the same redirect URL we’ve been using previously, the Client Secret and the token or “code” that MS sent us to use for this authentication session.
First we need to create the Client Secret in Azure. Under the App Registration click the Certificates & Secrets button and create a Secret and save for later.
Next we’ll start our login.php script. We want to check and see if the “code” variable is set. That will be the cheap trick to let us know that it is a redirect from MS and to process it as such. Then we will go ahead and define some variables and make the POST request to MS.
In the response we expect to receive a JSON string that includes the access key, expire information and a refresh key from MS.
Step 3 – Get the User’s Profile: Next We will do a second GET call to MS using their Graph API in order to get back the users profile so we can see who actually logged in as well as verify that the access key actually worked.
In the JSON formatted response we expect to see things like first and last name, user id, email address etc.
Step 4 – Start and Assign the Session: And Finally we will start the PHP session and assign some session variables in order to track the user through all our pages and send them to a post login page.
At this point the user is authenticated and has whatever access you deem needed. In my case being in the org was enough for me to trust you, but you can build access groups in Azure or manage access locally.
Step 5 – Authorize and Re-Authenticate the User: When a user browses to another page we will watch for the PHP session variables to allow access or redirect to the login process as needed. The access key expires on short intervals so we also want to refresh that key when we get close. As part of the session I’m storing the expire time (epoch time) and if we are within 20min I’m going ahead and refreshing the token with the refresh token provided earlier.