Because I gotta write about it somewhere

Kerberos Single Sign-On in iOS

Update: Just a quick note prompted by a comment. These steps should still work in iOS 8 releases, although I have not updated the post to talk about any of the new capabilities related to certificates in SSO. iOS 9 Update: Things still seem to function largely the same in iOS 9 in my (admittedly limited) testing.

In case you missed it, Apple’s recent iOS 7 release added a bunch of new business/enterprise-friendly features. One of the fine gentlemen at MobileIron wrote a nice summary covering several of them. While per-app-VPN and some of the new MDM capabilities look pretty cool, the one I’m most interested in is the “Enterprise SSO” feature.

If you’ve ever tried to use an iOS device in an enterprise environment that takes Windows Authentication for granted, you’ve probably quickly grown frustrated at the shear number of times you see the lovely dialog box in Safari asking you for a username and password. That’s not really the worst of it, because at least Safari is smart enough to prompt you, where some apps just silently fail without ever giving you the option to authenticate. The SSO feature is intended to solve this.

Unsurprisingly, Apple has chosen to use Kerberos as the core of their SSO support iOS, just like they do in it’s older brother – Mac OS. I’m not going to cover how to make your web application support SPNEGO and Kerberos in this post, but it’s really not as hard as many people make it out to be, particularly if you are a Windows/Active Directory shop. Let’s look at how you can take advantage of it assuming you have it working.

The key to “enterprisifying” your iOS devices with things like app restrictions, VPN settings, and PKI certificates revolves around configuration profiles and SSO is no different. Unfortunately, at the time I’m writing this Apple hasn’t yet updated the iPhone Configuration Utility to know how to generate profiles for the new iOS 7 feature. So, we get to do this the hard way – hand-creating an XML file with the proper config profile syntax. Unless you are some kind of blog-reading robot for whom XML syntax is a native language, this might not be the easiest task in the world, so I’m going to help you out with the contents for a “sample” profile at the bottom of the post. You can just grab this text and paste it into a plain text file with a .mobileconfig extension (e.g. kerberos.mobileconfig).

There are a few parts you’ll want to pay attention to, and then hopefully you should be off and running.

As with any example you grab from the web, unless you are referencing a “well-known” identifier for some kind of resources, you’ll want to make your own GUIDs and replace the ones you see in the example.

Anywhere you see “com.mycompany”, you’ll probably want to use your own domain

In the string value for the “Realm” key, you’ll want to put your own Kerberos realm. In the case of Active Directory, that’s usually going to be an AD domain

The URLPrefixMatches section is key, because iOS is only going to try to get and use the Kerberos ticket for URLs that match one of these. Unfortunately there is currently no “suffix” option, so you can’t just do http:⁄ ⁄ *.mycompany.com. As the name implies, you can use a prefix, but doing a “blanket” prefix like http:⁄ ⁄ * seems like it would be a pretty bad idea.

Eventually I assume there will be other apps that support Kerberos, and then you might list their bundle ids in the AppIdentifierMatches section, but for now using Safari is an interesting place to start

Save the modified file and then deploy it to your device. Unless you also happen to be an MDM administrator who knows how to use your MDM product to deploy these files, the easiest way to do this is probably just to email yourself the .mobileconfig file and then open it is as an attachment on the device. You’ll get a couple of security warnings this way, but it works. When the profile is geting installed you should also be prompted to enter a “principal name” for the specified realm. Generally speaking this will be your login id/username.

Now that you have a SSO configuration profile on your iOS 7 device, you can try it out. If you open up Safari and go to one of the sites that matches an entry in your URLPrefixMatches section, you’ll see a login dialog that looks a bit different than the typical “popup” prompt you’d see for a site requesting Basic or Negotiate-based authentication. Once you’ve entered your password, it should let you into the site. The beautiful part is that when you go to the next site in your list of URLs, you won’t get prompted at all, and you should be able to go revisit these sites in Safari over and over (up to the ticket expiration time for your Kerberos environment) without re-entering your password. Single sign-on is a beautiful thing!

Don’t get discouraged if it doesn’t work right away. The diagnostic logs from your device can be very helpful in figuring out what’s going on. I know they pointed me in the right direction for fixing up the .mobileconfig file several times. I’d be remiss if I didn’t tip my hat to Craig Newell, a mobile tech guru at VMWare for being kind enough to post some similar sample info in the Apple Developer forums that was super helpful in getting this working.

Post navigation

54 thoughts on “Kerberos Single Sign-On in iOS”

Thanks for posting…. I tried this a few different ways and it just keeps prompting me many times for my password. I suspect I can’t get any of the “diagnostic logs” from my device without developer tools – is that right? Anything in particular I should look at?

