I'm writing a Meteor.JS application and need to authenticate with an NTLM server. I think I'm most of the way there; my workflow is currently as follows:
Send GET request to server with NTLM Type 1 Message under 'www-authenticate' header,
Receive (401) response with NTLM Type 2 Message under 'www-authenticate' header (looks like 'www-authenticate': 'NTLM TlRMTVN....'),
Send GET request to server with NTLM Type 3 Message under 'www-authenticate' header,
Receive (401) response with header 'www-authenticate': 'Negotiate, NTLM'.
This is where I'm confused; At step 4, I'd expect to receive a 200 OK status based off of everything I've read. However, I instead receive 'Negotiate, NTLM' in the www-authenticate header, which I'm not sure what to do about. Has anyone else experienced this with NTLM? Am I on the right track here, or is this indicative something is totally wrong?
EDIT:
Before anyone asks, yes, I did see this question, but in my case, I have verified the credentials are correct. I'd like to know what exactly triggers the 'Negotiate, NTLM' header.
Are you communicating with an IIS server. The 'Negotiate NTLM' headers are sent to the client by the server when both Kerberos and NTLM are possible and the server wishes to tell the client about that. If you are using an IIS server, you can try by changing the Windows authentication type to NTLM only.
Alternatively, you can enable the Request tracing module on IIS and see the requests being transferred. The log usually has sufficient data for understanding the issue.
Hope this helps.
Related
Just noticed that with Kerberos authentication, client browser always gets a 401 response first (with WWW-Authenticate: Negotiate header) and in next request actual kerberos token is sent for authentication (handled internally by browser).
For first time its fine, but for every subsequent request why this process is repeated ? Once client knows that server support kerberos why dont client stores a cookie to indicate that every time I need to send auth token ?
I understand that the NTLM protocol is designed like this, but want to understand why ?
HTTP is stateless. Unless the server tells the client it should persist a state (via server cookie), the client should never assume anything about the server's intent.
More to the point it's wrong to assume that either party can always do Kerberos. The server originally said it wanted to Negotiate, and Negotiate contains a set of available protocols in preferred order (Kerberos, NTLM, etc.). A client can do Kerberos when it has line of sight to a KDC, but it can do NTLM in any/most circumstances, and it prefers Kerberos.
Additionally, once the client is authenticated the server may respond with a session cookie. The browser doesn't understand the contents, so it has no idea what happened. The server must then always indicate to the browser that it needs to auth up again (via 401 + WWW-Auth).
Let's assume that the client wants to authenticate himself to a HTTP proxy. The proxy is configured with kerberos, and has clearly the service name HTTP/proxy.foo.bar set in it's configs. How does the client know which service name to request the ticket to ? Does it request the ticket to the domain name he's making request to (in this case it is proxy.foo.bar indeed), or does it receive the name in the authentication sequence, in a 407 reply in this case (which doest contain the negotiate challenge, but I just don't know if there's a way to look into it) ?
I'm trying to debug the kerberos errors on a proxy which suddenly stopped authenticating some clients. The thing is, that looking in the Wireshark, I see that the client is requesting a ticket not for a service name configured on a proxy (same name he's instructed to use), HTTP/proxy.foo.bar, but for a name that the proxy IP resolves to, HTTP/host.foo.bar (well, at least it's the name that the proxy resolves to, may be though the client gets it some other way), and TGS just cannot find one, thus an error happens.
So you’ve got two questions in here (you didn't ask how to actually solve the problem, to do that more details would be needed - see comments).
You asked "The proxy is configured with kerberos, and has clearly the service name HTTP/proxy.foo.bar set in it's configs. How does the client know which service name to request the ticket to?"
A. It works pretty much like this. The client types in a URL in the web browser or clicks on a hyperlink. It looks up the IP host in DNS domain which matches the host name in the URL. Then it goes to that IP host, looking for the service defined in the URL, in this case it is the HTTP service. If it receives an HTTP 401 Negotiate challenge (it's 401, not 407) from the web server, due to it being Kerberos-protected, it goes to its KDC and requests a Kerberos service ticket for HTTP/proxy.foo.bar, zips back to proxy.foo.bar and presents the ticket to that host for the HTTP service running on it. The host validates this ticket and if all is well and the client web browser renders the HTML. You've seen the Kerberos ticket ticket when you ran klist on the client. I don't have any web references for you, this is all off the top of my head.
You also asked “Does it request the ticket to the domain name he's making request to (in this case it is proxy.foo.bar indeed), or does it receive the name in the authentication sequence, in a 407 reply in this case (which doest contain the negotiate challenge, but I just don't know if there's a way to look into it) ?”
A. Your question was a bit hard to follow but if I am understanding you correctly, the answer is the web client requests a ticket as a result of the HTTP 401 Negotiate authentication challenge from the web server (see above).
There’s many diagrams sequencing this process on the web, including here: http://www.zeroshell.org/kerberos/Kerberos-operation/
What exactly is the role of the ConnectionToken in SignalR?
I inspected the SignalR handshake in fiddler and saw that a ConnectionToken is being passed in the response to the negotiate request and then passed in all subsequent requests.
However, when inspecting the WS frames, I saw no trace of that ConnectionToken. Is it because fiddler hides it from me or is it simply not passed on the wire?
If it's because it's not passed on the wire, what is its' purpose?
If it is passed on the wire, is it considered to be a secret even if the transport is over ssl? how can an attacker exploit that token?
Connection token is an encrypted string containing the connection id and, if available, user name. It needs to be sent with each http request sent by the client to the server. If a server receives a request without the connection token or if it cannot decrypt the connection token it will reject the request. To read more on connection token and how it works take a look at this article.
You don't see the connection token in websocket frames since the connection token was validated when the websocket was opened (the connect request) and further validation is not needed (it is impossible for someone else to use this websocket). You would see the connection token again in case the connection was dropped and the client tried to reconnect.
Other transports send more http requests (e.g. for sending messages) and you will see that basically each of these requests (except for ping) contain the connection token. You can take a look at the SignalR protocol description I wrote some time ago for more details.
I have an IIS 7.5 on Windows Server 2008 R2. It has the Basic, Anonymous and Windows Authentication modes enabled. I have hosted a restful WCF service in it.
I make an http request with Authorization header from my client within the LAN/VPN, all goes well. On the service side I could see that the OperationContext.Current.IncomingMessageHeaders contains the Authorization header with the right value.
When I attempt to do the same from outside the LAN/VPN, (I used a different Internet connection and also a public proxy), the OperationContext.Current.IncomingMessageHeaders seems to have missing Authorization header.
I am unsure as to what exactly removes the header. I suspect a misconfigured IIS. Any clues?
If you want your service to always do windows authentication as the question seems to suggest, remove disable all other auth modes in IIS, requests from LAN are passing probably because people requesting it are from the same domain, in an internet (putting this simply) will go for the least required auth mode, which in this case would be anonymous.
is there a way for some one to sneak in the to see data if my service is over http and the caller in my case is hosted on http (i.e. service is on secure ssl host while caller is on simple http).
is that call secure or not?
Basic HTTP without any encryption or other means of obfuscating your content is just plain text going over the wire. Anyone with a bit of knowledge can trap that connection and just read everything that goes on.
I don't quite understand what you mean by the server is on secure host but the client is not? Either the conversation between those two is secured by SSL / HTTPS (but then BOTH ends need to participate), or not. If not - it's just clear text on the wire.
Yes if someone is able to sneak into your transmissions, they can workout if the messages are encrypted or not.
When you connect to a server marked with server side SSL (server marked with https), it sends a copy of its cert to the client (e.g. your browser) which verifies if its a genuine cert. This only confirms that the server is really what it says it is and not someone else masquerading.
This does not guarantee that no can intercept your message. They can intercept but wont be able to decrypt.