Setting the Default Kerberos Credential in MacBook Credential Cache

Estimated read time 40 min read

This blog solves an issue that can occur when a MacBook holds more than one Kerberos Token for the device user, and the so-called Default or Primary Kerberos Token is not the one that SAP Secure Login Client needs to perform SSO over SAPGUI to an SAP system. There are two manual solutions, and also an automated solution using a script and a plist file.

Because most SAP experts, and actually very many IT experts, often have a limited understanding of how Kerberos works, and/or of how Kerberos works for SSO over SAPGUI, so this blog provides the long story so as to hopefully show why the solutions are sometimes needed, and how these solutions work.

 

Intro and Context

In many organisations, for years the main directory-based Identity Service has been Microsoft Active Directory (“AD”) – and most likely AD will continue to be important for many years to come.

In particular, many services in organisations use AD-based Kerberos as the solution enabling SSO (Single Sign-On) – for example, SAPGUI clients such as SAPGUI for Java for MacBook and SAPGUI for Windows, with the help of the SAP Secure Login Client utility app, can use a user’s AD-based Kerberos Token to enable SSO SAPGUI sessions.

In the screenshot, replaced the actual Kerberos Token with a green rectangle – let’s give it an imaginary identity though for this blog’s imaginary user, Marmot Marmotsson, who is the AD-user: MARMOT@AD.BURROW (…the “AD.BURROW” part is called the Kerberos Realm).

When you login to your organisation-managed device – or when you login to your organisation’s network; and assuming that your organisation is running a Kerberos server (often called “KDC”), and assuming that the Kerberos server bases its distribution of Kerberos Tokens for users defined in the organisations Active Directory… then the Kerberos server will send the logged-in user a Kerberos TGT (“Kerberos Ticket Granting Token”, often abbreviated to “Kerberos Token”). This Kerberos Token is then squirreled away in a wee store on your device called the (Kerberos) Credentials Cache.

On a MacBook, there are two main methods for viewing the Kerberos Tokens in the Credentials Cache. One method is to open the system app called Ticket Viewer, e.g. via Spotlight (<command> + <space-bar>) then typing “ticket” and double-clicking on Ticket Viewer:

Yous have all been paying attention so you know that the green rectangle in this screenshot represents the Kerberos Token for MARMOT@AD.BURROW 😄.

The other method is to open a Terminal and use the ‘klist’ utility, more on that method later. For now, we are just noting that our human – or at least, mammalian – user Marmot Marmotsson has a relevant Kerberos Token for their AD-based user.

So now the user opens their SAPGUI for Java for MacBook app (“SAPGUI app”), where typically there is a list (or lists, if multiple workspaces) of Connection Items for connecting to SAP systems. In case Kerberos has been implemented properly generally, and in particular for SAP systems (a config-topic not considered in this blog), then each SAP system will have been defined in Active Directory as a so-called SPN (“Service Principal Name”), and if you view the details of a relevant Connection Item, under tab “Security”, you should find that “Enable Secure Network Connection” checkbox is ticked (i.e. in ON-state), and also you should find the SAP system’s SPN identifier prefixed by “p:CN=” under “SNC Name”, and in case of Kerberos usage, one of the radiobutton choices “Authentication” or “Max. Available” has been chosen:

If you like, you can imagine that the screenshot shows the details for SAP system “DDD”, which has, say, an SPN called SAPServiceDDD defined in Active Directory.

Now when the user e.g. double-clicks on the Connection Item in the relevant Workspace in their SAPGUI app to open a new SAPGUI session on the SAP system, what happens is that the SAPGUI app realises there is a possibility to perform an SSO logon (given the details of the Connection Item shown above), so it asks a separate client app on MacBook, called SAP Secure Login Client (“SLC”), to handle the authentication steps.

Assuming the SAP Secure Login Client has discovered the Default Kerberos Token for the user on the MacBook (usually it succeeds if such a Token exists), SLC essentially says to the Kerberos server’s TGS (“Ticket Granting Service”): “well, I have this Ticket Granting Token on behalf of (say) MARMOT@AD.BURROW – so, for the SPN called SAPServiceDDD, please grant me a ticket!”. So this is granted, and as a result the SAP System DDD (i.e. the “service” defined by that SPN) allows the user to logon.

[There is typically user-mapping configuration done in the target SAP System to relate each ADuser@Realm ticket to an SAP User ID – you would typically find this info in tcode SU01 (go to tab SNC for some user): the SAP User (say, MARMOTDD) has an SNC Name consisting of the prefix “p:CN=” and then the MARMOT@AD.BURROW (ADuser@Realm) text].

So the result is that the user is logged in to their SAPGUI session, and a message at the bottom of the SAPGUI screen informs you of the SSO success:

 

In this screenshot, the magenta rectangle covers the SAP system-client number and the SAP User ID for that system-client, while the green rectangle covers the MARMOT@AD.BURROW identifier.