Sorry, didn’t get to this til now. Are you getting a dialog that looks like the one above? Or the “challenge” dialog that has a username and password field? If it looks like the one in the post, it sounds like your device isn’t able to get it’s initial Kerberos ticket from your KDC. Assuming the password you’re using is right, this may be because the principal name doesn’t match up exactly. If you’re using AD, you may want to check to make sure the domain/realm is listed in all caps in the profile.

Sorry if I made it sound like the wildcard would be a huge security issues that would lead to your account being compromised or something. That definitely wasn’t my intent. The reasons it seems like it would be “pretty bad idea” to me is that you’d potentially be creating a lot of extra requests from your iOS device and in some extreme cases pounding your poor KDC (domain controller if we’re talking Active Directory) with queries for service principal names that don’t actually exist, or at least don’t exist in your Kerberos realm. Also, in a lot cases, it’s just going to generate useless/dead-end overhead for your device if you’re not actually on some kind of trusted/internal network and hitting a web server that sends back Negotiate headers in it’s response. I suppose it’s possible there’s some weird security edge case where this would lead to bad things when communicating with a malicious server (e.g. someone may be able to figure out the host name of your organization’s KDC by spoofing HTTP responses and sniffing for traffic at your local open wifi hotspot of choice). I’m not going to try to make the case that the world’s going to come to an end if you use this configuration though, so if you think it would suit your purposes, cool. I’d just recommend thinking it through first.

I got the dialog that looks like the one above,but when i enter the password, it didn’t work right .
the “diagnostic logs” from my device :”
Mar 5 15:23:52 makephone accountsd[11571] : 2015-03-05 15:23:52.779 accountsd[11571:8307]: Cannot check access to a private account type: com.apple.account.kerberos.sso.178EE3AB-9EBE-4FDF-BDBE-D87C46603AA2″.

Hello, thank you for your article. I have a question: Is this possible to make it work for different URLs? I mean, can I create a new XML profile for each website (e.g. mail.google.com, then for linkedin.com etc.) and deploy them to iOS? Thanks.

Sorry, I haven’t been keeping up with comments here. You should be able to have multiple SSO profiles. I’ve done some basic testing with, say one profile pushed via MDM plus a manually installed one and it seem to function as I expected. Of course, I can’t speak to whether this is intended behavior or not, but it seems consistent with behavior of other types of config profile.

As far as I know these steps still work in iOS 8. Haven’t seen any need to change anything with iOS 8 devices. There are some new capabilities allowing for certificates to be used in the SSO process I believe, but I have not had the opportunity to play with any of that. I’ll update the post indicating as much.

I’m won’t claim to know everything that’s possible with ADFS, but I don’t think that would be a very typical configuration. What I’ve usually seen with ADFS is people using it as a Kerberos “service” (with it’s own SPN) so that Kerberos clients can seamlessly authenticate to it by obtaining the appropriate ticket and then presumably be redirected on to some federated service provider. There are probably other patterns, but I haven’t personally encountered any where the ADFS server name would be used as a Kerberos realm.

The one unfortunate thing about SSO that I found is this doesn’t persist through Safari session close. Once you log in and force close Safari your Kerberos ticket is dead. When you relaunch safari you need to log back in again.

I haven’t found this to be the case. In fact, I’ve found it can be difficult to get rid of the ticket early, even after removing the profile with the SSO config. You definitely shouldn’t be getting prompted every time you open Safari. That sounds more like the OOTB behavior for Safari with sites that use Windows authentication.

At first, thanks a lot for this article, it helped me setting this up. But I’m having massive performance issues with this.
The site loads really slow (what isn’t the case without the SSO profile) and when it’s loaded the ajax call on the site also are really slow, what makes this solution unusable right now.
I couldn’t find any solution for this when googling and also the log in Xcode doesn’t give any interesting output. For me it sounds like there are some issues with the authentication and because of that the requests didn’t get passed correct to the IIS. Does somebody has a tip for me or some help that could help me continuing my research?

I wish I had a definitive answer for you on this. I think I have seen some noticeable performance hit for certain sites as well, but honestly have not dug into it enough to see what’s really going on. One thing you might try is tracing the requests (e.g. point your device’s proxy through something like Fiddler) and see if you’re getting way more 401s than you should. If so, there might be some things you can tweak on the IIS box, assuming you have control over them.

