Contact

Subscribe via Email

Subscribe via RSS/JSON

Categories

Creative Commons Attribution 4.0 International License
© Rakhesh Sasidharan

Elsewhere

TIL: Teams User-Agent String

Today I learnt that Teams too has a User-Agent String, and it defaults to that of the default browser of the OS. In my case, macOS with Firefox as the default, it was using the User-Agent String of Firefox. I encountered this today morning when Teams refused to sign on to our environment via ADFS because it wasn’t doing forms based as it usually did Windows Integrated Authentication, and that was failing because I am not on a domain joined machine. 

All of this happened due to a chain of events. At work enabled WIA SSO on ADFS for Safari and Firefox. At home my VPN client re-connected today morning, causing DNS resolutions to happen via the VPN DNS server than my home router, resulting in ADFS sign on for Teams going via the internal route to the ADFS server at work and since this was set to accept WIA now for Firefox it was defaulting to that instead of forms based authentication. The fix for this was to sort out my DNS troubles … so did that, and here we are! :) Good to know!

ADFS WIA Support UserAgent strings for Chrome etc.

This is more as a note to myself. Out of the box ADFS does not have WIA enabled for most browsers. You need to add the UserAgent strings of browsers you wish to enable WIA for. Here is the cmdlet with the list of agents I currently use:

This is based on this & this Microsoft Docs plus some other blog posts I read over the years. I will keep updating this blog post with any updates. 

It might be better to replace “Chrome” above with “Windows\s*NT.*Chrome”. I found this in the comments of this article. Useful so it only targets Chrome on Windows and not iOS/ Android. 

Here’s the User Agent Strings from Safari on my iPhone, Mac Book, and Vivaldi on Windows. 

  • Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1
  • Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.2 Safari/605.1.15
  • Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36 Vivaldi/2.1.1337.36

Matching on “Windows\s*NT.*Chrome” (which I think is regex and so should translate to the string Windows followed by zero or more spaces, followed by NT, followed by zero or more characters, followed by Chrome) will thus only pick the last User Agent String. 

Some more things to be done for WIA to work. You must add your ADFS site to the Local Intranet zone of IE. Best to use Group Policy Preferences for this, pushing out a registry key. Under the HKCU hive you can push out a key “Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\Domains\adfs.fqdn\” (or replace adfs with a * if you want *.fqdn to be matched), with a value of https and data of DWORD 00000001 in hex. Chrome, and Chromium based browsers (such as Vivaldi, Edge, etc.) will use this list so WIA will work for them automatically. 

This link from the Chromium page also mentions the SPN issue I encountered previously. The SPN generated will use the CNAME name if that exists, so better to use an A record with an IP address. 

When a server or proxy presents Chrome with a Negotiate  challenge, Chrome tries to generate a Kerberos SPN (Service Principal Name) based on the host and port of the original URI. Unfortunately, the server does not indicate what the SPN should be as part of the authentication challenge, so Chrome (and other browsers) have to guess what it should be based on standard conventions. 

The default SPN is: HTTP/<host name>, where <host name> is the canonical DNS name of the server. This mirrors the SPN generation logic of IE and Firefox.

ADFS and CNAME records – HTTP/400 error with WIA

I had heard that it is better to create an A record for ADFS (i.e. you get an IP address as the reply when querying the record) rather than a CNAME record (i.e. you get a name and the IP address of that alternate name) but didn’t know why until today. Now I know at least one reason why it is better to have an IP address. 

To begin with I must point to this blog post. The author had the same error as me, but of course he wasn’t using a CNAME, so his actual problem and fix was different. But the blog post is worth a read to know the situation. I had two domains – Domain A and Domain B – each with ADFS servers. I was trying to access the ADFS server in Domain B from a machine in Domain A, and getting prompted for credentials (expected) but once I enter the correct details it would give me an HTTP/400 error. Disabling WIA and enabling Forms Based Authentication worked, so the problem was to do with WIA. These are different domains, with trusts in place, and I was entering the correct details … so what gives? 