So, that’s how SSO for SAPGUI using Kerberos happens, when all the various config is correct on: the SAP system itself, the Active Directory, the KDC, the MacBook, the SAPGUI app, and the SAP Secure Login Client. “Easy… what could possibly go wrong?!” 😂… well, we will see how one innocent change to the way MacBook receives and stores Kerberos Tokens, introduced to improve the SSO-for-browsers user-experiences, can inadvertently break this SSO for SAPGUI workflow…

 

More Than One Kerberos Token

Nowadays one of the main use cases for SSO in organisations is to authenticate to various web services using a browser. For example, it’s quite common that for SAP Fiori Launchpads, the authentication is done via Microsoft Entra ID (which used to be called Azure Active Directory). There are of course other companies providing similar authentication services, but we will follow our Entra ID example.

So this is fine, but: Entra ID has its own separate Kerberos Realm, so it does not itself use the Kerberos Token supplied by our (on-premise) Kerberos server for Realm AD.BURROW; so for the MacBook users in our organisation it means that – per browser session– the user would have to login (via Entra ID) to some web service such as a Fiori Launchpad i.e. specifying username and password, and maybe also using (say) the Microsoft Authenticator mobile app to perform a 2FA manual login. Which is not really SSO anymore, when the user has to do these extra manual logins in addition to their initial device or network login.

So our MacBook and Identity Management teams came up with a good idea: a certain Microsoft service for MacBook gets installed and configured on the local device (we skip the details, other than to say that this service is Microsoft Azure-centric); then when the user logs in to their device, the service can go and fetch (via Azure) two Kerberos Tokens (even if the device isn’t currently on the organisation’s “on-premise” network): first, a Kerberos Token for the Entra ID user, let’s call it:

username@example.com@KERBEROS.MICROSOFTONLINE.COM

The Realm here is the actual Realm used by Entra ID to provide Kerberos. And this Azure-supplied Kerberos Token becomes – on the MacBook device – the Default Token in the Credentials Cache.

In addition, the old-school Kerberos Token for (say) the AD.BURROW Realm is fetched,  via integrations between Azure and our on-premise Active Directory. This Token is also stored in the Credentials Cache, though it is just an “ordinary” Token (and specifically not the Default Token). Ticket Viewer shows both Tokens in the Cache:

Now, this is generally a good thing – for the web services that prefer Entra ID to handle authentication, the browsers (Safari, Chrome, Edge tested) are able to ask the MacBook for the username@example.com@KERBEROS.MICROSOFTONLINE.COM Ticket Granting Token stored in the local Credentials Cache, and so when the user goes to, e.g. some SAP Fiori Launchpad* or some Jira Project page belonging to the organisation, SSO happens (via the Azure-based Kerberos server’s TGS, and so on) and the user doesn’t need to do manual login to those websites. So that’s a real improvement in the users working lives.

[*Note that for services located on your on-premise network which are not configured for public Internet access, you still need to be yourself connected to the on-premise network to access those services, e.g. on the office LAN or via a VPN connection – even if you have SSO working. Remember kids: SSO automates login workflows, but it doesn’t create its own “additional” VPN tunnel through your firewall… maybe you already know this, but in my experience many people don’t yet know this, so FYR].

The only downside to having these two Kerberos Tokens, where the Token for the AD.BURROW Realm isn’t the Default Token, is that, well, SSO for SAPGUI doesn’t work in this scenario anymore (though this blog will later explain how to get it working again). The reason for failure is that SAP Secure Login Client is only aware of the Default Token in the local Credentials Cache, so it finds only the Token for KERBEROS.MICROSOFTONLINE.COM – but because this Azure-based Kerberos server doesn’t know anything about the SPN (say) SAPServiceDDD defined within an entirely different Kerberos Realm (and what the server does not know, it certainly will not trust), so it is not going to be able to grant a Ticket for the relevant SAP Service (e.g. SAP System DDD)… and so the logon attempt to DDD over SAPGUI fails, probably with the following error message:

Well, that’s annoying. So we need solutions which allow us to keep both Kerberos Tokens in the local Credential Cache, but for the Default Token to be the one for the on-premise, AD-based Kerberos Realm.

Below we describe three solutions. I have tested that they work, including testing that for the websites using the Azure-based Kerberos Token, those continue to work even when that Azure-based Kerberos Token loses its “Default” status in the local Credentials Cache. Disclaimer: if these solutions don’t work for you, then you will need to find your own solutions, as I don’t run any Helpdesk in my spare time, and won’t in future either 😂 .

[A fourth possible solution would be if the Microsoft service on the MacBook could do the needed swapping of the Default Token at fetch-and-store-time, but as I have solved the issue on client-device side already using the below solutions, so I haven’t investigated this possibility].

It’s a good idea to close SAP Secure Login Client and close SAPGUI for Java for MacBook before applying any of the manual solutions, to ensure that old Token info isn’t left in the caches of these apps. One way is to right-click on their respective icons in the Dock, and choose “Quit”. Or: in the top menu of the SAPGUI app, choose SAPGUI -> Quit SAPGUI; and in the wee icon in the right-hand side of MacBook top menu bar, for SAP Secure Login Client (white tick on blue diamond), click on the icon and choose Quit SAP Secure Login Client.

 

