I am very new in websockets area. I am trying to figure out the auth for websocket endpoint in c#. The service already has its auth which works for http endpoints. Few questions I had are
Would I need to handle the auth for websocket endpoint differently? Also once the handshake happens, would we need to authenticate the requests again?
Do we need to maintain the state of clients on server corresponding to the requests? If yes, what are the recommended approach for the same?
The websocket connection is established by upgrading an http request. If you have some kind of authentication already working for http requests, then you need to make sure that this authentication is applied before the upgrade happens, so that no upgrade can take place unless the request has been authenticated. How you do this depends on the specifics of your system.
Once the websocket connection has been established using a properly authenticated http request as the starting point, authentication is not applicable anymore in the context of the websocket. There is nothing you have to do. There is no such thing as requests that you have to authenticate. The websocket is a bi-directional stream of messages in an established session.
And yes, the concept of a session does always imply client state, so your server will have to have knowledge of every single websocket client which is at any moment connected. At the very least you need to keep the connection object alive, so that you can read messages from it and write messages to it.
Related
Recently, we migrated one of our existing web service to WCF service with basic http binding (hosted in IIS). The problem is whenever user sending a long running request (>5min) to the service, the client keep on waiting for server response until closing it manually. After analysing the Wireshark and Firewall logs we found the reason, the default HTTP session timeout set for 300 sec in firewall due to this firewall remove the long running session from the table after 5min.
We can resolve this by increasing HTTP session timeout in firewall but the complexity is we can control it at server side firewall but we can’t control at client side(each client will have different ISP and IT Policy). So my network admin suggested to implement the keep-alive mechanism (sending heart beat message to server) but it doesn’t worked for me.
I tried following things while implementing keep-alive mechanism,
First, I tried to send echo messages to server with the same channel
which created for long running request but it was failed since the
channel already waiting for response.
Then I tried to send echo message to server for every four min with
separate channel but there is not impact on the issue since it using
the brand new connections.
I tried with async service calling pattern but there is no impact.
Finally, I tried by adding the Keep-Alive (Keep-Alive: max=100,
timeout=1801) header for each request and response at both client and
server side again there is no impact on the issue.
So, could you please help me to resolve this issue?
I have written a winforms client, that connects to a Windows service establishing a connection with XSockets.Net. This is working fine for a direct connection to the internet.
But when there is a proxy server, it will fail.
As I checked the XSockets API I have not found any settings, that allows me to use a proxy server.
Also for the websockets protocol I have not found a sufficient answer.
Any ideas?
Use WSS:// for connection, that is the equivalent to HTTPS in WebSocket.
The WebSocket protocol handshake sends the HTTP headers "Upgrade:websocket" and "Connection:Upgrade", meaning that the proxy will probably remove the "Upgrade" header because is set as a "Connection" header. By using a secure protocol, the proxy won't be able of intercept the request and will just let it pass.
Cheers.
I am writing a proxy with TcpListener in C#.
This proxy listens a port that users send request to. And when accepted a user request, it will parse the request header and find the host name. Then it creates a TcpClient to the host server.
Here comes the problem. When http request comes, it should connect the port 80 of the server; while https request comes, it should connect the port 443 of the server. But I have no idea of how to distinguish http request and https request.
Question in one sentence: how to know it is a http request or https request that TcpListener accepted?
Many thanks!
You've stepped in a problem that has flustered web server administrators for a long time.
Here's the process:
Web browser establishes a TCP connection to a particular IP on the web server.
The web server knows what IP it's getting a connection from, knows that that IP is only ever used for secure.example.com, and so loads the SSL certificate for secure.example.com.
The web server and web browser negotiate a SSL connection.
The web browser sends vanilla HTTP headers down the SSL pipe, which include the "HOST: secure.example.com" line that indicates the virtual host to use.
The web server processes the request and sends the response using vanilla HTTP headers sent down the SSL pipe.
The web server has to decide which virtual host to use before it has any HTTP headers. This is because it has to negotiate an SSL connection first, and it has to know which certificate to use first. The vanilla solution is to use IP-based virtual hosts - run the web server on IP address X; whenever the server gets a request sent to address X, it knows the request belongs to the configured vhost for that address.
The problem with that scheme is that the server has to have separate IP addresses for each secure website it runs. That might be many, many IP addresses, and is either costly or impractical.
Step in Server Name Indication. When the web browser is negotiating the SSL connection to the web server, the web browser includes the hostname it wants to connect to in the SSL negotiation information. Now the web server can use that information to do normal name-based virtual hosts, and so the web server can run a thousand different secure websites each with their own SSL certificates all on exactly one IP address. Everything is right in the world again.
You want to get in the middle of this, which means that you have to understand the SSL/TLS negotiation phase, parse the server name information, and forward the request down to the right web server.
Your new flow looks something like this:
Web browser establishes a TCP connection to the proxy.
Proxy begins recording the SSL exchange.
Web browser starts to do SSL negotiation, and as part of such, sends the Server Name Information down.
The proxy parses the Server Name Information, decides which web server should handle the request, and forwards the SSL negotiation information to the web server.
The proxy does not otherwise participate in the negotiation; it reads the SNI, but otherwise is completely "pass-through".
The web browser and server complete the SSL negotiation, the server picks the right vhost, and the browser sends vanilla http headers for a request.
The web server reads the vanilla headers via the SSL connection, and processes the request.
Now that that's been said, you might realize that sticking your nose in the SSL connection negotiation might be more trouble than it's worth. Turns out a few other people have already had the same idea as you and have implemented a few programs that seem to do exactly what you're trying to do - do a search for "http sni proxy" - I came up with this: https://github.com/dlundquist/sniproxy
The headers are entirely encrypted. The only information going over the network 'in the clear' is related to the SSL setup and D/H key exchange. This exchange is carefully designed not to yield any useful information to eavesdroppers, and once it has taken place, all data is encrypted.
Update By the way After the SSL negotiation, normal HTTP headers will travel inside the encrypted stream, so there is really no difference between the two.
I do not quite understand how exactly persistent connections work.
So the keepalive property is set by default and this should keep my connection open, as far as I understand it.
So right now I am sending my data via a POST on an HTTPWebRequest.
But I do this everytime I send something to the recipient.
So it is like this:
POST data from client to server, response to the post is returned.
But next i just send another POST, instead of using the connection I already opened. So I feel like I am sending more than I actually have to.
Can't I just open the connection once and then continue communication via this connection?
I am sorry for my poor understanding of this subject, but this is the first time I really work with network protocols.
Thanks in advance
Daniel
KeepAlive was added to HTTP protocol to improve server-side performance.
HTTP is generally a stateless protocol. All state is preserved as cookies or server's session. If KeepAlive is set to true, client and the server could potentially keep their underlying TCP Connection alive.
Usually a time-out set for KeepAlive so that if client did not make any other request, this connection is closed.
This feature is usually implemented differently across different platforms, for example I have seen issues with Java implementation where they do not respect the timeout and server closes the connection so client's attempt to connect again fails since it assumes connection is still open.
See RFC document here.
You can reuse the connection IF the server supports it.... including any proxies in between you and the server. Which is where it sometimes falls down. It was tacked on to HTTP 1.0 and officially added in 1.1.
Basically, your client asks "may I keep this connection alive" with a special header, then if the server supports it, it replies saying "yes" and the client can then send more requests on the same socket.
Your client code also has to support this ability. .Net should be fine.
We have a custom chat application(c#) which uses TCPClient. We are having problem on clients who are behind Firewall or proxy. We know that these client can browse the internet without a problem so we decided to change our TCPClient application so that It uses HTTP messages to communicate.
Will it be enough just to wrap our text massages with standard HTML tags and HTTP headers? We need a long lasting connection. Does keep-alive have a limit? Do firewalls or proxies have time limits for "alive" connections.
You would need to change your protocol, probably pretty significantly. There's no guarantee that a proxy is going to use the same TCP connection for subsequent HTTP requests, it has the freedom to close any connection after receiving a message from the server, and they generally will after only a few idle seconds.
Unless your protocol can work stateless, then it isn't going to work over HTTP through a proxy.