Looking at the System logs on my machine in Domain A (not where the ADFS server is in) I had entries like this:

The Kerberos client received a KRB_AP_ERR_MODIFIED error from the server msvc_adfs2$. The target name used was HTTP/rak2addc01.two.raxnet.global. This indicates that the target server failed to decrypt the ticket provided by the client. This can occur when the target server principal name (SPN) is registered on an account other than the account the target service is using. Ensure that the target SPN is only registered on the account used by the server. This error can also happen if the target service account password is different than what is configured on the Kerberos Key Distribution Center for that target service. Ensure that the service on the server and the KDC are both configured to use the same password. If the server name is not fully qualified, and the target domain (TWO.RAXNET.GLOBAL) is different from the client domain (TWO.RAXNET.GLOBAL), check if there are identically named server accounts in these two domains, or use the fully-qualified name to identify the server.

The highlighted entry is the clue. I was accessing the ADFS server as adfs.two.raxnet.global, and it was a CNAME to rak2addc01.two.raxnet.global, so looks like during WIA it was using the CNAME instead of the actual name and hence using the SPN HTTP/rak2addc01.two.raxnet.global rather than HTTP/adfs.two.raxnet.global. It also seemed to be using the (correct) HTTP/adfs.two.raxnet.global SPN and identifying the associated service account msvc_adfs2 but since that service account couldn’t decrypt the Kerberos tickets, I was getting an error.

ADFS 2016 prompts for credentials via a popup (and doesn’t work)

Setup ADFS in my home lab. There’s a single server called rak1adfs01.raxnet.global. The ADFS service is called adfs.raxnet.global and in DNS this is a CNAME to the server. 

When I go to https://adfs.raxnet.global/adfs/ls/IdpInitiatedSignon.htm I get a login prompt and even though I enter the correct credentials it doesn’t let me in. This is unlike what I am used to at work where we get a forms based screen and that works. 

To troubleshoot this I went to the authentication options on ADFS and under the Intranet section I unticked Windows Authentication and Microsoft Passport Authentication, leaving only Forms Authentication ticked. 

Screen Shot 2018 12 14 at 5 59 50 PM

Restarted the ADFS service and went back to ADFS page again – voila! it signs in. So the issue is definitely the WIA authentication. 

I noticed that when the prompt comes up it has my server name in it (rak1adfs.raxnet.global) rather than the ADFS service name (adfs.raxnet.global). That didn’t make sense – sounded like my browser was trying to authenticate against the server directly. 

Screen Shot 2018 12 14 at 6 03 18 PM

Could be an SPN issue? According to this article I am supposed to have an SPN of the form host/adfs.raxnet.gloabal and that does exist. 

Looking at the SPNs of rak1adfs01.raxnet.global (my ADFS server) I don’t see anything tying it to my service account. I came across another article, for a single ADFS server, which suggests setting up an SPN for http/<servername>. 

Once I did that WIA started working. (If I delete this SPN and create one for http/adfs.raxnet.global WIA fails again. I guess my issue is that since it’s a single server currently it is being treated as a single server case rather than an ADFS farm). 

I went back and enabled the Forms Authentication and everything works as usual. 

Lessons learnt: 1) WIA takes precedence over Forms Based Authentication; and 2) SPNs must be created against the single server if you have a single server install (even though you might be thinking of it as a farm install because you plan on installing more servers later). 

As an aside, some useful links: 

  • Here’s an example of a simple authentication app you can setup that uses ADFS
  • If you don’t want to install an app but just want to test ADFS authentication you can always go to https://fqdn.domain.com/adfs/ls/IdpInitiatedSignon.aspx. This will only work on ADFS 2016 if you enable it
  • Lastly, one more SAML test app that you can install. 
  • The two SPNs that are required for ADFS.