Solution 1 – Use Ticket Viewer to Change Default Token

Open Ticket Viewer – e.g. via Spotlight (<command> + <space-bar>) then typing “ticket” and double-clicking on Ticket Viewer – then click on the Token you want to set as the Default Token so that it is highlighted (blue background denotes highlighted item). In our example, we highlight the Token for AD.BURROW …Then click on the button called “Set as Default”:

And, well… that’s all you need to do!

Ticket Viewer doesn’t tell you that this action has succeeded, and has no marker identifying the current Default Token in the list, but I have tested that the button works fine.

Now you can open SAPGUI app and logon via SSO using in our AD-based Kerberos Token (SAPGUI app will open SAP Secure Login Client when needed).

“So you wrote this long blog just to tell us about such a simple solution??” …well, it’s simple enough once you realise that it’s a solution, but realising what to do is tricky unless you have understood the root cause of the issue. The good thing about this solution using Ticket Viewer is it is quite easy to use. The disadvantage is that each user needs to remember to do this manual solution every time they login to their device, and before they open the SAPGUI app. Which is why I developed a better solution (“Solution 3”, below in this blog) that doesn’t require the users to implement this Ticket Viewer solution. Though the manual solution remains as a good fallback option in case a more complex solution doesn’t work.

During the research for a better solution, I found an interim solution (“Solution 2” below) that i might use myself, but most users wouldn’t use – anyway the next section describes this Terminal app solution…

 

Solution 2 – Terminal app, klist, and kswitcher

Because I wanted to automate the solution that uses Ticket Viewer, well, one way to do that is to first work out what happens at command-line level when a user presses the “Set as Default” button in the Ticket Viewer app (and once this is known, use a script and config file to further automate). So I found the relevant commands… to use them, open the Terminal app… the first one is:

klist

This command displays the current Default Token from the Credentials Cache. But we would like to see a list of all Kerberos Tokens in the cache, for that we should use:

klist -l

[The option is the lowercase “L”, abbreviation of “list-all”, and not the numeral “1”].

In the results command, the current Default Token is denoted by the relevant item having an asterisk character ‘*’ as the first string at the start of its line, shown in this heavily redacted screenshot in the magenta box:

 

To change the default, the easy way is to use the command:

kswitch -i

[“i” for “interactive”].

This lists all the Tokens in the cache with line numbers, and asks you to choose the line number of the Token you want to be set as default. So you choose the number, e.g. of the line for AD.BURROW Token in our blog example – so that is line 2 from the above screenshot – and then you can check (using ‘klist -l’ again) that the relevant Token was indeed set. Now you can open SAPGUI app and logon to SAP using SSO.

 

Solution 3 – A script and a plist file

This works for me just fine – feel free to base your own solutions on my templates, but remember kids, I am not going to offer any debug help if this doesn’t work for you.

So the idea is to have a script, which runs at user login to the MacBook, and the script assumes that during the first 30 seconds after user login, the computer retrieves some Kerberos Tokens and sets the Azure-based Token as Default – so that when the script discovers those Tokens, it can if needed set the AD-based Token to be Default.

[The reason I mention this assumption, is that it may not be true in your organisation. For example, it could be that all the Kerberos Tokens for your user+device combination are only fetched later, e.g. once the user connects to a VPN – in such a case, you would need some way of running this script once some system or program event is recognised, or by some other method like a wee GUI app or whatever. And since that “delayed fetch”-scenario doesn’t apply to me in my organisation, I haven’t researched the details of that scenario at all. Probably it’s doable though, wishing yous good luck with that].

To enable the script to run at login, we define a plist file, which is an XML file. Here is an example file, called com.example.org.kswitcher.plist

<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>

<plist version=”1.0″>
<dict>
<key>Label</key>
<string>com.example.org.kswitcher</string>
<key>LimitLoadToSessionType</key>
<array>
<string>Aqua</string>
</array>
<key>Program</key>
<string>/Users/Shared/macscripts/userlogin/kswitcher.zsh</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

 

It’s important to make sure that the Label string matches the filename minus the “.plist” part. [If you don’t make them match properly, the plist does nothing]. So in our case the correct string is com.example.org.kswitcher

The LimitLoadToSessionType key with value “Aqua” just ensures that this plist is only “active” for GUI-based user login sessions (i.e. the typical situation, not remote SSH login). Then the Program key specifies where our special custom-built kswitcher.zsh script is located. And the RunAtLoad key just means that the specified Program should run when the user logs in.

So for the relevant user, this plist file goes in their home directory:

~/Library/LaunchAgents

…the “~” means the home directory of the current user (so the target LaunchAgents directory is in the Library directory of the user, and not in the Library directory of the device).

Ok, so the plist file is in the right place – being in the user’s LaunchAgents directory, the plist will be run next time the user logs in to their device. Now what about the kswitcher.zsh script that the plist will run? First you create the directory that matches where the plist will look for the script, so for example:

mkdir -p /Users/Shared/macscripts/userlogin

Then you put the script in that subdirectory, and change the permissions of the script so that any logged-in user can run it, for example:

chmod 775 /Users/Shared/macscripts/userlogin/kswitcher.zsh

