Notes of Azure AD authentication, SSO, etc.

I am familiar with Azure AD authentication etc. but not so clued in when it comes to authentication for Azure AD Hybrid joined machines and such. Was reading up on that and thought I’d make some notes here.

Azure AD authentication

You set up Azure AD connect to synchronize on-prem users to Azure AD. This doesn’t have to synchronize the password related info, so you can use Azure AD purely as a user database with the actual authentication happening elsewhere (or on Azure AD itself). We have four options for these (well, three options practically speaking), divided into two categories depending on how you want things to be:

  • You want the authentication to happen on-premises:
    • Option 1: Setup Pass-through Authentication (this involves installing one or more Agents on-premises; when a user visits Azure AD to be authenticated, the username and password are encrypted and stored in a queue, these Agents keep polling the queue and decrypt the username and password and authenticate against local AD and return the result to Azure AD)(you can read about it here or watch a helpful video here)
    • Option 2: Setup ADFS on-premises and federation from Azure AD to ADFS such that when a user visits Azure AD to be authenticated they are then sent to the on-prem ADFS server for actual authentication and the results of these are sent to Azure AD. Azure AD’s role here is more as a go-between ADFS and the application the user wants to access. Whereas ADFS uses SAML you can have Azure AD talk OAuth or similar to the application as it will take the SAML claims it gets and send over what the application needs. This is obviously more involved than Pass-through authentication but is the only option if you need to use smartcards or certificates or other methods that Azure AD does not support. (Check out this page for a decision tree; this page for a comparison table).
  • You want the authentication to happen in Azure AD:
    • Option 1: Synchronize user passwords to Azure AD (well actually, synchronize a hash of the on-prem password hash (hence the name Password Hash Sync) so Azure AD can use that to authenticate the user) (you can read about it in this official doc)
    • Option 2: Not sure why you’d want to do this, but you can just have separate passwords in Azure AD. Ignore this!

When using ADFS or Pass-through authentication, it is possible to sync the password hashes via Password Hash Sync either as something you can flip to in case of a DR scenario (ADFS is down perhaps) or you want to take advantage of Microsoft’s services like notifications of leaked passwords. Once you enable Password Hash Sync it takes about 3 hours for the passwords to be added to Azure AD, hence why it’s better to have them syncing beforehand if you envision using that in a pinch.

Another way of looking at the above is whether you want Cloud authentication (Azure AD does the authentication either via Password Hash Sync or Pass-through Authentication) or Federated authentication (ADFS does the authentication).

Seamless SSO

Now add to the above mix SSO (Single Sign On). The idea being that since a user on a domain joined machine is already authenticated to their domain via a DC, in the case of Password Hash Sync (PHS) or Pass-through Authentication (PTA) or ADFS it would be good if their sign-in were made easier and seamless because they already have a kerberos ticket from the DC. And we can do this for PHS or PTA, but not for ADFS.

What happens in this scenario is that when the user visits Azure AD to be authenticated, rather than ask for a password and do its magic via PHS or PTA, Azure AD can ask for a kerberos ticket from the DC and use that to authenticate the user. Of course it can’t simply get the kerberos ticket so some behind the scenes needs to be done by the Azure AD connect wizard as part of enabling this (create a computer account called AZUREADSSOACC and setup some SPNs) and by the IT admins (add a URL to the local Intranet zone plus some additional steps for browsers such as Firefox or caveats for older Windows OSes)(you can read all the steps here). Once all this is done though when a user visits Azure AD to be authenticated the user will automatically sign in without having to enter credentials (more details of the flow here; also what happens when you are using a browser; what happens when you are using a native application).

Azure AD join etc.

