Office 365 Logon Enhancement – Username Capture
Hi,
I also found that signing in via a different Microsoft landing page results in a different POST request to the Idp. Different again from the new and old sign-in experience.
The particular landing page I came across was office365.com, which redirects you to products.office.com. If you click sign in from here, the sign-in page looks very similar to the O365 new sign-in experience, however it's actually login.live.com.
The POST request to the IDP still has a referer of login.microsoftonline.com, however the username parameter doesn't exist. Fortunately however, the username is available in the Referer header with "login_hint=". The iRule below is based on Grahams with the added functionality of being able to grab the login_hint username when available.
The iRule is working in a Dev environment for these use-cases, however there may be others. By default these will still require manual input of username on the Idp. It could also be possible to make the iRule more efficient by putting the new sign in experience conditional statements (payload capture) first, assuming it is the most common sign-in method for a given client base.
The following iRule attempts to capture the Username for Office365 SAML SP initiated authentication requests
to allow pre-population of username on logon page. This iRule requires specific logic to be built in the VPE.
when HTTP_REQUEST {
Enable/disable iRule debug logging.
set o365usernamedebug 0
Check for for SAML POSTS
if { [HTTP::uri] starts_with "/saml/idp/profile/redirectorpost/sso" && [HTTP::method] eq "POST" } {
if {$o365usernamedebug} {log local0.info "Request is a SAML POST"}
For logins via certain Microsoft landing pages - Check if Referer header contains login_hint
if { [HTTP::header exists "Referer"] } {
if {$o365usernamedebug} {log local0.info "POST Request has a Referer header"}
set refererHeader [HTTP::header "Referer"]
if { $refererHeader contains "login_hint="} {
set username [URI::decode [URI::query $refererHeader login_hint]]
if {$o365usernamedebug} {log local0.info "Referer header contains login_hint. Username = $username "}
}
unset refererHeader
}
For logins via new sign-in experience - Collect Payload to enable a search for a username parameter
Collect up to 1Mb of request content
if { ![ info exists username ] } {
if {$o365usernamedebug} {log local0.info "login_hint not available. Looking for username in payload"}
if { [HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] < 1048577 } {
set contentLength [HTTP::header "Content-Length"]
} else {
set contentLength 1048576
}
if { $content_length > 0 } {
HTTP::collect $contentLength
}
}
}
}
when HTTP_REQUEST_DATA {
For logins via new sign-in experience - check payload for username parameter
if { [ info exists contentLength ] } {
Parse the username from the collected payload
if { [HTTP::payload] contains "username="} {
set username [URI::decode [URI::query "?[HTTP::payload]" username]]
if {$o365usernamedebug} {log local0.info "Username parameter exists. Username = $username "}
HTTP::release
}
}
}
when ACCESS_SESSION_STARTED {
if { [ info exists username ] } {
ACCESS::session data set session.sso.custom.o365mail $username
}
}