Here is the template for kswitcher.zsh – obviously you would swap in your own Realm in case it is not the same as in the blog example (where we use AD.BURROW). BTW I am not saying this is the best code ever, only that it worked well enough for me – feel free to develop your own version from any clues in this script…

#!/bin/zsh
###################################################################
# dylan drummond, helsinki #
# 26.11.2025 – 12.01.2026 (dd.mm.yyyy) #
# Licensed under: https://creativecommons.org/licenses/by-nc/2.5/ #
###################################################################

###################################################################
# This script switches the default Kerberos credentials to be #
# those for the AD.BURROW realm, so that Secure Login Client #
# picks up the correct Kerberos Token. #
###################################################################

# Add a log-entry:
date >> /Users/Shared/macscripts/userlogin/kswitchlog
echo “kswitcher script running…” >> /Users/Shared/macscripts/userlogin/kswitchlog
# counter=0

# At interval of 0.5 seconds (half a second), up to around 30 seconds from login, check to see if kswitch can be done:
repeat 60 {
# counter=$((counter+1))
# date >> /Users/Shared/macscripts/userlogin/kswitchlog
# echo “klist iteration: ” $counter >> /Users/Shared/macscripts/userlogin/kswitchlog

# Get the output of ‘klist -l’
OURKLISTL=”$(klist -l)”
ADSTR=”$(echo $OURKLISTL | grep AD.BURROW)”
ADTOKEN=”$(echo $ADSTR | awk ‘{print $1}’)”

# If empty, wait 0.5 seconds before retry (use ‘continue’ to skip to next loop iteration):
if [ -z $ADTOKEN ]
then
sleep 0.5
continue
fi

# We check whether the default Kerberos Token is already the AD-based one,
# i.e. if the ADTOKEN contains an asterisk instead of the actual Kerberos Token.
# In that case there is nothing to do so we can exit 0 i.e. exit with success return code…
if [ “$ADTOKEN” = “*” ]
then
date >> /Users/Shared/macscripts/userlogin/kswitchlog
echo “Nothing to do as AD.BURROW credentials are already the default… Bye!” >> /Users/Shared/macscripts/userlogin/kswitchlog
exit 0
fi

# We assume that if we got to this point, we have the string matching the relevant credential in ADTOKEN,
# …because if the Kerberos Token is not the default, that Token will be the first string retrieved into ADTOKEN.
# So we can kswitch:
kswitch –principal=$ADTOKEN

# We need to check that this has worked:
if [ $? -ne 0 ]
then
date >> /Users/Shared/macscripts/userlogin/kswitchlog
echo “Before SAPGUI usage: Open Ticket Viewer app from Spotlight and set AD.BURROW Token as default using the button!”
>> /Users/Shared/macscripts/userlogin/kswitchlog
exit 1
fi
date >> /Users/Shared/macscripts/userlogin/kswitchlog
echo “kswitcher ran successfully!” >> /Users/Shared/macscripts/userlogin/kswitchlog
exit 0

}
# Ended repeat loop

#If we got through that repeat loop, that should mean no AD.BURROW Token was found via ‘klist -l’:
date >> /Users/Shared/macscripts/userlogin/kswitchlog
echo “No Kerberos Token found for Realm AD.BURROW, so we cannot set non-existent token to be default credential.” >> /Users/Shared/macscripts/userlogin/kswitchlog

 

Once you have the automated solution set up (plist and script in correct locations and file permissions set), so you can log out of your MacBook, then login again and check if the solution works e.g. from the logfile, before opening SAPGUI app and unit-testing. You can see from the template that the script runs for up to 30 seconds and uses some kind of primitive Watcher-pattern, checking every half a second for Kerberos Tokens – and if they are found, attempting to kswitch the relevant Token to be the Default Token:

kswitch –principal=$ADTOKEN

[Note the two hyphens before “principal”, as this option specified using the full name of the option. Unlike in Solution 2, we don’t use ‘kswitch -i’, because in the script we want to avoid making the user interactively choose a Default Token].

So, good luck if you choose to use this Solution 3 with plist and script as a way to automate Solution 1 using Ticket Viewer. If it doesn’t work, good luck in your attempts to make it work; but remember that you can always fall back to using Ticket Viewer and the “Set as Default” button as a manual solution. Anyway remember to ensure that both SAPGUI app and SAP Secure Login Client are closed until some solution has been applied, so that when they are opened they will use the new Default Token that you set.

Although I have tested that this template version of the script runs ok (no syntax errors), in reality I have no such Kerberos Token for the imaginary AD.BURROW Realm, so it wasn’t a very comprehensive test: the logfile recorded an entry about no such Token for that Realm found, so the expected results matched the actual results 😂…however, this template was made by replacing (in a copy of the original script) the actual Realm used in my organisation, and I have tested that original script successfully: it’s working every day I login to my device, thanks to the plist that ensures the original script runs at login.

Also you can see some commented-out commands that I used when building and testing the script (so I could find out roughly how many seconds my device took to fetch the Kerberos Tokens and put them in the Credentials Cache – usually about 5 seconds). Left them in the script as comments, as a reference in case you want to do similar logging of the loop iterations.

 

 

