How SSO works in Windows 10 devices

In a previous post I talked about the three ways to setup Windows 10 devices for work with Azure AD. I later covered in detail how Azure AD Join and auto-registration to Azure AD of Windows 10 domain joined devices work, and in an extra post I explained how Windows Hello for Business (a.k.a. Microsoft Passport for Work) works. In this post I will cover how Single Sign-On (SSO) works once devices are registered with Azure AD for domain joined, Azure AD joined or personal registered devices via Add Work or School Account.

SSO in Windows 10 works for the following types of applications:

  1. Azure AD connected applications, including Office 365, SaaS apps, applications published through the Azure AD application proxy and LOB custom applications integrating with Azure AD.
  2. Windows Integrated authentication apps and services.
  3. AD FS applications when using AD FS in Windows Server 2016.

 

The Primary Refresh Token

SSO relies on special tokens obtained for each of the types of applications above. These are in turn used to obtain access tokens to specific applications. In the traditional Windows Integrated authentication case using Kerberos, this token is a Kerberos TGT (ticket-granting ticket). For Azure AD and AD FS applications we call this a Primary Refresh Token (PRT). This is a JSON Web Token containing claims about both the user and the device.

The PRT is initially obtained during Windows Logon (user sign-in/unlock) in a similar way the Kerberos TGT is obtained. This is true for both Azure AD joined and domain joined devices. In personal devices registered with Azure AD, the PRT is initially obtained upon Add Work or School Account (in a personal device the account to unlock the device is not the work account but a consumer account e.g. hotmail.com, live.com, outlook.com, etc.).

The PRT is needed for SSO. Without it, the user will be prompted for credentials when accessing applications every time. Please also note that the PRT contains information about the device. This means that if you have any device-based conditional access policy set on an application, without the PRT, access will be denied.

 

PRT validity

The PRT has a validity of 90 days with a 14 day sliding window. If the PRT is constantly used for obtaining tokens to access applications it will be valid for the full 90 days. After 90 days it expires and a new PRT needs to be obtained. If the PRT has not been used in a period of 14 days, the PRT expires and a new one needs to be obtained. Conditions that force expiration of the PRT outside of these conditions include events like user’s password change/reset.

For domain joined and Azure AD joined devices, renewal of the PRT is attempted every 4 hours. This means that the first sign-in/unlock, 4 hours after the PRT was obtained, a new PRT is attempted to be obtained.

Now, there is a caveat for domain joined devices. Attempting to get a new PRT only happens if the device has a line of sight to a DC (for a Kerberos full network logon which triggers also the Azure AD logon). This is a behavior we want to change and hope to make for the next update of Windows. This would mean that even if the user goes off the corporate network, the PRT can be updated. The implication of this behavior today, is that a domain joined device needs to come into the corporate network (either physically or via VPN) at least once every 14 days.

 

Domain joined/Azure AD joined devices and SSO

 

The following step-by-step shows how the PRT is obtained and how it is used for SSO. The diagram shows the flow in parallel to the long standing Windows Integrated authentication flow for reference and comparison.

sso-in-windows-10

 

(1) User enter credentials in the Window Logon UI

In the Windows Logon UI the user enters credentials to sign-in/unlock the device. The credentials are obtained by a Credential Provider. If using username and password the Credential Provider for username and password is used, if using Windows Hello for Business (PIN or bio-gesture), the Credential Provider for PIN, fingerprint or face recognition is used.

credprov

 

(2) Credentials are passed to the Cloud AP Azure AD plug-in for authentication

The Credential Provider gets the credentials to WinLogon which will call LsaLogonUser() API with the user credentials (to learn about the authentication architecture in Windows see Credentials Processes in Windows Authentication). The credentials get to a new component in Windows 10 called the Cloud Authentication Provider (Cloud AP). This is a plug-in based component running inside the LSASS (Local Security Authority Subsystem) process with one plug-in being the Azure AD Cloud AP plug-in. For simplicity in the diagram these two are shown as one Cloud AP box.

The plug-in will authenticate the user against Azure AD and AD FS (if Windows Server 2016) to obtain the PRT. The plug-in will know about the Azure AD tenant and the presence of the AD FS by the information cached during device registration time. I explain this at the end of step #2 in the post Azure AD Join: what happens behind the scenes? when the information from the ID Token is obtained and cached just before performing registration (the explanation applies to both to domain joined devices registered with Azure AD and Azure AD joined devices).

 