While everything I talked about above was in the context of user accounts, Azure AD can also deal with computer accounts. A user device (computer or phone etc. – hence “device”) can be in one of the following states when it comes to Azure AD:

  • Azure AD registered
    • These are user owned or company owned devices that are registered in Azure AD as the user has signed in with their Azure AD account to some application on these devices (for example: Teams)
    • These devices can be Windows 10, iOS, Android, or macOS.
      • You can stop Windows devices from being Azure AD registered via a registry key: HKLM\SOFTWARE\Policies\Microsoft\Windows\WorkplaceJoin: "BlockAADWorkplaceJoin"=dword:00000001. You’d probably want to do this to keep your Azure AD devices view clean or if you know you’ll move to Azure AD Hybrid later and don’t want devices appearing twice (though once a user signs in on the same machine again after it is Azure AD Hybrid joined then the Azure AD registered entry is automatically removed).
    • The devices themselves may or may not be managed by the company. They can be unmanaged (or managed by something that’s not Intune), or managed by Intune, or only the company applications are managed using Mobile Application Management features of Intune.
      • If managed via Intune one can apply Conditional Access policies to these devices using the “Compliant” flag. If using MAM then Conditional Access can apply via App Protection Policies (which is where you “containerize” the app so you control what interactions it can have with the user’s device or other apps); you use Conditional Access to restrict access to such apps basically.
    • Typically the device gets registered when the user signs in to an app (example: Teams, Outlook) using their Azure AD account and ticks the “Use this account everywhere on your device” checkbox (screenshot). But they can also register their Windows 10 machine with Azure AD via Settings or via the Authenticator app in iOS (some screenshots here). For Android I am not sure if the Authenticator app can do the job, if not they have to download the Intune Company portal app and register from there.
    • Is this same as Workplace Join? Seems to be. That’s the name for pre-Windows 10 devices to Azure AD register I think.
  • Azure AD joined
    • This is where Microsoft wants you to be. These devices only exist in Azure AD. They are not domain joined. Bye-bye Kerberos!
    • Only Windows 10 or Server 2019 running in Azure (not even Server Core) can be Azure AD joined.
    • These are typically company managed/ owned devices. You Azure AD join a Windows 10 machine during OOBE setup, or during building via Autopilot, or bulk enrollment, or Windows Settings.
  • Hybrid Azure AD joined
    • This is where realistically you want to be. These are domain joined machines with a leg in Azure AD – hence “hybrid”.
    • Only Windows devices (7 & above; 2008/R2 and above) can be Hybrid Azure AD joined. Typically you sync these machines via Azure AD connect and once the machines sync to Azure AD they also Hybrid Azure AD join.
      • Behind the scenes this happens because as part of setting this up in Azure AD connect it creates a Service Connection Point (SCP) in AD so machines can Hybrid Azure AD join. During the setup process you are given a script to run manually with your Enterprise Admin account, or you can provide these creds and the tool will run this for you. You can view this in the Configuration Context under CN=Configuration,DC=<domain>,DC=<tld> > CN=Services > CN=Device Registration Configuration. Right click the entry there and you can view azureADId (tenant ID) and azureADName (tenant name).
        • Alternatively, don’t run the script or let the tool do this for you; or if it’s already done this then delete the SCP entry. You can then use GPO to selectively target OUs.
        • This requires various URLs to be reachable from the machines as well some a couple of URLs that must be in the local intranet zone. See this doc for details.
      • If you are using ADFS you have to use that to enable Hybrid Azure AD join. See this doc.
      • You can use Conditional Access to restrict access to Hybrid Azure AD joined machines.
        • You cannot use Conditional Access to restrict access to Azure AD joined devices, but if such devices are managed by something like Intune then they can be marked as “Compliant” and that can be used to restrict access. This is similar to the case for Azure AD registered devices.
        • I am not sure why there’s no option to restrict access to Azure AD joined devices. Am sure there’s some reason I haven’t come across yet.

And now for some new stuff (new to me at least as I had worked with this briefly some months ago but having to revisit it now): Primary Refresh Tokens (PRTs). For devices that are Azure AD joined, Azure AD registered, or Hybrid Azure AD joined Azure AD issues a PRT to the device and this is used for Single Sign On. I still haven’t gotten my head around PRTs, but the thing that confused me was how does this work in conjunction with the SSO I talked about above?

