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.

  1. 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.
  2. Anywhere you see “com.mycompany”, you’ll probably want to use your own domain
  3. 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
  4. 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.
  5. 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
  6. 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!
KerbLogin

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.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>PayloadContent</key>
	<array>
        <dict>
            <key>PayloadType</key>
            <string>com.apple.sso</string>
            <key>PayloadVersion</key>
            <integer>1</integer>
            <key>PayloadIdentifier</key>
            <string>com.mycompany.sso.test.kerberos</string>
            <key>PayloadUUID</key>
            <string>132013d0-faff-11e2-b778-0800200c9a66</string>
            <key>PayloadDisplayName</key>
            <string>SSO profile for my enterprise</string>
            <key>PayloadDescription</key>
            <string>Configures Kerberos Single Sign On.</string>
            <key>PayloadOrganization</key>
            <string></string>
            <key>Name</key>
            <string>Kerberos Config</string>
            <key>Kerberos</key>
            <dict>
                <key>Realm</key>
                <string>AD-DOMAIN.MYCOMPANY.COM</string>
                <key>URLPrefixMatches</key>
                <array>
                    <string>https://kerbenabledapp.mycompany.com</string>
                    <string>http://nonstandardapp.mycompany.com:16089</string>
		    <string>http://commonhostnameprefix*</string>
                </array>
                <key>AppIdentifierMatches</key>
                <array>
                    <string>com.apple.mobilesafari</string>
                </array>
            </dict> 
        </dict>
	</array>
	<key>PayloadDescription</key>
	<string>Sets up Safari to use Kerberos SSO for certain URLs</string>
	<key>PayloadDisplayName</key>
	<string>KerberosConfigProfile</string>
	<key>PayloadIdentifier</key>
	<string>com.mycompany.ssoconfig</string>
	<key>PayloadOrganization</key>
	<string>MyCompany</string>
	<key>PayloadRemovalDisallowed</key>
	<false/>
	<key>PayloadType</key>
	<string>Configuration</string>
	<key>PayloadUUID</key>
	<string>B55B5378-6709-40EB-A380-76F59C3B7D86</string>
	<key>PayloadVersion</key>
	<integer>1</integer>
</dict>
</plist>
Advertisements

39 thoughts on “Kerberos Single Sign-On in iOS

  1. JoeD

    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?

    Reply
  2. syates21 Post author

    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.

    Reply
  3. Pingback: Looking at kerberos authentication in iOS7 | Toby's stuff

  4. syates21 Post author

    Somehow I didn’t notice that the post said you *can* have URL suffixes, instead of you *can’t* have them. Updated that accordingly – thanks Dan!

    Reply
  5. syates21 Post author

    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.

    Reply
  6. wood

    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″.

    Reply
  7. Jaco

    Thanks a lot. It works !
    Question : it works fine for Safari (due to this line, I guess : com.apple.mobilesafari)

    Unfortanately it doesn’t work for a WebClip (normal, because it isn’t safari).

    I’m trying to get it work in adding a line com.apple.webClip.managed, but I can’t get it working…

    If someone has any idea.

    Reply
  8. Oleg

    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.

    Reply
    1. syates21 Post author

      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.

      Reply
  9. Roby

    Hello. Thanks for the article.
    Are you planning on revising this article to go with iOS8? Or is the article still valid with iOS8 as well?

    I am getting an “Invalid Profile” error when I try to follow your instructions.
    Device: iPAD Air
    OS: iOS 8.3

    I may be doing something silly too. Not sure.
    Can you please help?

    Thanks,
    Roby

    Reply
    1. syates21 Post author

      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.

      Reply
    1. syates21 Post author

      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.

      Reply
  10. Jon Towles

    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.

    Reply
    1. syates21 Post author

      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.

      Reply
  11. thoff

    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?

    Thanks a lot in advance

    Reply
    1. syates21 Post author

      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.

      Reply
    2. Tom

      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.

      Reply
      1. thoff

        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.

      2. syates21 Post author

        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.

      3. Jelle

        I’m looking into this for a while now. i have kerberos setup through IIS and i find numerous posts that say that it is not possible to get Kerberos authentication from IIS for computers that aren’t in the domain (e.g. http://stackoverflow.com/questions/14224580/iis-using-kerberos-with-client-computers-that-are-not-on-the-domain). So I’m wondering what is needed by IIS to receive a proper Kerberos ticket and if it is even possible what I’m trying to do here.

      4. syates21 Post author

        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.

      5. Jelle

        Do i understand it correctly that what you are saying is that the application are responsible for kerberos authentication and IIS is just a simple reverse proxy?

  12. Pingback: iOS上实现单点登录(SSO) | 思空,简观

  13. deanparkr

    Interesting post. We have tried to implement SSO and we find we get the SSO login box, but when we enter the credentials the page then shows the traditional HTTP challenge box afterwards.

    If we enter the password incorrectly on the SSO box, the SSO box appears again so it seems like the password is being accepted ok.

    Looking in Fiddler after entering the password correctly in the SSO box we see three further 401 requests before the traditional HTTP challenge box appears. Most odd!

    Reply
  14. Nathan

    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 upgraded this morning to iOS 9.2.1 and the issue was not fixed.

    Reply
  15. Jim

    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:

    Apr 14 11:50:35 Jims-iPad kernel[0] : Sandbox: com.apple.WebKit(218) deny(1) network-outbound *:88

    Seeing that I added com.apple.WebKit to the AppIdentifierMatches array but no difference. So it looks like mobilesafari/webkit is being blocked from contacting the KDC on port 88 by sandboxing.

    Likely iOS sandboxing bug or have a done something daft in the mobileconfig file?

    Reply
    1. syates21 Post author

      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.

      Reply
      1. Jim

        Good point. Seeing the deny message in the console I didn’t even think to check the KDC logs!

        So I see the following sorts of messages in the KDC syslog stream:

        kdc-1 krb5kdc[906]: AS_REQ (4 etypes {18 17 16 23}) 192.168.19.170: NEEDED_PREAUTH: jimcroft@OURREALM.NET for krbtgt/OURREALM.NET@OURREALM.NET, Additional pre-authentication required
        kdc-1 krb5kdc[906]: AS_REQ (4 etypes {18 17 16 23}) 192.168.19.170: ISSUE: authtime 1460649699, etypes {rep=18 tkt=18 ses=18}, jimcroft@OURREALM.NET for krbtgt/OURREALM.NET@OURREALM.NET
        kdc-1 krb5kdc[906]: TCP client 192.168.19.170.60382 wants 1820459715 bytes, cap is 1048572
        kdc-1 krb5kdc[906]: closing down fd 20

        I’ve no idea what they mean yet but have something to go on now! 🙂

  16. Greg Walrath

    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?

    Reply
    1. syates21 Post author

      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.

      Reply
  17. Brian Topping (@briantopping)

    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.

    Reply
  18. Rice_bowl

    Hi,

    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.

    Thanks,

    Rice_bowl

    Reply
  19. Peter Tozser

    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.

    Reply
    1. syates21 Post author

      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.

      Reply
      1. Peter Tozser

        Thank you for the reply, that might be the key to the main difference: automatic renewal when a windows workstation is unlocked, which doesn’t happen on iOS.

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