(3) Authentication of user and device to get PRT from Azure AD (and AD FS if federated and version of Windows Server 2016)

Depending on what credentials are used the plug-in will obtain the PRT via distinct calls to Azure AD and AD FS.

PRT based in username and password

To obtain the Azure AD PRT using username and password, the plug-in will send the credentials directly to Azure AD (in a non-federated configuration) or to AD FS (if federated). In the federated case, the plug-in will send the credentials to the following WS-trust end-point in AD FS to obtain a SAML token that is then sent to Azure AD.

adfs/services/trust/13/windowstransport

Azure AD will authenticate the user with the credentials obtained (non-federated) or with verifying the SAML token obtained from AD FS (federated). After authentication Azure AD will build a PRT with both user and device claims and will return it to Windows.

PRT based in the Windows Hello for Business credential

To obtain the Azure AD PRT using the Windows Hello for Business credential, the plug-in will send a message to Azure AD to which it will respond with a nonce. The plug-in will respond with the nonce signed with the Windows Hello for Business credential key.

Azure AD will authenticate the user by checking the signature based on the public key that it registered at credential provisioning as explained in the post Azure AD and Microsoft Passport for Work in Windows 10 (please note that Windows Hello for Business is the new name for Microsoft Passport for Work). The PRT will contain information about the user and the device as well, however a difference with the PRT obtained using username and password is that this one will contain a “strong authentication” claim.

"acr":"2"

 