Turns out the Seamless SSO I talked about above is only used on domain joined machines but the moment a machine is Azure AD joined, Azure AD registered, or Hybrid Azure AD joined then PRT takes precedence. This is mentioned in the SSO document and also in the FAQ:

Seamless SSO needs the user’s device to be domain-joined only, but it is not used on Azure AD Joined or Hybrid Azure AD joined devices. SSO on Azure AD joined, Hybrid Azure AD joined, and Azure AD registered devices works based on the primary refresh token.


Q: What is the difference between the single sign-on experience provided by Azure AD Join and Seamless SSO?

Azure AD Join provides SSO to users if their devices are registered with Azure AD. These devices don’t necessarily have to be domain-joined. SSO is provided using primary refresh tokens or PRTs, and not Kerberos. The user experience is most optimal on Windows 10 devices. SSO happens automatically on the Microsoft Edge browser. It also works on Chrome with the use of a browser extension.

You can use both Azure AD Join and Seamless SSO on your tenant. These two features are complementary. If both features are turned on, then SSO from Azure AD Join takes precedence over Seamless SSO.

Some things to note:

  • The SSO I talked about above is called “Seamless SSO”. While the SSO for devices in the three states above is called “SSO from Azure AD Join”. Good to get the terminology right as I was stumbling on it.
  • The features are complementary and SSO from Azure AD takes precedence over Seamless SSO.
    • So I suppose if your devices are not being synced into Azure AD and/ or not Azure AD joined (thus you are neither Azure AD joined nor Hybrid Azure AD joined), and when you sign in to an app such as Teams you ensure the device does not become Azure AD registered then you do not fall under the SSO from Azure AD join case. In this scenario Seamless SSO kicks in.
  • The point about Edge is important and something that bit me some days ago. For Internet Explorer and Edge (am assuming the old Edge too but I am not sure) the browser can pick up the PRT (again, not sure if this works for IE too – the docs mostly mention Edge and IE is only mentioned once in a cookies section) and do SSO. For Chrome an extension is required. And there’s no mention of Firefox. I guess it would use Seamless SSO? Ditto for Chrome without the extension?
    • Good to know: Private modes of these browsers respect the private mode and don’t use PRT for SSO.

Another point to note from the “What does the PRT contain?” section: The PRT contains the device ID and this is used to determine if a device is Hybrid Azure AD joined, compliant, etc. This becomes important if you have Conditional Access policies that restrict access to such devices. In such cases if you were to use (say) on a Hybrid Azure AD device Chrome without the extension (so it can’t access the PRT and thus cannot send the device ID), Conditional Access will block Chrome even though one would expect it to be approved as the device is Hybrid Azure AD joined. The device name is not what matters. What matters is the device ID assigned to it in Azure AD, which is in turn stored on the machine in the PRT. This bit me a few days ago as I turned on such a policy and apps like Teams worked fine (am guessing it works like Edge and has this ability baked in) while Chrome stopped working (as the user didn’t have the extension).

Yet another point to note: Even in the case of Edge the user has to be signed in to Edge with the Azure AD account that is present on the device. Typically this happens during first run experience, but if a user skips to do this they have to sign in to Edge for it to be able to access the PRT. Read more in this doc.

Another fun tidbit: PRTs are what is used even on iOS and Android devices. The “How is a PRT issued?” section gave me the impression PRTs applied to Windows 10 devices only but that’s not the case.

What’s the advantage of SSO by Azure AD join over Seamless SSO? The advantage is that Seamless SSO only works when you are on-premises whereas SSO by Azure AD join works from anywhere. Since you are known to Azure AD and once you are in such a situation chances are you’d want things to work when not connected to the firm via VPN either, SSO by Azure AD join is what we need.

Updates: Some updates since the original post based on further reading follow…

Primary Refresh Tokens (PRTs)

Turns out PRTs aren’t a new thing. They have been around since ADFS 2016/ Windows 10 1511, I just wasn’t aware. ADFS can do device authentication (I was aware of that) but I always thought that required certificates. Turns out that’s only up to ADFS 2012 R2 coz from 2016 it can use PRTs as well as something called PKeyAuth. In fact, PRT is the default from ADFS 2016 but you can use it along with certs of PKeyAuth. In ADFS lingo PRT is also called SignedToken.