​ This blog solves an issue that can occur when a MacBook holds more than one Kerberos Token for the device user, and the so-called Default or Primary Kerberos Token is not the one that SAP Secure Login Client needs to perform SSO over SAPGUI to an SAP system. There are two manual solutions, and also an automated solution using a script and a plist file.Because most SAP experts, and actually very many IT experts, often have a limited understanding of how Kerberos works, and/or of how Kerberos works for SSO over SAPGUI, so this blog provides the long story so as to hopefully show why the solutions are sometimes needed, and how these solutions work. Intro and ContextIn many organisations, for years the main directory-based Identity Service has been Microsoft Active Directory (“AD”) – and most likely AD will continue to be important for many years to come.In particular, many services in organisations use AD-based Kerberos as the solution enabling SSO (Single Sign-On) – for example, SAPGUI clients such as SAPGUI for Java for MacBook and SAPGUI for Windows, with the help of the SAP Secure Login Client utility app, can use a user’s AD-based Kerberos Token to enable SSO SAPGUI sessions.In the screenshot, replaced the actual Kerberos Token with a green rectangle – let’s give it an imaginary identity though for this blog’s imaginary user, Marmot Marmotsson, who is the AD-user: MARMOT@AD.BURROW (…the “AD.BURROW” part is called the Kerberos Realm).When you login to your organisation-managed device – or when you login to your organisation’s network; and assuming that your organisation is running a Kerberos server (often called “KDC”), and assuming that the Kerberos server bases its distribution of Kerberos Tokens for users defined in the organisations Active Directory… then the Kerberos server will send the logged-in user a Kerberos TGT (“Kerberos Ticket Granting Token”, often abbreviated to “Kerberos Token”). This Kerberos Token is then squirreled away in a wee store on your device called the (Kerberos) Credentials Cache.On a MacBook, there are two main methods for viewing the Kerberos Tokens in the Credentials Cache. One method is to open the system app called Ticket Viewer, e.g. via Spotlight (<command> + <space-bar>) then typing “ticket” and double-clicking on Ticket Viewer:Yous have all been paying attention so you know that the green rectangle in this screenshot represents the Kerberos Token for MARMOT@AD.BURROW 😄.The other method is to open a Terminal and use the ‘klist’ utility, more on that method later. For now, we are just noting that our human – or at least, mammalian – user Marmot Marmotsson has a relevant Kerberos Token for their AD-based user.So now the user opens their SAPGUI for Java for MacBook app (“SAPGUI app”), where typically there is a list (or lists, if multiple workspaces) of Connection Items for connecting to SAP systems. In case Kerberos has been implemented properly generally, and in particular for SAP systems (a config-topic not considered in this blog), then each SAP system will have been defined in Active Directory as a so-called SPN (“Service Principal Name”), and if you view the details of a relevant Connection Item, under tab “Security”, you should find that “Enable Secure Network Connection” checkbox is ticked (i.e. in ON-state), and also you should find the SAP system’s SPN identifier prefixed by “p:CN=” under “SNC Name”, and in case of Kerberos usage, one of the radiobutton choices “Authentication” or “Max. Available” has been chosen:If you like, you can imagine that the screenshot shows the details for SAP system “DDD”, which has, say, an SPN called SAPServiceDDD defined in Active Directory.Now when the user e.g. double-clicks on the Connection Item in the relevant Workspace in their SAPGUI app to open a new SAPGUI session on the SAP system, what happens is that the SAPGUI app realises there is a possibility to perform an SSO logon (given the details of the Connection Item shown above), so it asks a separate client app on MacBook, called SAP Secure Login Client (“SLC”), to handle the authentication steps. Assuming the SAP Secure Login Client has discovered the Default Kerberos Token for the user on the MacBook (usually it succeeds if such a Token exists), SLC essentially says to the Kerberos server’s TGS (“Ticket Granting Service”): “well, I have this Ticket Granting Token on behalf of (say) MARMOT@AD.BURROW – so, for the SPN called SAPServiceDDD, please grant me a ticket!”. So this is granted, and as a result the SAP System DDD (i.e. the “service” defined by that SPN) allows the user to logon.[There is typically user-mapping configuration done in the target SAP System to relate each ADuser@Realm ticket to an SAP User ID – you would typically find this info in tcode SU01 (go to tab SNC for some user): the SAP User (say, MARMOTDD) has an SNC Name consisting of the prefix “p:CN=” and then the MARMOT@AD.BURROW (ADuser@Realm) text].So the result is that the user is logged in to their SAPGUI session, and a message at the bottom of the SAPGUI screen informs you of the SSO success: In this screenshot, the magenta rectangle covers the SAP system-client number and the SAP User ID for that system-client, while the green rectangle covers the MARMOT@AD.BURROW identifier. So, that’s how SSO for SAPGUI using Kerberos happens, when all the various config is correct on: the SAP system itself, the Active Directory, the KDC, the MacBook, the SAPGUI app, and the SAP Secure Login Client. “Easy… what could possibly go wrong?!” 😂… well, we will see how one innocent change to the way MacBook receives and stores Kerberos Tokens, introduced to improve the SSO-for-browsers user-experiences, can inadvertently break this SSO for SAPGUI workflow… More Than One Kerberos TokenNowadays one of the main use cases for SSO in organisations is to authenticate to various web services using a browser. For example, it’s quite common that for SAP Fiori Launchpads, the authentication is done via Microsoft Entra ID (which used to be called Azure Active Directory). There are of course other companies providing similar authentication services, but we will follow our Entra ID example.So this is fine, but: Entra ID has its own separate Kerberos Realm, so it does not itself use the Kerberos Token supplied by our (on-premise) Kerberos server for Realm AD.BURROW; so for the MacBook users in our organisation it means that – per browser session- the user would have to login (via Entra ID) to some web service such as a Fiori Launchpad i.e. specifying username and password, and maybe also using (say) the Microsoft Authenticator mobile app to perform a 2FA manual login. Which is not really SSO anymore, when the user has to do these extra manual logins in addition to their initial device or network login.So our MacBook and Identity Management teams came up with a good idea: a certain Microsoft service for MacBook gets installed and configured on the local device (we skip the details, other than to say that this service is Microsoft Azure-centric); then when the user logs in to their device, the service can go and fetch (via Azure) two Kerberos Tokens (even if the device isn’t currently on the organisation’s “on-premise” network): first, a Kerberos Token for the Entra ID user, let’s call it:username@example.com@KERBEROS.MICROSOFTONLINE.COMThe Realm here is the actual Realm used by Entra ID to provide Kerberos. And this Azure-supplied Kerberos Token becomes – on the MacBook device – the Default Token in the Credentials Cache.In addition, the old-school Kerberos Token for (say) the AD.BURROW Realm is fetched,  via integrations between Azure and our on-premise Active Directory. This Token is also stored in the Credentials Cache, though it is just an “ordinary” Token (and specifically not the Default Token). Ticket Viewer shows both Tokens in the Cache:Now, this is generally a good thing – for the web services that prefer Entra ID to handle authentication, the browsers (Safari, Chrome, Edge tested) are able to ask the MacBook for the username@example.com@KERBEROS.MICROSOFTONLINE.COM Ticket Granting Token stored in the local Credentials Cache, and so when the user goes to, e.g. some SAP Fiori Launchpad* or some Jira Project page belonging to the organisation, SSO happens (via the Azure-based Kerberos server’s TGS, and so on) and the user doesn’t need to do manual login to those websites. So that’s a real improvement in the users working lives.[*Note that for services located on your on-premise network which are not configured for public Internet access, you still need to be yourself connected to the on-premise network to access those services, e.g. on the office LAN or via a VPN connection – even if you have SSO working. Remember kids: SSO automates login workflows, but it doesn’t create its own “additional” VPN tunnel through your firewall… maybe you already know this, but in my experience many people don’t yet know this, so FYR].The only downside to having these two Kerberos Tokens, where the Token for the AD.BURROW Realm isn’t the Default Token, is that, well, SSO for SAPGUI doesn’t work in this scenario anymore (though this blog will later explain how to get it working again). The reason for failure is that SAP Secure Login Client is only aware of the Default Token in the local Credentials Cache, so it finds only the Token for KERBEROS.MICROSOFTONLINE.COM – but because this Azure-based Kerberos server doesn’t know anything about the SPN (say) SAPServiceDDD defined within an entirely different Kerberos Realm (and what the server does not know, it certainly will not trust), so it is not going to be able to grant a Ticket for the relevant SAP Service (e.g. SAP System DDD)… and so the logon attempt to DDD over SAPGUI fails, probably with the following error message:Well, that’s annoying. So we need solutions which allow us to keep both Kerberos Tokens in the local Credential Cache, but for the Default Token to be the one for the on-premise, AD-based Kerberos Realm.Below we describe three solutions. I have tested that they work, including testing that for the websites using the Azure-based Kerberos Token, those continue to work even when that Azure-based Kerberos Token loses its “Default” status in the local Credentials Cache. Disclaimer: if these solutions don’t work for you, then you will need to find your own solutions, as I don’t run any Helpdesk in my spare time, and won’t in future either 😂 .[A fourth possible solution would be if the Microsoft service on the MacBook could do the needed swapping of the Default Token at fetch-and-store-time, but as I have solved the issue on client-device side already using the below solutions, so I haven’t investigated this possibility].It’s a good idea to close SAP Secure Login Client and close SAPGUI for Java for MacBook before applying any of the manual solutions, to ensure that old Token info isn’t left in the caches of these apps. One way is to right-click on their respective icons in the Dock, and choose “Quit”. Or: in the top menu of the SAPGUI app, choose SAPGUI -> Quit SAPGUI; and in the wee icon in the right-hand side of MacBook top menu bar, for SAP Secure Login Client (white tick on blue diamond), click on the icon and choose Quit SAP Secure Login Client. Solution 1 – Use Ticket Viewer to Change Default TokenOpen Ticket Viewer – e.g. via Spotlight (<command> + <space-bar>) then typing “ticket” and double-clicking on Ticket Viewer – then click on the Token you want to set as the Default Token so that it is highlighted (blue background denotes highlighted item). In our example, we highlight the Token for AD.BURROW …Then click on the button called “Set as Default”:And, well… that’s all you need to do!Ticket Viewer doesn’t tell you that this action has succeeded, and has no marker identifying the current Default Token in the list, but I have tested that the button works fine. Now you can open SAPGUI app and logon via SSO using in our AD-based Kerberos Token (SAPGUI app will open SAP Secure Login Client when needed).”So you wrote this long blog just to tell us about such a simple solution??” …well, it’s simple enough once you realise that it’s a solution, but realising what to do is tricky unless you have understood the root cause of the issue. The good thing about this solution using Ticket Viewer is it is quite easy to use. The disadvantage is that each user needs to remember to do this manual solution every time they login to their device, and before they open the SAPGUI app. Which is why I developed a better solution (“Solution 3”, below in this blog) that doesn’t require the users to implement this Ticket Viewer solution. Though the manual solution remains as a good fallback option in case a more complex solution doesn’t work. During the research for a better solution, I found an interim solution (“Solution 2” below) that i might use myself, but most users wouldn’t use – anyway the next section describes this Terminal app solution… Solution 2 – Terminal app, klist, and kswitcherBecause I wanted to automate the solution that uses Ticket Viewer, well, one way to do that is to first work out what happens at command-line level when a user presses the “Set as Default” button in the Ticket Viewer app (and once this is known, use a script and config file to further automate). So I found the relevant commands… to use them, open the Terminal app… the first one is:klistThis command displays the current Default Token from the Credentials Cache. But we would like to see a list of all Kerberos Tokens in the cache, for that we should use:klist -l[The option is the lowercase “L”, abbreviation of “list-all”, and not the numeral “1”]. In the results command, the current Default Token is denoted by the relevant item having an asterisk character ‘*’ as the first string at the start of its line, shown in this heavily redacted screenshot in the magenta box: To change the default, the easy way is to use the command:kswitch -i[“i” for “interactive”].This lists all the Tokens in the cache with line numbers, and asks you to choose the line number of the Token you want to be set as default. So you choose the number, e.g. of the line for AD.BURROW Token in our blog example – so that is line 2 from the above screenshot – and then you can check (using ‘klist -l’ again) that the relevant Token was indeed set. Now you can open SAPGUI app and logon to SAP using SSO. Solution 3 – A script and a plist fileThis works for me just fine – feel free to base your own solutions on my templates, but remember kids, I am not going to offer any debug help if this doesn’t work for you.So the idea is to have a script, which runs at user login to the MacBook, and the script assumes that during the first 30 seconds after user login, the computer retrieves some Kerberos Tokens and sets the Azure-based Token as Default – so that when the script discovers those Tokens, it can if needed set the AD-based Token to be Default.[The reason I mention this assumption, is that it may not be true in your organisation. For example, it could be that all the Kerberos Tokens for your user+device combination are only fetched later, e.g. once the user connects to a VPN – in such a case, you would need some way of running this script once some system or program event is recognised, or by some other method like a wee GUI app or whatever. And since that “delayed fetch”-scenario doesn’t apply to me in my organisation, I haven’t researched the details of that scenario at all. Probably it’s doable though, wishing yous good luck with that].To enable the script to run at login, we define a plist file, which is an XML file. Here is an example file, called com.example.org.kswitcher.plist<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
<!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”>