Regardless of how the PRT was obtained, a session key is included in the response which is encrypted to the Kstk (one of the keys provisioned during device registration as explained in step #4 in the post Azure AD Join: what happens behind the scenes?).

The session key is decrypted by the plug-in and imported to the TPM using the Kstk. Upon re-authentication the PRT is sent over to Azure AD signed using a derived version of the previously imported session key stored in the TPM which Azure AD can verify. This way we are bounding the PRT to the physical device reducing the risk of PRT theft.

 

(4) Cache of the PRT for the Web Account Manager to access it during app authentication

Once the PRT is obtained it is cached in the Local Security Authority (LSA). It is accessible by the Web Account Manager which is also a plug-in based component that provides an API for applications to get tokens from a given Identity Provider (IdP). It can access the PRT through the Cloud AP (who has access to the PRT) which checks for a particular application identifier for the Web Account Manager. There is a plug-in for the Web Account Manager that implements the logic to obtain tokens from Azure AD and AD FS (if AD FS in Windows Server 2016).

You can see whether a PRT was obtained after sign-in/unlock by checking the output of the following command.

dsregcmd.exe /status

Under the ‘User State’ section check the value for AzureAdPrt which must be YES.

prtindsregcmd

A value of NO will indicate that no PRT was obtained. The user won’t have SSO and will be blocked from accessing service applications that are protected using device-based conditional access policy.

 

A note on troubleshooting

To troubleshoot why the PRT is not obtained can be a topic for a full post, however one test you can do is to check whether that same user can authenticate to Office 365, say via browser to SharePoint Online, from a domain joined computer without being prompted for credentials. If the UPN suffix of users in Active Directory on-premises don’t route to the verified domain (alternate login ID) please make sure you have the appropriate issuance transform rule(s) in AD FS for the ImmutableID claim.

One other reason that I have seen PRT not being obtained, is when the device has a bad transport key (Kstk). I have seen this in devices that have been registered in a very early version of Windows (which upgraded to 1607 eventually). As the PRT is protected using a key in the TPM this could be a reason why the PRT is not obtained at all. One remediation for this case is to reset the TPM and let the device register again.

 

(5, 6 and 7) Application requests access token to Web Account Manager for a given application service

When a client application connects to a service application that relies in Azure AD for authentication (for example the Outlook app connecting to Office 365 Exchange Online) the application will request a token to the Web Account Manager using its API.

The Web Account Manager calls the Azure AD plug-in which in turn uses the PRT to obtain an access token for the service application in question (5).

There are two interfaces in particular that are important to note. One that permits an application get a token silently, which will use the PRT to obtain an access token silently if it can. If it can’t, it will return a code to the caller application telling it that UI interaction is required. This could happen for multiple reasons including the PRT has expired or when MFA authentication for the user is required, etc. Once the caller application receives this code, it will be able to call a separate API that will display a web control for the user to interact.

WinRT API

WebAuthenticationCoreManager.GetTokenSilentlyAsync(...) // Silent API
WebAuthenticationCoreManager.RequestTokenAsync(...) // User interaction API

Win32 API

IWebAuthenticationCoreManagerStatics::GetTokenSilentlyAsync(...) // Silent API
IWebAuthenticationCoreManagerInterop::RequestTokenForWindowAsync(...) // UI API

 

After returning the access token to the application (6), the client application will use the access token to get access to the service application (7).

 

Browser SSO

When the user accesses a service application via Microsoft Edge or Internet Explorer the application will redirect the browser to the Azure AD authentication URL. At this point, the request is intercepted via URLMON and the PRT gets included in the request. After authentications succeeds, Azure AD sends back a cookie that will contain SSO information for future requests. Please note that support for Google Chrome will come sometime in the future.

 

Final thoughts

Remember that registering your domain joined computers with Azure AD will give you instant benefits and it is likely you have everything you need to do it. Also, if you are thinking in deploying Azure AD joined devices you will start enjoying some additional benefits that come with it.

Please let me know you thoughts and stay tuned for other posts related to device-based conditional access and other related topics.

See you soon,

Jairo Cadena (Twitter: @JairoC_AzureAD)

This entry was posted in Uncategorized. Bookmark the permalink.

9 Responses to How SSO works in Windows 10 devices

  1. Aaron Marks says:

    Great post as always Jairo. Thank you! Do you have an eta on Chrome support?

    Like

  2. Sven Franz says:

    What Azure AD license is required for auto-registration to Azure AD of Windows 10 domain joined devices to work? We have O365 AzureAD is that enough or is Premium required?

    Like

  3. Mikael Cavrak says:

    Hi Jairo,
    Thanks for the very detailed article.
    One thing I can’t understand is the PRT validity time. Maybe I’m a little bit slow here… 
    Is my understanding right…
    On personal registered devices via Add Work or School Account,
    1. The initial PRT is obtained during Add Work or School Account process.
    2. It’s valid for full 90 days only if I access an AzureAD protected resource during the first 14 days. One AzureAD protected resource will be enough.
    3. New PRT will only be obtained if the initial expired which mean after 90 days or 14 days.
    On devices that are registered Azure AD for domain joined or Azure AD joined.
    1. The initial PRT is obtained during first Sign-on/Unlock if the previous one has not expired.
    2. It’s valid for full 90 days, but the end-user doesn’t need to access an AzureAD protected resource during the first 14 days to have full life time of 90 day. The reason being is that it’s all handle silently and automatically by Windows every 4 hours.
    Question. Regarding #3 in the personal registered devices via Add Work or School Account. What will the end-user experience be if I’m signed in to my desktop and try to access AzureAD protected resource with a PRT that just got expired?
    Question. From an Admin Point view what do I have to do to revoke the Credentials. Will it suffice to disable the User Account In Azure AD? Is there something more that has to be done on the device side?

    Like

  4. Andrew Colombino says:

    Hi Jairo,
    Thanks for such detailed articles on this topic. I’m having issues getting my domain-joined Windows 10 PCs to join Azure AD. Your articles (and comments) have helped get me past some initial bumps, but I seem to have hit a roadblock.

    In my environment, I’m using Azure AD Connect to sync our local AD users to Azure AD, and we use ADFS for authentication. I followed Microsoft’s documentation to add the additional required claims rules to the relying party trust, enable the ‘adfs/services/trust/13/windowstransport’ endpoint, configured group policy to register the PCs as devices, etc.

    But in the User Device Registration logs on my PC I’m seeing a few token-related errors:
    * Error 305: Automatic registration failed at authentication phase. Unable to acquire access token.
    * Error 304: Automatic registration failed at join phase.
    * Warning 308: This Device is joined to Azure AD, however, the user did not sign-in with an Azure AD account. Microsoft Passport provisioning will not be enabled.

    The user account I’m logging into my PC with is a local AD user account that is synced to Azure AD with Azure AD Connect.

    In contradiction to the Warning 308 that gets logged, when I run ‘dsregcmd /status’, it’s showing the device as “AzureAdJoined: NO”, my user as “IsUserAzureAD: NO”

    Not sure what I’m doing wrong. I’d appreciate any light you can shed on this.

    Thanks

    Like

  5. Pingback: (2016-12-16) Automatic Azure AD Join With ADFS v3.0 And Higher And Conditional Access – What You Really Need In Detail « Jorge's Quest For Knowledge!

  6. Pingback: (2016-12-28) Joining Devices To Azure AD – The Options And The Differences « Jorge's Quest For Knowledge!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s