PRTs are mentioned in the ADFS 2016 FAQ too, but I must have glossed over. A point to note from that FAQ is that ADFS must have BrowserSSOEnabled set to True for PRTs to work (it’s obvious once you think about it, but just pointing out in case someone has this disabled; it is enabled by default). As an aside I came across this interesting post when searching on ADFS and PRTs. It talks about WIA (Windows Integrated Authentication) (Seamless SSO in case of ADFS, basically). I like what the author is attempting to do.

In ADFS too device authentication serves a similar purpose as with Azure AD. Typically ADFS SSO works on-premises (using Windows Integrated Auth basically against your on-premises ADFS server, while if you are external and hit the WAP server you get Forms Based Authentication which is not SSO) but if you wanted to have SSO off-premises too then device authentication was the way to go. Similarly if you wanted to apply some Access Control Policies (the equivailent of Conditional Access policies in Azure AD) that was the way to go. And while all this was certs based in ADFS 2012R2 it started using PRTs with ADFS 2016. I found this blog post which talks a bit more about this and is worth a read.

Something I forgot to mention earlier, but which I remembered from the previously linked blog post is the dsregcmd /status command which you can use to see the Azure AD join state as well as the PRT status (check out the screenshot in that blog post).

Just as a refresher, when are PRTs issued? They are issued when:

  • During Windows logon for Azure AD joined and Hybrid Azure AD joined devices.
    • Note: This only happens if the account being logged in with is in Azure AD (i.e. it has synced over to Azure AD or is an Azure AD only account). So if you are in a scenario wherein devices are being synced over but user accounts are not synced over yet, the device could be Hybrid Azure AD joined but not have any PRT.
    • Note2: I must emphasise the above point because the initial impression I had was that PRTs are issued to devices. That is not correct, I think. PRTs are issued the logged on user on that device – thus both user and device must be known to Azure AD. This is implied in the link above and also in this troubleshooting link.
    • If a PRT is issued then dsregcmd /status will show AzureAdPrt as YES in the SSO section.
  • If a user adds an account in Azure AD via the Settings app; or if a user signs in with an account in Azure AD to an app and ticks the “Use this account everywhere on this device” checkbox.
    • If a logged in user has Azure AD registrations they can be seen in the User State section of dsregcmd /status. Looks like the SSO section is ignored for Azure AD registered machines, so PRTs don’t matter to them? This makes sense to me because like I noted above PRTs are issued to the user+device so Azure AD must have the device too synced to it (or be Azure AD joined), and since Azure AD registered machines are not synced to Azure AD it would stand to reason they don’t get PRTs. So I think the documentation isĀ  wrong/ misleading when it says PRTs are issued to Azure AD registered devices.

And what do PRTs contain? They contain:

  • A deviceID which contains the ID of the device (this can be seen in Azure AD or as part of dsregcmd /status on the machine)
    • The deviceID changes when the device state changed between Azure AD registered and joined etc. That’s why you’ll see duplicate entries in Azure AD’s Devices view if a device was previously Azure AD registered but is now (say) Hybrid Azure AD joined.
    • Not obvious on first sight, something like sysprep does not reset the deviceID. Thus if you sysprep and clone a Hybrid Azure AD joined machine for instance, the clone will have a different name but the same deviceID.
    • The deviceID is stored in the registry at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\CloudDomainJoin\JoinInfo. Not sure if just deleting that key as part of a sysprep is enough to reset the deviceID for cloned devices?
  • A Session Key (issued by Azure AD).
    • I am not clear enough to explain how this is used but you can read about it in this section of the official docs. Here’s a summary though:
      • The Session Key is a symmetric key. That means there’s only one key and it can do both decryption and encryption (unlike asymmetric, which is a key pair).
      • The first time a device registers with Azure AD a Device Key pair (public & private) and a Transport Key pair (public & private) are created, with the private keys being stored in TPM on the device (or in software if no TPM is present – not good) and the public keys stored in Azure AD.
      • When the device registers with Azure AD the latter sends it a Session Key encrypted with the Public Transport Key so only the client can decrypt this Session Key.
      • This Session Key is stored in TPM (or not, if it’s not available).
      • Subsequently the Session Key can be used as a proof of possession or a shared secret with Azure AD for any requests to Azure AD. Basically any tokens or PRT refresh requests are signed with the Session Key.

