401 unauth response in Kerberos - authentication

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).

Related

Workaround for third party cookie from server side

We have a customer having their own client UI application (www.myclient.com). When they make an API call to our server (www.iamserver.com), we set cookies (Set-Cookie header) and send back in the response. We expect these cookies to be sent in the subsequent requests from the client. [Third-Party-Cookies scenario]
Problem: Recently, due to some org policy, our client browsers have been blocked from using third party cookie. Obviously, calls to our server are not going through since the cookies are not set.
Is there any workaround from server side that we can do without doing any change in the client application? Looking for answers only from the server side.
I tried changing the domain of the cookie we set to that of the client domain. It still won't work because the browser blocks the cookie saying "domain attribute was invalid with regards to the current host url".
Browser: chrome
Any references/pointers are deeply appreciated.
Thanks in advance.

How can I authenticate a websocket connection where client and server reside on seperate domains?

I'm currently playing around with SignalR and websockets. From my research, it seems, as websockets do not support custom headers, there's basically only two ways to authenticate a websocket connection during token based authentication.
1) Passing the token in the query string
2) Storing the token in a cookie which then gets passed to the server when WithCredentials is set to true
The first method isn't great practice - even through websocket communication is encrypted, query strings may be logged by servers etc.
The second method I have got working on my local machine but it doesn't work once deployed because my client and server reside on different domains. So basically, I have an Angular site that has one domain (eg. client.com) and a WebAPI site that alls CORS with a completely different domain (eg. server.com). On my browser, if I'm on client.com, I cannot set a cookie that gets sent to server.com on a request.
What is a good way to authenticate websockets when client and server sit on different domains?
The WebSocket Protocol specification doesn't specify any particular way for authentication. You need to perform the authentication during the handshake phase and for that you can use any HTTP authentication mechanism like Basic, Digest, etc.
Further you could look into JWT token based authentication. Angular app can store the token in local storage and send it as a Transport header during the handshake request to the server. If the token is invalid, server can terminate the WebSocket connection upgrade request and the Angular app can re-direct the user to login page.

Identity cookie expiry

How would I redirect to login page AUTOMATICALLY, if my Identity cookie has expired at "ExpireTimeSpan" value? I do understand there is an event "OnRedirectToLogin" but that doesn't get triggered unless a request comes through. Is there a way, I can redirect to login right after the cookie has expired rather than keep sending requests to verify it has timed out?
Unless I misunderstand, what you want is the server to reach out to the client, but standard client/server HTTP works the other way around. The client is supposed to send requests to the server, and at some point to get redirected if its authentication cookie has expired, but if the cookie expires and the client never ask the server for anything more ever, then it doesn't have to be told anything has expired. Communication the other way around, where servers notify clients can be achieved by several means but is to be reserved for very particular needs. Are you sure you need that?

Difference between SSL and JWT

I've been reading and trying to comprehend the differences in browser side security. From what I gather, SSL is used to keep people from sniffing the traffic you send to the server. This allows you to send a password to a server in clear text...right? As long as you are in an SSL encrypted session you don't have to worry about hashing the password first or anything weird, just send it straight to the server along with the username. After the user authenticates you send them back a JWT and then all future requests to the server should include this JWT assuming they are trying to access a secured area. This allows the server to not even have to check the password, all the server does is verify the signature and that's all the server cares about. As long as the signature is verified you give the client whatever info they are requesting. Have I missed something?
You are correct. "This allows the server not to even have to check the password." Why would you have to check a password on each request?
A JWT is a means of verifying authentication. It is generated upon a successful authentication request and hence forth passed with each request to let the server know this user is authenticated.
It can be used to store arbitrary values such as user_id or api_key but they are not very secure so don't store any valuable information here.
Be wary though, if a plain JWT is intercepted by a third party, it can assume this user's session and possible data.
SSL is a lower level form of security, encrypting every request from and to the server to prevent interception and retains integrity.
SSL is achieved by (purchasing) an SSL certificate and installing it on your server. Basically an SSL certificate is a small data file that binds a cryptographic key to an 'organisation'. Once installed succesfully, HTTPS requests (on port 443 by default) are possible.

NTLM Authentication Failure, 'www-authenticate': 'Negotiate, NTLM'

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.