I am struggling to authenticate to a Java web container (I've tried both Tomcat and Jetty) when running on Windows 2012.
Every time I try the Negotiate auth scheme I get an error: org.ietf.jgss.GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
Steps to reproduce
Start out by setting up a Windows Server 2012 or 2016 instance and install active directory domain services.
In my example, I created:
NETBIOS Domain: NICKIS
Dns domain: nickis.life
Create the kerberos subject user on Active Directory
IMPORTANT: MAKE SURE THAT THE FIRST NAME, LAST NAME AND FULL NAME ARE THE SAME!
The new user in my case is:
DN = CN=kerberos500,CN=Users,DC=nickis,DC=life
login+domain = kerberos500@nickis.life
NETBIOS\samAccountName = NICKIS\kerberos500
Run the setspn command from the Windows Active Directory Server
setspn -A HTTP/nickis.life@NICKIS.LIFE kerberos500
Example output:
C:\Users\Administrator>setspn -A HTTP/nickis.life kerberos500
Checking domain DC=nickis,DC=life
Registering ServicePrincipalNames for CN=kerberos500,CN=Users,DC=nickis,DC=life
HTTP/kerberos500.nickis.life
Updated object
Run the ktpass command from the Windows Active Directory Server
ktpass -out c:\Users\Administrator\kerberos500.keytab -princ HTTP/nickis.life@NICKIS.LIFE -mapUser kerberos500 -mapOp set -pass XXXXpasswordforkerberos500userXXXX -crypto DES-CBC-MD5 -pType KRB5_NT_PRINCIPAL +DesOnly
Example output:
C:\Users\Administrator>ktpass -out c:\Users\Administrator\kerberos500.keytab -princ HTTP/nickis.life@NICKIS.LIFE -mapUser kerberos500 -mapOp set -pass xxxxxxxx -crypto DES-CBC-MD5 -pType KRB5_NT_PRINCIPAL +DesOnly
Targeting domain controller: WIN-OVV6VHBGIB8.nickis.life
Using legacy password setting method
Successfully mapped HTTP/kerberos500.nickis.life to kerberos500.
Key created.
Output keytab to c:\Users\Administrator\kerberos500.keytab:
Keytab version: 0x502
keysize 71 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 3 etype 0x3 (DES-CBC-MD5) keylength 8 (0xcd07200bea625d20)
Account kerberos500 has been set for DES-only encryption.
At this point, you will now have a keytab file:
c:\Users\Administrator\kerberos500.keytab
And a user principal:
HTTP/kerberos500.nickis.life@NICKIS.LIFE
These are the 2 inputs that are needed to provide to the GSSApi to get single sign on with Kerberos.
So I deployed those inputs to my web container's kerberos security realm in the Hadoop security module.
Curl test I tried unsuccessfully to use curl to test it:
curl --negotiate -u : http://nickis.life:8080/my/webapp
Internet Explorer test I also tried using Internet Explorer. I added nickis.life
domain to the Trusted Roles in Internet Explorer. Then I launch the site in internet explorer: http://nickis.life:8080
Either way, I get the error below:
org.apache.hadoop.security.authentication.client.AuthenticationException: GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler.authenticate(KerberosAuthenticationHandler.java:398) ~[hadoop-auth-2.7.1.jar:?]
...
Caused by: org.ietf.jgss.GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
at sun.security.jgss.GSSHeader.<init>(Unknown Source) ~[?:1.8.0_131]
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) ~[?:1.8.0_131]
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source) ~[?:1.8.0_131]
at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler$2.run(KerberosAuthenticationHandler.java:365) ~[hadoop-auth-2.7.1.jar:?]
at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler$2.run(KerberosAuthenticationHandler.java:347) ~[hadoop-auth-2.7.1.jar:?]
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_131]
at javax.security.auth.Subject.doAs(Unknown Source) ~[?:1.8.0_131]
at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler.authenticate(KerberosAuthenticationHandler.java:347) ~[hadoop-auth-2.7.1.jar:?]
I am stumped. NOTE: I have found several links around here and there but none of them were all inclusive on the steps that were followed like I have summed up here, and none of the solutions provided within worked for me.
- I am attempting kerberos login from a different machine on the domain than the server is running on
- I have tried all sorts of combinations of keytab generation variations none have worked.
- There is no duplicate SPN.
- I tried setting up the DNS in the domain server as an
A
record. - I wonder maybe if there's some kerberos windows server setup steps and Microsoft employee verified that this should not be the case here: https://social.msdn.microsoft.com/Forums/sharepoint/en-US/db15ad96-e269-436e-952f-fe9dfb39da8a/setting-up-a-test-windows-server-active-directory-for-kerberos-testing?forum=winserverDS
Can anyone trace what I am screwing up here?
UPDATE:
- I have AD server with domain set to
fusionis.life
, and the AD server isWIN-OVV6VHBGIB8.fusionis.life
- I moved the tomcat server to another windows machine in the domain.
DESKTOP-VTPBE99.fusionis.life
- I opened
dnsmgmt.msc
and added a "Forward Lookup Zone" with "kerberos500.nickis.life" with A HOST set to the IP of theDESKTOP-VTPBE99.fusionis.life
box. - I deleted the AD account, recreated it, then re-generated the keytab again as suggested in one of the answers on the ticket.
C:\Users\Administrator>ktpass -out c:\Users\Administrator\kerberos500.keytab -princ HTTP/kerberos500.nickis.life@NICKIS.LIFE -mapUser kerberos500 -mapOp set -pass xxxxxxxxx -crypto ALL -pType KRB5_NT_PRINCIPAL
Targeting domain controller: WIN-OVV6VHBGIB8.fusionis.life
Using legacy password setting method
Successfully mapped HTTP/kerberos500.nickis.life to kerberos500.
Key created.
Key created.
Key created.
Key created.
Key created.
Output keytab to c:\Users\Administrator\kerberos500.keytab:
Keytab version: 0x502
keysize 67 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 4 etype 0x1 (DES-CBC-CRC) keylength 8 (0x04e30b9183ba8389)
keysize 67 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 4 etype 0x3 (DES-CBC-MD5) keylength 8 (0x04e30b9183ba8389)
keysize 75 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 4 etype 0x17 (RC4-HMAC) keylength 16 (0xe39a141de38abd8750bf9c0bf49fd1c5)
keysize 91 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 4 etype 0x12 (AES256-SHA1) keylength 32 (0xe368a1b060cfe4816f522c1c5f62ca07fe201ed96c6d018054dfbd5b86251892)
keysize 75 HTTP/kerberos500.nickis.life@NICKIS.LIFE ptype 1 (KRB5_NT_PRINCIPAL) vno 4 etype 0x11 (AES128-SHA1) keylength 16 (0x1b1a548fa2893a78c6f4c7f9c482b614)
I saved the keytab updated file on the server, then updated the Service Principal to
HTTP/kerberos500.nickis.life@NICKIS.LIFE
I logged into tomcat machine as a domain user, added http://kerberos500.nickis.life to the trusted sites, then navigated to http://kerberos500.nickis.life:8764
I checked all combinations of the encryption check boxes in the kerberos500 AD "account" tab.
Now i'm getting a new error...
GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos credentails)
UPDATE:
Resolved finally. I got this final error because I needed fusionis.life
to be on the same host as nickis.life