<plist version=”1.0″>
<dict>
<key>Label</key>
<string>com.example.org.kswitcher</string>
<key>LimitLoadToSessionType</key>
<array>
<string>Aqua</string>
</array>
<key>Program</key>
<string>/Users/Shared/macscripts/userlogin/kswitcher.zsh</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist> It’s important to make sure that the Label string matches the filename minus the “.plist” part. [If you don’t make them match properly, the plist does nothing]. So in our case the correct string is com.example.org.kswitcherThe LimitLoadToSessionType key with value “Aqua” just ensures that this plist is only “active” for GUI-based user login sessions (i.e. the typical situation, not remote SSH login). Then the Program key specifies where our special custom-built kswitcher.zsh script is located. And the RunAtLoad key just means that the specified Program should run when the user logs in.So for the relevant user, this plist file goes in their home directory:~/Library/LaunchAgents…the “~” means the home directory of the current user (so the target LaunchAgents directory is in the Library directory of the user, and not in the Library directory of the device).Ok, so the plist file is in the right place – being in the user’s LaunchAgents directory, the plist will be run next time the user logs in to their device. Now what about the kswitcher.zsh script that the plist will run? First you create the directory that matches where the plist will look for the script, so for example:mkdir -p /Users/Shared/macscripts/userloginThen you put the script in that subdirectory, and change the permissions of the script so that any logged-in user can run it, for example:chmod 775 /Users/Shared/macscripts/userlogin/kswitcher.zshHere is the template for kswitcher.zsh – obviously you would swap in your own Realm in case it is not the same as in the blog example (where we use AD.BURROW). BTW I am not saying this is the best code ever, only that it worked well enough for me – feel free to develop your own version from any clues in this script…#!/bin/zsh
###################################################################
# dylan drummond, helsinki #
# 26.11.2025 – 12.01.2026 (dd.mm.yyyy) #
# Licensed under: https://creativecommons.org/licenses/by-nc/2.5/ #
###################################################################