We are facing the same issue. The manually created certificate like posted here works as expected (also complex sites, we tried SharePoint 2013 – works), but some other web pages are extremely slow. We tracked this down on network level and found that in a complex multinational AD environment not the correct (local) domain controller is always used (Windows devices like Surface, … do this this – they know which site they belong to) , but rather random other domain controllers worldwide are contacted by the ipad on Kerberos ports giving you timeouts, slow replies and non-working sites because of complex JavaScript-Usage. One JS depends on the other and the first one not being loaded in time so the second fails. Connecting the ipad via Cable to Mac Safari in Debug Mode clearly shows that random elements of a complex page are not loaded. Once the correct domain controller is found accidentially, the page is loaded fast. Information on how iPad can be forced to behave like Windows devices on DNS level – urgently needed if possible at all.

Thank you both for the replies Tom and syates21. When tracking down the code with Fiddler and Safari Developer Tools I also recognized long loading times before the first HTTP request was visible in Fiddler wich sounded to me like an issue with requesting the TGT or the ticket for the web request wich would fit with your suggestion.
But in the developer tools I often could find an error showing up that said something like “Webkit recognized an internal error”. But that doesn’t need to exlude Tom’s suggestion. BTW: I haven’t tried this with iOS 9 because I don’t want to open new issues as I couldn’t track these down completely.
So far I had no chance (or it was not possible for me) to track this down on network level like Tom did.

Hmm, yeah I’ve run into that problem in other contexts, where you have a non-Windows client looking up a domain controller in DNS in order to make some kind of call (e.g. LDAP). That makes sense as an explanation, if you have a geographically distributed AD domain/forest with some far flung domain controllers. In theory Apple could handle this, although I think the process of looking of the “closest” domain controller is kind of involved, and fairly specific to Active Directory. If your AD isn’t managing it’s own DNS, you might be able to get cute with the way you do SRV records for Kerberos in your DNS infrastructure. Otherwise, I don’t know of a good way to control this behavior, because all the default SRV records I believe report the same exact priority and weight. I’m not aware of anything that would let you specify a KDC address, and even if you could it might not be a very good idea.

With all due respect to the posts you’re looking at, it’s definitely possible for a Kerberos client to get a ticket from a Windows domain controller without being on a computer that’s a member of the domain. I can see where the perception would come from though, as the “magic”/seamless Windows authentication that leverages Kerberos does only work with computers that are either domain members or have some sort of trust relationship with a domain AFAIK. But even on Windows, if you use, say, the “kinit” that comes with Java, you can do kinit user@SOME.UNTRUSTED.DOMAIN and put in the password for that account and it will grab a ticket and store it in a cache file for you. This is roughly equivalent to what an iOS device (or a Java app) would be doing to use Kerberos auth.

To address IIS specifically, it’s definitely possible to have iOS devices authenticate to services hosted with IIS and use Kerberos tickets to do so. In fact, I’d bet that’s the most common use case for iOS and Kerberos (think corporate intranet on SharePoint and that sort of thing), or at least one of them.

Since the release of iOS 9.2, I am getting the same behavior that deanparkr mentioned – after the initial SSO password prompt, the page never resolves and constantly prompts the traditional login screen. I know these settings worked with SSO in previous iOS versions. Was something changed in iOS 9.2?

I’m trying to get Kerberos (*nix, not AD) sign in working on an iPad running iOS 9.3.1 and think I’ve hit a sandbox bug but just wondered if anyone else has seen this and/or has a solution.

I’ve deployed the mobile config for our realm to my test device. When I go the webapp in Safari I’m prompted for my principals password but then fails to authenticate. Looking at the device logs I see the following a few times before Safari gives up:

Interesting one Jim. I don’t think I’ve ever run across/noticed those sandbox log messages. Have you been able to verify that your KDC is not actually seeing any requests/communication coming from the device? Basically trying to see if this is blocking everything or just certain messages for some reason. Also, is this new behavior in 9.3.1 you’re noticing? I don’t think I’ve done any Kerberos testing on that release yet.

Here’s something I’ve been wrestling with recently in trying to propagate this file. It works great if I updated it for my company (realm name, new GUID’s, etc.) and mail it to my self. I tap it, it installs, and when I go to one of the URL’s I’ve configured it asks me for my user ID, which I supply, and password. From then on it just asks me for my password.

Great, but I’ve got about 2000 mobile devices out there in my org running iOS. Whether I use AirWatch or InTune, it’s an MDM, and I can’t deploy this in an MDM without adding the PrincipalName attribute, and that doesn’t work to distribute it unless I supply my specific ID as the string value for that key attribute. When I do that it works great – the MDM distributes it, it downloads to my device, and it works as it did before when I simply mailed it to myself.

