Openfire and Spark - SSO on Windows 2016 server and Windows 10 client

Hi all! I’ve been trying to configure a new installation of Openfire v4.4.4 to support SSO. After days of Googling and reading this forum I’ve decided to open a topic about the issue. Over the past 10+ years there have been multiple posts on this topic with various solutions. I’ve read all these and tried them but unfortunately, I couldn’t solve my issue. Hopefully someone here can help me out!

Environment:
DC (Name: srv-dc02): Windows Server 2016 Standard with 2008R2 functional level (there are 3 DCs in the forest, one of them is still 2008 R2)
Openfire server (Name: srv-chat01): Windows Server 2016 Std with a remote MSSQL database server. The installed Openfire version is 4.4.4 with integrated Java (install path: E:\Openfire)
AD Domain: domain.local
Public DNS domain (split DNS, all DCs are zone masters internally): public.hu

Authentication was working before I attempted to configure SSO.

Steps:

  1. Created DNS records: chat.domain.hu CNAME srv-chat01.public.hu and the following SRV records (as the Admin Console suggested):
    _xmpp-client._tcp.chat.public.hu IN SRV 0 5 5222 srv-chat01.domain.local
    _xmpp-server._tcp_chat.public.hu IN SRV 0 5 5269 srv-chat01.domain.local
    _xmpps-client._tcp.chat.public.hu IN SRV 0 5 5223 srv-chat01.domain.local
    _xmpps-server._tcp.chat.public.hu IN SRV 0 5 5270 srv-chat01.domain.local
    There is a reverse DNS record for the server, which points to srv-chat01.domain.local
  2. Created the AD accounts. _svc_openfire is used to query LDAP and access the database, and _openfire_keytab is used for the SPN records. Both are regular domain users and the passwords never expire. The keytab account has “This account supports Kerberos AES 128bit encryption” and “Do not require Kerberos preauthentication” checked.
  3. Created SPN records for the keytab account. Setspn –L shows the following SPNs: xmpp/chat.public.hu, xmpp/srv-chat01.domain.local, xmpp/chat.public.hu@domain.local
  4. Exported the keytab with ktpass with “-crypto all” and “-ptype KRB5_NT_PRINCIPAL”. Also tried this step with the ktab.exe on the Openfire server, which did not make a difference.
  5. Added the allowtgtsession REG_DWORD key on both the server and the client. (Also tried with REG_SZ as some documentation said it’s not DWORD).
  6. Disabled Virtualization Based Security in local policy (Administrative Templates -> System -> Device Guard) on both the server and the client
  7. In the Openfire Admin Console, I’ve added the required System Properties: sasl.gssapi.config: E:\Openfire\conf\gss.conf, sasl.gssapi.debug: true, sasl.gssapi.useSubjectCredsOnly: false, sasl.mechs: GSSAPI, sasl.realm: DOMAIN.LOCAL
  8. Created krb5.ini, placed it in C:\Windows on the Openfire server. Also created the gss.conf file and placed it in E:\Openfire\conf folder.

krb5.ini:
[libdefaults]
default_realm = DOMAIN.LOCAL
dns_lookup_realm = false
[realms]
DOMAIN.LOCAL = {
kdc = srv-dc02.domain.local
admin_server = srv-dc02.domain.local
default_domain = domain.local
}
[domain_realms]
domain.local = DOMAIN.LOCAL
.domain.local = DOMAIN.LOCAL

Also tried adding a few values to this file like ticket_lifetime, renew_lifetime, default_ccache_name but these did not make any difference either.

gss.conf:
com.sun.security.jgss.accept {
com.sun.security.auth.module.Krb5LoginModule
required
storeKey=true
keyTab=“E:/Openfire/resources/openfire.keytab”
doNotPrompt=true
useKeyTab=true
isInitiator=false
realm=“DOMAIN.LOCAL”
principal=“xmpp/chat.public.hu@DOMAIN.LOCAL”
debug=true;
};

If I start Spark with administrative rights on the client and enable SSO, the username and account fields are populated automatically.

When I fill the domain field with chat.public.hu login fails. The following error message is display in the Spark client warn log:

dec. 04, 2019 9:29:07 DE org.jivesoftware.spark.util.log.Log warning
WARNING: Exception in Login: org.jivesoftware.smack.sasl.SASLErrorException: SASLError using GSSAPI: not-authorized at org.jivesoftware.smack.SASLAuthentication.authenticationFailed(SASLAuthentication.java:365) at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1052) at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:956) at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:971) at java.lang.Thread.run(Unknown Source)

what do you have your xmpp.domain set to in openfire?

It is set to chat.public.hu. I believe it was set during the setup process.

Its been a while since I’ve messed with this. have you seen this video? How To: Video on setting up SSO/AD with Openfire

Yes! This is the first one I checked, I based the entire config on it. :slight_smile: Unfortunately, it did not work as expected, though the error message was not the same as the one I get now. That’s when I started browsing through every post mentioning SSO here and got to the “not-authorized” message which I didn’t find a solution to.

id suggest deleting the spn and recreate it. then recreate your keytab. If that doesn’t work, let me know and perhaps we could screenshare/teamviewer.

I’ve deleted all the SPNs:
setspn -D xmpp/chat.public.hu _openfire_keytab
setspn -D xmpp/srv-chat01.domain.local _openfire_keytab
setspn -D xmpp/chat.public.hu@domain.local _openfire_keytab