###################################################################
# This script switches the default Kerberos credentials to be #
# those for the AD.BURROW realm, so that Secure Login Client #
# picks up the correct Kerberos Token. #
###################################################################

# Add a log-entry:
date >> /Users/Shared/macscripts/userlogin/kswitchlog
echo “kswitcher script running…” >> /Users/Shared/macscripts/userlogin/kswitchlog
# counter=0

# At interval of 0.5 seconds (half a second), up to around 30 seconds from login, check to see if kswitch can be done:
repeat 60 {
# counter=$((counter+1))
# date >> /Users/Shared/macscripts/userlogin/kswitchlog
# echo “klist iteration: ” $counter >> /Users/Shared/macscripts/userlogin/kswitchlog

# Get the output of ‘klist -l’
OURKLISTL=”$(klist -l)”
ADSTR=”$(echo $OURKLISTL | grep AD.BURROW)”
ADTOKEN=”$(echo $ADSTR | awk ‘{print $1}’)”

# If empty, wait 0.5 seconds before retry (use ‘continue’ to skip to next loop iteration):
if [ -z $ADTOKEN ]
then
sleep 0.5
continue
fi

# We check whether the default Kerberos Token is already the AD-based one,
# i.e. if the ADTOKEN contains an asterisk instead of the actual Kerberos Token.
# In that case there is nothing to do so we can exit 0 i.e. exit with success return code…
if [ “$ADTOKEN” = “*” ]
then
date >> /Users/Shared/macscripts/userlogin/kswitchlog
echo “Nothing to do as AD.BURROW credentials are already the default… Bye!” >> /Users/Shared/macscripts/userlogin/kswitchlog
exit 0
fi

# We assume that if we got to this point, we have the string matching the relevant credential in ADTOKEN,
# …because if the Kerberos Token is not the default, that Token will be the first string retrieved into ADTOKEN.
# So we can kswitch:
kswitch –principal=$ADTOKEN

# We need to check that this has worked:
if [ $? -ne 0 ]
then
date >> /Users/Shared/macscripts/userlogin/kswitchlog
echo “Before SAPGUI usage: Open Ticket Viewer app from Spotlight and set AD.BURROW Token as default using the button!”
>> /Users/Shared/macscripts/userlogin/kswitchlog
exit 1
fi
date >> /Users/Shared/macscripts/userlogin/kswitchlog
echo “kswitcher ran successfully!” >> /Users/Shared/macscripts/userlogin/kswitchlog
exit 0

}
# Ended repeat loop