As you can discern from this, though, it means I need an individual .mobileconfig file, and an individual MDM configuration policy for each individual user in the organization. For a few dozen users, that might be OK, but for thousands, that’s untenable.

Does anyone have any experience trying to deploy this type of file from an MDM?

First, I agree that managing an individual file for that many users is untenable. Fortunately the state of support for this stuff is much better than when I originally wrote this post. With an MDM provider like AirWatch, it ought to be able to deploy a configuration profile like this without you even needing to upload a file “by hand”. It should also be able to plug in attributes about the user into the profile, so depending on what kind of info you populate (or sync) into the users profile in your MDM system, you should be able to plug in the user part of the UPN at least. I think a pretty common scenario for larger enterprise is to sync data from Active Directory or some LDAP or database source to the MDM system, so in this case it would be important to make sure that username attribute is synced. If you have a multi-domain active directory or something, there may still be some trickiness for specifying the “realm” for a user, but you could probably at least cut the number of distinct configurations down to one per domain or something.
Does that help at all? I don’t really have access to a lot of different MDM solutions, or I’d try to provide more specific instructions.

Something I’ve been very interested in. Primarily because my latest mail server does not accept plaintext password under SSL — it needs to be a GSSAPI login. It works great under macOS, just get a TGT and check mail. But on iOS, not so much. Even though I’ve added the app key for Mail, it does not cause the mobile device to act any differently to check mail.

This is an interesting post. Thank you for the guide. Could I also check, is there a way to automate the renewal of Kerberos authentication, without or with very minimal end user intervention, maybe one login in a week or so. Basically my goal is to automatically get the device to re-register the kerberos certificate and also extend the expiry of the certificate, before it even expires.

I have the same question regarding the renewal process. When accessing the URL via Windows machine, the Kerberos ticket renewal is seamless and I never have to re-enter my password. On the iOS device, the user is prompted for a password after the expiry period. Although my issued Kerberos ticket has a 10hr expiry, it does have the renewable flag set and the Renew Time set to 1 week after the start time. On iOS, the user is prompted for a password every 10 hrs, instead of once a week. Any assistance would be appreciated.

It might be a little bit misleading to compare the behavior on an iOS device to a domain-joined Windows machine when it comes to Kerberos. I’ll admit upfront I have not done any experimentation with trying to extend the ticket lifetime on an AD DC/KDC. I think that renewal is going to tend to seem “automagic” on Windows, at least if any kind of auto-lock policy is applied because they user will be re-entering their credentials each time the machine is unlocked. I don’t think iOS has any equivalent process (AFAIK unlocking the device does not initiate communication with the KDC in and of itself). This may account for the difference in behavior people see between the two types of clients.
Of course, it’s entirely possible there are other differences at work as well. 🙂 Please don’t just take my (speculative) word for it.

Very interesting article! I came to your blog looking for a solution to a certain case. We have airwatch and we use iOS mobile SSO. Authentication goes to ADFS 3.0 which federates different apps. During the first login for some days of inactivity login to such app from iOS can take up to 30-40s. No issues when we do not use iOS mobile SSO. Any thoughts, did you saw something similar?

I did open an Enterprise Support ticket with Apple and got hold of a super guy with deep knowledge about the issue. I’m not able to share the case details but we submitted network traces and detailed device side logs (remember to enable this using bug-reporter profiles)

Seems this issue last quite a long time. We are using MDM with Safari SSO profile. Even distribute the certificate to the device through SCEP to improve overall SSO process. But when tickets expired, the overall SSO still cant go seamlessly.
What I observed for months.
Safari SSO to Exchange OWA > looks good and able to load properly
Access OKTA User page > Mostly prompt for UserID/Password after ticket expired. Mostly I will load OWA to kick up to obtain Kerberos tickets. After reload OWA 1 – 2 times. Access OKTA webpage again will be “SSOed” .
After that, access other SSO website will be normal again.

https://developer.apple.com/enterprise/documentation/Configuration-Profile-Reference.pdf tells me on page 79, that “PrincipalName String Optional. The Kerberos principal name. If not provided, the user is prompted for one during profile installation. This field must be provided for MDM installation.”
I nowhere found the string to add to the xml to dynamically “generate” the principal name after the deployment of the profile to the device.

We’re using a SCCM/Intune hybrid currently and I try to push the xml as imported ConfigurationItem in SCCM.

any updates on the problem regarding the waiting time when the first authentication takes place?

We have a working SSO-enviroment, but the first authentication (after reboot) takes a very long time. About 20 – 40 seconds.
The next time when accessing the ressource, authentication proceeds withing 2 or 3 seconds.