If I recreate only one (just like in the video), Spark can no longer determine the username on the client:
setspn -S xmpp/chat.public.hu@DOMAIN.LOCAL _openfire_keytab

ktpass -princ xmpp/chat.public.hu@DOMAIN.LOCAL -mapuser _openfire_keytab@domain.local -crypto AES128-SHA1 -pass * -ptype KRB5_NT_PRINCIPAL -out openfire2.keytab
Targeting domain controller: SRV-DC02.domain.local
Using legacy password setting method
Successfully mapped xmpp/chat.public.hu to _openfire_keytab.
Type the password for xmpp/chat.public.hu:
Type the password again to confirm:
Key created.
Output keytab to openfire2.keytab:
Keytab version: 0x502
keysize 61 xmpp/chat.public.hu@DOMAIN.LOCAL ptype 1 (KRB5_NT_PRINCIPAL) vno 6 etype 0x11 (AES128-SHA1) keylength 16

It can only determine the user if I use -crypto all in the ktpass export.

And I’ve got a new error message. (Which I have seen previously)

dec. 04, 2019 2:50:46 DU org.jivesoftware.spark.util.log.Log warning
WARNING: Exception in Login:
org.jivesoftware.smack.SmackException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7))]
at org.jivesoftware.smack.sasl.javax.SASLJavaXMechanism.getAuthenticationText(SASLJavaXMechanism.java:123)
at org.jivesoftware.smack.sasl.SASLMechanism.authenticate(SASLMechanism.java:196)
at org.jivesoftware.smack.sasl.SASLMechanism.authenticate(SASLMechanism.java:169)
at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:236)
*at org.jivesoftware.smack.tcp.XMPPTCPConnection.loginNonAnonymously(XMPPTCPConnection.java:373)at org.jivesoftware.smack.AbstractXMPPConnection.login(AbstractXMPPConnection.java:457)
at org.jivesoftware.LoginDialog$LoginPanel.login(LoginDialog.java:1131)
at org.jivesoftware.LoginDialog$LoginPanel.access$900(LoginDialog.java:335)
at org.jivesoftware.LoginDialog$LoginPanel$3.construct(LoginDialog.java:894)
at org.jivesoftware.spark.util.SwingWorker.lambda$new$1(SwingWorker.java:138)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7))]
at com.sun.security.sasl.gsskerb.GssKrb5Client.evaluateChallenge(Unknown Source)
at org.jivesoftware.smack.sasl.javax.SASLJavaXMechanism.getAuthenticationText(SASLJavaXMechanism.java:120)
… 10 more
Caused by: GSSException: No valid credentials provided (Mechanism level: Server not found in Kerberos database (7))
at sun.security.jgss.krb5.Krb5Context.initSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.initSecContext(Unknown Source)
… 12 more
Caused by: KrbException: Server not found in Kerberos database (7)
at sun.security.krb5.KrbTgsRep.(Unknown Source)
at sun.security.krb5.KrbTgsReq.getReply(Unknown Source)
at sun.security.krb5.KrbTgsReq.sendAndGetCreds(Unknown Source)
at sun.security.krb5.internal.CredentialsUtil.serviceCreds(Unknown Source)
at sun.security.krb5.internal.CredentialsUtil.acquireServiceCreds(Unknown Source)
at sun.security.krb5.Credentials.acquireServiceCreds(Unknown Source)
… 15 more
Caused by: KrbException: Identifier doesn’t match expected value (906)
at sun.security.krb5.internal.KDCRep.init(Unknown Source)
at sun.security.krb5.internal.TGSRep.init(Unknown Source)
at sun.security.krb5.internal.TGSRep.(Unknown Source)
… 21 more

this might be the keytab file. did you overwrite your original one or does the new keytab havee a new file name. if new filename, be sure you update your gss.conf

I renamed the old file, and copied the new one with the same name. Then I restarted the Openfire service.

hmm… I dont know. I might suggest starting from scratch. perhaps there was a step missed?

Okay. So I uninstalled Openfire, removed the database, removed both AD accounts and started from scratch, doing everything as it is in the video. This included changing the XMPP domain name and the server FQDN, as well as the SRV records to match those in the video.

Old XMPP domain: chat.public.hu
New XMPP domain: public.hu

Old FQDN: srv-chat01.domain.local
New FQDN: chat.public.hu

Old SRV: _xmpp-client._tcp.chat.public.hu
New SRV: _xmpp-client._tcp.public.hu

I think this did the trick, works as expected. Thank you for your time, speedy!
I will just need to figure out if there’s any way to read TGT Session keys without administrator privileges on the client. Spark is unable to determine the user if it runs without administrative privileges.

2 Likes

Do you know if there are any plans to either move SSO to Windows SSPI (https://issues.igniterealtime.org/browse/SPARK-2042) or implement this change described on the Oracle pages?

https://docs.oracle.com/en/java/javase/11/security/accessing-native-gss-api.html
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6722928
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8210801

It seems like Oracle has made changes to support SSO on new versions of Windows 10 with Credential Guard active, but I don’t understand if implementing this requires to modify Spark/Openfire code, or if it can be done via system properties or gss.conf.

Certainly wouldn’t expect something on Spark side. The project is inactive currently. If changes needs to be done on Openfire side, then there are more chances. Although dev resources are also limited.

Thank you for your reply. :slight_smile: