Hello Everyone! Today we are going to take an in-depth look at how Microsoft handles the authentication of a Microsoft Live account to a Microsoft Azure resource. The user experience may seem simple enough, but behind the scenes there is a lot going on with a number of federated authentication and authorization standards and protocols. We will use Fiddler and some online JWT decoders to capture what is going on.
For this scenario we will be using a Microsoft Live account with a username of dumactmstest@gmail.com that is not configured with MFA. The resource at Microsoft Azure we will be attempting to access is the Microsoft Azure Management Portal.
The first step is to navigate the browser to https://manage.windowsazure.com/ which will redirect us to https://login.microsoft.com with an OAuth 2.0 authorization request included in the header. Let’s take a closer look at the authorization request:
- The response_type parameter is set to code id_token which is requesting the response from the authorization server contain an authorization code and id token for the user after the user authenticates. The id token will be an Open ID Connect 1.0 identity token that will be returned from Open ID Connect Provider.
- The redirect_uri parameter is set to https://manage.windowsazure.com/ which indicates the endpoint the code and id token should be returned to.
- The client_id parameter is set to 00000013-0000-0000-c000-000000000000. This is the unique value that will identify the client to the authorization server.
- The resource parameter is set to https://management.core.windows.net/ . This is used by Microsoft Azure to determine what Azure API the access token will be used for.
- The scope parameter is set to user_impersonation openid which indicates the client wishes to impersonate the user and be returned an Open ID Connect id token.
- The nounce parameter is set to 2b4c9074-0e45-4511-aaf6-8d140db3b0a4. It is a unique value used to help prevent replay attacks.
- The site_id is set to 500879 is an identifier which will be used in later authentication and authorization calls.
- The response_mode is set to form_post which instructs the browser to post back the response in form encoded format.
We are then redirected to the home realm discovery URI at https://login.microsoft.com with some queries attached to the URI. Let’s break down the query strings:
- The user parameter is set to dumactmstest@gmail.com which is the username of the account we are attempting to authenticate with.
- The api-version is set to 2.1. I can’t find any documentation on this, so my assumption is this is the API version that is performing the home realm discovery.
· The stsRequest is set to rQIIAYWQsUvDQBjFvaZW6lIpOAgOHeIiXHJJrknTTZx08U8o18tXGyR3IblSKPgfOHWSDg5udhQH6eAf0EE6WBBHJ0FwcNLNxFJBHHzD-x7vW368Xc0yrKZOvmU5OD8L48u01GGpTkjD85Pq-kZ_7e3Gnj7uX32e7szPzqsjtDJGta5Scdo0zYgJdgxGPxSB7Kds0EvA4DIybxGaIfSC0Lig223KfeJRTIDWMa1bFmas4-JGYFEStJ02YfSpUDna66munZtMwgE8_2neC-WOTKJWLFM11CqS5V8jdy4DGGqbMgYRBlwKAVwZYaDkCYixpv-GjUCojDH5oTYEKPNaK2XckRQTTfd8hzK_3sEALseUuwQz8AC71CYBdT0nq6baVi-FpBVGMSSpFEyFUtQWBLMi-iiiy9VsvftXDzsXk4M742EOs9H2pPzvdF81. - The checkForMicrosoftAccount is set to True. I was unable to find any documentation this parameter. My guess on this parameter is it instructs the API to first check for the existence of this account at Microsoft Live prior to checking Azure Active Directory. The reason I assume this is I ran into an odd issue a few months back where I had the same username for both my Microsoft Live Account and Azure Active Directory identity and Microsoft was only keying in on my Microsoft Live Account.
We are returned the results of the home realm discover in JSON format. Here is a breakdown:
- The AuthURL attribute has a value of https://login.live.com/login.srf?username=dumactmstest%40gmail.com&wa=wsignin1.0&wtrealm=urn%3afederation%3aMicrosoftOnline&wctx=estsredirect%3d2%26estsrequest%3drQIIAYWQsUvDQBjFvaZW6lIpOAgOHeIiXHJJrknTTZx08U8o18tXGyR3IblSKPgfOHWSDg5udhQH6eAf0EE6WBBHJ0FwcNLNxFJBHHzD-x7vW368Xc0yrKZOvmU5OD8L48u01GGpTkjD85Pq-kZ_7e3Gnj7uX32e7szPzqsjtDJGta5Scdo0zYgJdgxGPxSB7Kds0EvA4DIybxGaIfSC0Lig223KfeJRTIDWMa1bFmas4-JGYFEStJ02YfSpUDna66munZtMwgE8_2neC-WOTKJWLFM11CqS5V8jdy4DGGqbMgYRBlwKAVwZYaDkCYixpv-GjUCojDH5oTYEKPNaK2XckRQTTfd8hzK_3sEALseUuwQz8AC71CYBdT0nq6baVi-FpBVGMSSpFEyFUtQWBLMi-iiiy9VsvftXDzsXk4M742EOs9H2pPzvdF81 which instructs the browser on where the user should authenticate to.
- The cloudinstancename attribute has a value of login.microsoftonline.com. I couldn’t find any information on this one, so I’ll be curious to see if it differs at all with an Azure Active Directory identity.
- The ConsumerDomain attribute has a value of True. I believe it is identifying the DNS namespace of the Microsoft Live identity as a consumer domain, i.e. gmail.com, comcast.net, etc. I know there are limitations as to what can be done with an account with a consumer domain, so that might be the purpose of this attribute.
- The DomainName attribute has a value of live.com which tells us the domain name for Microsoft Live accounts.
- The federation_protocol attribute has a value of WSTrust which indicates the IdP will be using the WS-Trust framework to generate a security token.
- The FederationBrandName attribute has a value of MSA Realms. This is a custom string that is configurable when a domain is federated in Azure Active Directory.
- The Login attribute has a value of dumactmstest@gmail.com and is the username of the account that needs to authenticate.
- The MicrosoftAccount has a value of 0. I’m not sure what this is used for, but I will be curious to see its value when we test with an Azure Active Directory identity.
- The NameSpaceType has a value of federated which indicates the namespace is federated and not standard. A standard namespace would mean the identities and their credentials exist in Azure Active Directory.
Our browser’s next stop is to the URI that was received in the AuthURI attribute of the JSON response. Here we submit a WS-Federation request for a security token for dumactmstest@gmail.com. Let’s breakdown the request:
- The wa parameter is set to wsignin1.0 which is required for WS-Federation security token requests.
- The wtrealm is set to urn:federation:MicrosoftOnline which is the relying party identifier for the entity requesting the user authentication.
- The wctx parameter is set to estsredirect=2&estsrequest=rQIIAYWQsUvDQBjFvaZW6lIpOAgOHeIiXHJJrknTTZx08U8o18tXGyR3IblSKPgfOHWSDg5udhQH6eAf0EE6WBBHJ0FwcNLNxFJBHHzD-x7vW368Xc0yrKZOvmU5OD8L48u01GGpTkjD85Pq-kZ_7e3Gnj7uX32e7szPzqsjtDJGta5Scdo0zYgJdgxGPxSB7Kds0EvA4DIybxGaIfSC0Lig223KfeJRTIDWMa1bFmas4-JGYFEStJ02YfSpUDna66munZtMwgE8_2neC-WOTKJWLFM11CqS5V8jdy4DGGqbMgYRBlwKAVwZYaDkCYixpv-GjUCojDH5oTYEKPNaK2XckRQTTfd8hzK_3sEALseUuwQz8AC71CYBdT0nq6baVi-FpBVGMSSpFEyFUtQWBLMi-iiiy9VsvftXDzsXk4M742EOs9H2pPzvdF81. This is an optional parameter and I’m unsure what Microsoft is using the value for.
- The id parameter is set to 500879 which is also the siteID from the original OAuth 2.0 authorization request.
- The cbcxt parameter is set to azuManage. I’m unsure as to what Microsoft is using this value for.
- The pcexp parameter is not set. This parameter controls whether the user receives a mobile experience. The value is by default True. If it was false we would receive the mobile experience.
- The username is set to dumactmstest@gmail.com.
- The popupui parameter is not set. From what I’ve read online, this value would be set for 1 if using a this was not a browser session.
The browser is directed to another URI at https://login.live.com where the browser posts the WS-Federation request and the user authenticates using forms-based authentication by providing a username and password. After authentication the user’s browser is directed back to a URI at https://login.microsoftonline.com where the user posts result of the WS-Federation authentication request. Let’s break down the interesting portions of the SAML assertion contained in the WS-Federation authentication response.
- The claim below shows the user authenticated with a password.
- <saml:AuthenticationStatement AuthenticationInstant=”2016-04-01T23:53:00Z” AuthenticationMethod=”urn:oasis:names:tc:SAML:1.0:am:password”>
- Ever wonder what your Microsoft account UPN looks like behind the scenes? Well here you go.
- <saml:Subject><saml:NameIdentifier Format=”http://schemas.xmlsoap.org/claims/UPN”>00037FFEE3497D1E@Live.com
</saml:NameIdentifier></saml:Subject>
- <saml:Subject><saml:NameIdentifier Format=”http://schemas.xmlsoap.org/claims/UPN”>00037FFEE3497D1E@Live.com
- This claim indicates that the accounts credentials do not exist within Azure Active Directory.
- <saml:Attribute AttributeName=”Managed” AttributeNamespace=”http://schemas.xmlsoap.org/claims”>
<saml:AttributeValue>FALSE</saml:AttributeValue></saml:Attribute>
- <saml:Attribute AttributeName=”Managed” AttributeNamespace=”http://schemas.xmlsoap.org/claims”>
- I’m assuming this is some unique identifier of the Microsoft Live account.
- <saml:Attribute AttributeName=”CID” AttributeNamespace=”http://schemas.xmlsoap.org/claims”>
<saml:AttributeValue>7f5c85a988a96054</saml:AttributeValue></saml:Attribute>
- <saml:Attribute AttributeName=”CID” AttributeNamespace=”http://schemas.xmlsoap.org/claims”>
- Here is the email address associated with the account. We see here that MS assigns each Microsoft Live account a unique user principal name but allows the user to use the email address as a the identifier to improve the user experience.
- <saml:Attribute AttributeName=”EmailAddress” AttributeNamespace=”http://schemas.xmlsoap.org/claims”>
<saml:AttributeValue>dumactmstest@gmail.com</saml:AttributeValue>
</saml:Attribute>
- <saml:Attribute AttributeName=”EmailAddress” AttributeNamespace=”http://schemas.xmlsoap.org/claims”>
The browser then posts the authorization code and id token to a hidden form which is submitted to https://manage.windowsazure.com/. Let’s take a closer look to the id token after translating it through an online JWT decoder.
{
typ: “JWT”,
alg: “RS256”,
x5t: “MnC_VZcATfM5pOYiJHMba9goEKY”,
kid: “MnC_VZcATfM5pOYiJHMba9goEKY”
}.
{
aud: “00000013-0000-0000-c000-000000000000”,
iss: “https://sts.windows.net/f8cdef31-a31e-4b4a-93e4-5f571e91255a/”,
iat: 1459554480,
nbf: 1459554480,
exp: 1459558380,
altsecid: “1:live.com:00037FFEE3497D1E”,
amr: [ “pwd” ],
c_hash: “264Qre8J0_XsX8h1K0Njfw”,
email: “dumactmstest@gmail.com”,
idp: “live.com”,
ipaddr: ,
nonce: “cea3bad2-791b-4d89-a5aa-a007f61d7fe6”,
sub: “VGbEv7U0OCZLbm-vUyo8caG2uHldcRilsIrit_c7xQU”,
tid: “f8cdef31-a31e-4b4a-93e4-5f571e91255a”,
unique_name: “live.com#dumactmstest@gmail.com”,
ver: “1.0”
}.
[signature]
Here are the interesting claims:
- The audience (aud) claim has a value of 00000013-0000-0000-c000-000000000000. This is the clientID of the application.
- The issuer (iss) claim has a value of https://sts.windows.net/f8cdef31-a31e-4b4a-93e4-5f571e91255a/ which is the STS that created the token.
- The altsecid claim has a value of 1:live.com:00037FFEE3497D1E. If you look closely, you’ll notice this resembles the UPN from our SAML assertion.
- The authentication methods reference (arm) claim has a value of pwd which indicates the user authenticated with a password.
- The email claim has the value of dumactmstest@gmail.com which matches the email address supplied claim from our SAML assertion.
- The identity provider (idp) claim has a value of live.com. Recall that we used a Microsoft Live identity for this scenario.
- The unique_name claim shows live.com#dumactmstest@gmail.com. It will be interesting to see how this differs from an Azure Active Directory account.
We are then directed to another URI at https://manage.windowsazure.com. I’m assuming the value after the forward slash is the tenantID. After this we are redirected back to https://login.microsoftonline.com with an authorization request for an authorization code and id token. The only difference between the first authorization request and this request is the redirect_uri is set to https://manage.windowsazure.com/80b0dae2-f20b-4799-8f5b-3edea102c1b9?tenantWalk=. Since we have already authenticated we are issued the authorization code and id token and are redirected to the redirect_uri where the browser posts the authorization code and token. The redirect URI then redirects the browser to an error page at https://manage.windowsazure.com which notes the account is not associated with a Microsoft Azure subscription.
Let’s sum up what we learned:
- Microsoft Azure issues an authorization request for an authorization code and id token when a user first attempts to access an Azure service.
- Microsoft has improved the user experience via updates to Microsoft Azure which now do not require the user to choose whether the account is an Azure account or a Microsoft account. This is determined during the home realm discovery process and the user is directed the appropriate authentication endpoint.
- WS-Trust is used to obtain a security token from the Microsoft Live security token service after the user authenticates with forms-based authentication. The security token is then delivered to an endpoint at Microsoft Online
Next up will be following this same flow with an Azure Active Directory identity.