Overall TPM seems to be a very important security lynchpin for the above. It’s the PRT along with the Session Key (which is stored encrypted in the PRT but which is used to sign any requests to Azure AD) that make all this possible. (I wonder how things are if a device does not have TPM. Are things less secure?)

I found these two blog posts (this & this) that go into some details on PRTs and Session Keys and how to generate your own PRTs and generally hack the system. I got a headache reading those posts as they are above my knowledge-level. They are worth a read if you can handle it though. :) There is something called BrowserCore.exe installed on Windows 10 devices that can interact with Azure AD and that’s how Edge and Chrome (plus extension) can interact with Azure AD for PRTs etc.

PRTs are valid for 14 days as long as the user actively uses the system. If the PRT is used regularly over the 14 days (and for further 14 days and so on) it can stay valid for up to 90 days. After 90 days, or if the PRT wasn’t used for a continuous 14 days, it needs to be renewed.


This is my understanding from the above. Take it with a pinch of salt. Feel free to let me know if I have misunderstood things!

The machine is not domain joined

If you are an Azure AD joined device:

  • Are you logged in with an Azure AD account? You get a PRT.
  • Are you logged in with a non Azure AD account? You don’t get a PRT.
    • What if you launch something like Teams and login with an Azure AD account and tick the box to use this account everywhere? Or perhaps you add an Azure AD account via Settings? Then you get a PRT.

Seamless SSO does not apply here as these are not domain joined; so SSO from Azure AD join is the only option.

If you are not Azure AD joined:

  • Are you logged in with an Azure AD account? This makes you Azure AD Registered. You get a PRT.
  • Are you logged in with a non Azure AD account? This makes you a non domain-joined non Azure AD joined machine. You don’t get a PRT.
    • As above, what if you launch Teams or similar and checkbox or add an Azure AD account via Settings? This makes you Azure AD Registered. Hooray, you get a PRT.

Seamless SSO does not apply here as these are not domain joined; so SSO from Azure AD join is the only option.

The machine is domain joined

If you are a Hybrid Azure AD joined device:

(I think this is similar to the Azure AD joined scenario but with some caveats for SSO.)

  • Are you logged in with an Azure AD account? You get a PRT.
  • Are you logged in with a non Azure AD account? You don’t get a PRT.
    • What if you launch something like Teams and login with an Azure AD account and tick the box to use this account everywhere? Or perhaps you add an Azure AD account via Settings? You get a PRT.

Seamless SSO could apply here but since it is Hybrid Azure AD joined SSO from Azure AD join takes precedence.

However, does this vary between browsers? Chrome without the extension is not aware of being Azure AD Hybrid joined (as it can’t send the PRT over which is what tells Azure the device ID). So would Chrome naturally resort to Seamless SSO? Similarly Firefox. These browsers would succeed or fail with Seamless SSO depending on their configuration (trusted sites, NTLM config etc.)

Also, what about the use case where the device does not have a PRT? Does Seamless SSO kick in?

Of course any policies that specifically target Hybrid Azure AD join will only work for browsers that are aware of this (i.e. can access the PRT – i.e. the Seamless SSO from Azure AD join scenario and not for regular Seamless SSO)

If you are not Hybrid Azure AD joined device:

  • Are you logged in with an Azure AD account? This makes you Azure AD Registered. You get a PRT.
  • Are you logged in with a non Azure AD account? This makes you a regular domain joined machine with a domain joined user logged in to it. You don’t get a PRT.
    • What if you launch Teams or similar and login with an Azure AD account and tick the box to use this account everywhere? Or perhaps you add an Azure AD account via Settings? This makes you Azure AD Registered. You get a PRT.