EvilOrange
EvilOrange

Reputation: 926

Tomcat 8 and Windows NTLM authentication for non-domain user

We have Tomcat 8 application with configured Windows Authentication (IWA) with SPNEGO authenticator, keytab and SPN. It works fine for domain users - they are authenticated without prompting user and password using Kerberos. For non-domain users we would like to allow authentication by entering user name and password using native browser popup. It seems, that tomcat should use NTLM for that case. Hovewer, when non-domain user enters login and password to browser popup - it reappears and there is exception in tomcat log:

2017-01-24 05:15:46,910 [http-nio-127.0.0.1-8455-exec-9] DEBUG org.apache.catalina.authenticator.SpnegoAuthenticator- Unable to login as the service principal
java.security.PrivilegedActionException: GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
                at java.security.AccessController.doPrivileged(Native Method)
                at javax.security.auth.Subject.doAs(Subject.java:422)
                at org.apache.catalina.authenticator.SpnegoAuthenticator.authenticate(SpnegoAuthenticator.java:230)
                at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:577)
                at com.avaya.cas.auth.authenticator.IViewTokenAuthenticator.invoke(IViewTokenAuthenticator.java:212)
                at com.avaya.cas.ssl.valves.SSLValve.invoke(SSLValve.java:84)
                at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
                at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
                at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:240)
                at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:676)
                at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
                at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
                at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
                at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
                at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1527)
                at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1484)
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
                at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
                at java.lang.Thread.run(Thread.java:745)
Caused by: GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
                at sun.security.jgss.GSSHeader.<init>(GSSHeader.java:97)
                at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:306)
                at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
                at org.apache.catalina.authenticator.SpnegoAuthenticator$AcceptAction.run(SpnegoAuthenticator.java:323)
                at org.apache.catalina.authenticator.SpnegoAuthenticator$AcceptAction.run(SpnegoAuthenticator.java:310)
                ... 20 more

There is piece ofcode of GSSHeader:

int var2 = decodedHeader.read();
        if(var2 != 96) {
            throw new GSSException(10, -1, "GSSHeader did not find the right tag");

in my case var2 is 78 ('N' char) decodedHeader- is a standart first NTLM message, which is send from browser in Authorization header. In my case it is:

Authorization:Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKADk4AAAADw==

After decoding it will be something like 'NTLMSSP...binary data...'. So, first byte of this message is always 'N'(78) but not 96, as Tomcat's code expected.

Does Tomcat support NTLM authentication? It's very strange, since Domain users can be authenticated(it means that Tomcat could decrypt challenge from user using provided keytab)

Upvotes: 1

Views: 1808

Answers (1)

Michael-O
Michael-O

Reputation: 18415

Donator of the SPNEGO code here.

GSSHeader did not find the right tag

means that no SPNEGO token has been sent by the client; you receive a pure NTLM token. This happens when Kerberos fails for some reason which is your case.

NTLM is very different and very proprietary. In this case the server acts as a middle man to pass the hashes from the client to a domain controller. The server cannot very anything itself. There is no way that Tomcat can decrypt anything without the help of a domain controller. Also, there is no known NTLM server-side implementation which is available as open source (especially not in Java), except Samba's internal code.

Upshot: forget about NTLM and do what I recommend here.

Note: there is IAKERB for such a scenario, but only MIT Kerberos and at most Heimdal support it.

Upvotes: 2

Related Questions