#If we got through that repeat loop, that should mean no AD.BURROW Token was found via ‘klist -l’:
date >> /Users/Shared/macscripts/userlogin/kswitchlog
echo “No Kerberos Token found for Realm AD.BURROW, so we cannot set non-existent token to be default credential.” >> /Users/Shared/macscripts/userlogin/kswitchlog Once you have the automated solution set up (plist and script in correct locations and file permissions set), so you can log out of your MacBook, then login again and check if the solution works e.g. from the logfile, before opening SAPGUI app and unit-testing. You can see from the template that the script runs for up to 30 seconds and uses some kind of primitive Watcher-pattern, checking every half a second for Kerberos Tokens – and if they are found, attempting to kswitch the relevant Token to be the Default Token:kswitch –principal=$ADTOKEN[Note the two hyphens before “principal”, as this option specified using the full name of the option. Unlike in Solution 2, we don’t use ‘kswitch -i’, because in the script we want to avoid making the user interactively choose a Default Token].So, good luck if you choose to use this Solution 3 with plist and script as a way to automate Solution 1 using Ticket Viewer. If it doesn’t work, good luck in your attempts to make it work; but remember that you can always fall back to using Ticket Viewer and the “Set as Default” button as a manual solution. Anyway remember to ensure that both SAPGUI app and SAP Secure Login Client are closed until some solution has been applied, so that when they are opened they will use the new Default Token that you set.Although I have tested that this template version of the script runs ok (no syntax errors), in reality I have no such Kerberos Token for the imaginary AD.BURROW Realm, so it wasn’t a very comprehensive test: the logfile recorded an entry about no such Token for that Realm found, so the expected results matched the actual results 😂…however, this template was made by replacing (in a copy of the original script) the actual Realm used in my organisation, and I have tested that original script successfully: it’s working every day I login to my device, thanks to the plist that ensures the original script runs at login. Also you can see some commented-out commands that I used when building and testing the script (so I could find out roughly how many seconds my device took to fetch the Kerberos Tokens and put them in the Credentials Cache – usually about 5 seconds). Left them in the script as comments, as a reference in case you want to do similar logging of the loop iterations.    Read More Technology Blog Posts by Members articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author