F5’s Access Policy Manager (APM) offers many compelling security and optimization features for Microsoft’s Active Directory Federation Services (ADFS) – more info in the APM/ADFS Deployment Guide. Odds are if you’re deploying ADFS you’re also using or looking at Office 365. Normally, when you login to O365 you will be redirect to a Home Realm Discovery page, login.microsoftonline.com. This page does 2 things:
- determines if you’re a federated users (i.e. you use another authentication source like F5, MS ADFS, Okta, …. <insert long list of IDMs on the market today>).
- if you’re not a federated user, authenticate you against Azure AD.

So when you type in your email address Microsoft parses the domain name and automatically redirects you to your local APM/ADFS environment for authentication – pretty nice! However, when you land at the APM login page you notice the username field is empty and you have to enter your username or email address (depending on how APM is configured for authentication) again.
You can fix this by customizing the APM Visual Policy Editor to look for O365 to ADFS logins and prepopulate the username.

So what does the APM configuration look like?

Step 1: Create an object to detect O365 to ADFS Login
- Click the (+) button on the Start fallback branch
- In the search box type empty and select the Empty resource then click “Add Item”
- Name the resource O365 Login
- Click on the “Branch Rules” tab and click “Add Branch Rule”
- Name the branch “Yes” and add the following expression via the advance tab
- expr {[mcget {session.server.landinguri}] contains “username=”}
- Click Save

Step 2: Extract the Username from the O365 Redirect Request
When the user enters their email address into the O365 login this data is included in the GET request back to the APM/ADFS environment.


To capture this data we’ll need to create perform the following steps:
- Click the (+) button on the Yes branch off of O365 Login
- In the search box type variable and select the Variable Assign resource then click “Add Item”
- Name the resource “set username from O365” and add the following variables
session.logon.last.username = expr {[string range [mcget {session.server.landinguri}] [mcget {session.custom.pos_username}] [mcget {session.custom.pos_at_sign}]] }
session.custom.pos_at_sign = expr {[string first “%40” [mcget {session.server.landinguri}]] – 1}
session.custom.pos_username = expr {[string first “username=” [mcget {session.server.landinguri}]] + 9}
Click “Finished” and then click “Save”

Step 3: Customize the APM Logon Page
Now that we have the username we need to prepopulate it on the APM Logon page and set the form variable to read only.
- Click the (+) button on the “set username from O365” fallback branch
- Select “Logon Page’ then click “Add Item”
- Name the resource “O365 Logon Page”
- Change the “Read Only” setting for field 1 to “Yes”
- Click “Save”

The remainder of the VPE configurations are basic and are not covered in this article to keep it from being a novel.
That’s it! Now you’re user’s only have to enter their information once which will definitely make them happier.
Great article. One item you should correct is 3.1 “Click the (+) button on the “set username to UPN” fallback branch” should be “Click the (+) button on the “set username from O365” fallback branch”.
For some reason, O365 isn’t sending the username, when doing the GET request on my system, so I’m unable to populate the username field. Any idea what would cause this, or have they changed the functionality removing it?
They functionality hasn’t been removed but I have seen issues where the username is not the first object in the payload with an equal sign.. i.e. there is another something=value before username. Let me know if you can post a sanitized version of your payload and I’ll take a look.
Great article Cody. One question, When I am using the above expression in variable assign, I am not able to save it. Is there any reason behind it. I just copied and pasted there. Please advise me.
Thanks,
Shri
Yes, sometimes the quotes do not copy over as the correct unicode character in TCL. Delete all ” and replace them manually.
Thank you Cody. It is working now and I entered those manually. I have one more question on APM if you can answer that, it will be very helpful to me. I am working on one policy and that policy has to authenticate Local DB users and AD users but I am not able to make it that success. Might be I am missing something. Can you please check below policy.
Did you write any article for remaining steps. I mean from AD to sso creds mapping ?
No, that is cover in other documents by F5: https://support.f5.com/kb/en-us/products/big-ip_apm/manuals/product/apm_config_10_2_0/apm_config_sso.html
Hi Cody,
Thank you for this. I got it working. I would like to understand the significance of the ‘+9’ and ‘-1’ in the session variables. Also, how can i insert the UPN instead of the sAMAccountname.
Thanks,
karthik
These TCL string operations are trying to extract the required variable out of landing URL on the F5 APM. So I’m looking for the @ sign in the landing URI (the -1 is so I don’t include it) then I look for username= (which is 9 characters and is why you see the +9). The username is everything between these two points in the string.
Thanks. That’s what I was thinking as well. So by not including the @ sign you are stripping away anything that comes after the @ sign which in effect leaves you with the sAMAccountname. How would I modify this to include the domain name (i.e UPN)