“GSSException Defective token detected” - when trying to Authenticate to Tomcat running on Windows using Kerberos

前端 未结 2 1296
无人及你
无人及你 2020-12-28 18:20

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

相关标签:
2条回答
  • 2020-12-28 18:42

    The error “Defective token detected” likely means that an ntlm token was detected. That’s what the Negotiate mechanism uses inside popular web browsers if kerberos fails - when not instructed by the web server otherwise.  On windows operating systems, the IE web browser on it (and Firefox, if configured correctly) basically says, if you won’t do Kerberos, I’m going to send you an NTLM token.  And the server replies “no way” I don’t even know NTLM so I’m calling what you sent me defective.  Since you seem to be setting this up for the first time, you likely did not configure any fallback mechanism (such as NTLM) for when Kerberos fails, therefore, that error message. We solve this by understanding why Kerberos is failing.  I think I see the reason for the failure in your question, in two places, related to SPNs and Trusted Sites. Even if you resolve those two items, there is a third reason and fourth reason why it could continue to fail, related to encryption.

    1. The spn for the HTTP service does not match the URL entered by the browser. These need to match, otherwise Kerberos will fail. To work, the browser should be using: http://kerberos500.nickis.life:8080, not http://nickis.life:8080. I say that based on what I saw in your keytab creation syntax. In that you’ve coded the SPN as such: HTTP/kerberos500.nickis.life@NICKIS.LIFE. That’s why you need to use http://kerberos500.nickis.life:8080. The browser won’t know how to get to your web service when you tell it to go to http://nickis.life:8080. With that top URL, the browser assumes it needs to find a web service running on your Active Directorydomaincontroller (anything with just nickis.life is assumed to run on the Domain Controller). DCs should never run web servers for security reasons.
    2. You’ll need to add http://kerberos500.nickis.life as a Trusted Site under IE settings. Alternatively, *.nickis.life would work as well. (You called it Trusted Roles, when it’s actually called Trusted Sites).
    3. You are restricting the Kerberos encryption type to DES-CBC-MD5. Starting with Windows Server 2008 Active Directory R2, DES is disabled by default. DES is an outdated and generally insecure encryption type these days. Much better to use AES128 or even better, AES256. You can fix that by re-generating the keytab per my example below.
    4. In the AD user account kerberos500, go to the Account tab, scroll to the bottom, and check all the boxes for DES, AES 128, and AES 256, and OK you’re way out of the dialog boxes. You must check these boxes even if you did everything right above, or else Kerberos authentication will still fail.

    How to properly re-generate the keytab: You should not run the setspn -a command to add an SPN to an AD user whenever you are planning to make a keytab associated with that user account.  The reason why is because the keytab creation command adds the SPN to the user account as part of the command.  If your scenario doesn’t work after following my advice above, then you’ll need to remove the SPN via setspn -D like below:

    setspn -D HTTP/nickis.life@NICKIS.LIFE kerberos500
    

    And the re-generate the keytab afterwards, my only change is that I told it to use all encryption types. The client and server will agree on the strongest common one during the authentication process. 

    ktpass -out c:\Users\Administrator\kerberos500.keytab -princ HTTP/nickis.life@NICKIS.LIFE -mapUser kerberos500 -mapOp set -pass XXXXpasswordforkerberos500userXXXX -crypto ALL -pType KRB5_NT_PRINCIPAL
    


    Then replace the old keytab with the new one. For additional in-depth information on keytabs, you can read more from my technical article on how to create Kerberos keytabs here: Kerberos Keytabs – Explained. I frequently go back and edit it based on questions I see here in this forum.

    By the way, HTTP/kerberos500.nickis.life is a service principal, not a user principal as you wrote in your question. I only use web browsers to test Kerberos in HTTP scenarios like this one, I don’t use cURL.

    I am positive if you diligently go through all four points I’ve highlighted above, you will resolve this problem.

    EDIT1: This answer assumes you have an HTTP service running on a host with the fully-qualified domain name of kerberos500.nickis.life. If you don't have such a host with that name, my answer will slightly change. Please let me know if any.

    EDIT2: To achieve the objective of authentication using the URL of http://nickis.life:8080, then you may keep on using the same keytab you already created.

    On the AD account NICKIS\kerberos500, go to the Account tab, scroll to the bottom, and check the box for "Use Kerberos DES encryption types for this account".

    Then enable DES encryption itself at the AD domain level via Group Policy. To do that, conduct the following:

    1. Open up Group Policy Management Console (GPMC).
    2. Edit Default Domain Policy GPO. (Its safer to create a new domain-level GPO instead and edit that, but that's up to you).
    3. Navigate to Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options > “Network Security: Configure Encryption types allowed for Kerberos” and check the both checkboxes for DES_CBC_MD5 and DES_CBC_MD5. IMPORTANT: In that same Group Policy, also ensure the checkboxes for RC4, AES128, and AES256 are also checked. Those encryption types won't be used for tickets to your web site, but they will for everything else in the domain. and OK you're way out of the dialog boxes and close the GPMC.
    4. Run the 'gpupdate /force' command on both the DC server and the client.
    5. Run 'klist purge' on the client to purge all Kerberos tickets.
    6. In the web browser, clear the cache and delete all cookies.
    7. Ensure that the DC server allows port 8080 TCP inbound.
    8. Try it again.

    Reference: Windows Configurations for Kerberos Supported Encryption Type

    EDIT 3: Avoid running Kerberos KDC (the DC), client and server on the same machine. That is a classic recipe for getting the "Defective token error" even if you've done everything else right.

    EDIT 4: (Final update which was verified by the OP): Looked at the new ktpass keytab creation output, and I saw this: Targeting domain controller: WIN-OVV6VHBGIB8.fusionis.life. Now, the defined SPN in the keytab is HTTP/kerberos500.nickis.life. The AD domain name is different from the SPN you defined, so this is not going to work unless you have some kind of trust setup between these domains. If you don't have a trust, you need to use an SPN of HTTP/kerberos500.fusionis.life instead.

    0 讨论(0)
  • 2020-12-28 18:57

    Try this:

    Solution 1

    run this on windows cmd:

    ksetup /addkdc ksetup /addhosttorealmmap

    and set SPNEGO settings on browser

    Solution 2

    try with Firefox, do this before:

    1) open this URL in Firefox

    about:config

    2) Set this: network.negotiate-auth.trusted-uris

    Set for any cluster DNS domain requiring negotiated authentication (like the kerberos enabled cluster HTTP authentication).

    Example:

    network.negotiate-auth.trusted-uris=.lily.cloudera.com,.solr.cloudera.com

    2) Set this: network.auth.use-sspi=false 3) Restart Firefox 4) You have to download the Windows isntaller from here:

    http://web.mit.edu/kerberos/dist/#kfw-4.0

    5) Copy the Kerberos client configuration to here

    C:\ProgramData\MIT\Kerberos5\krb5.ini

    6) Create a ticket with the MIT kerberos GUI client

    7) Try again with Firefox

    Hope it can help.

    0 讨论(0)
提交回复
热议问题