RTC Forums
November 27, 2024, 08:24:09 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: Deny client connection  (Read 4680 times)
ClementDoss
RTC License
***
Posts: 36


« on: November 11, 2017, 10:26:36 PM »

Hello Danijel,

I wrote a Rest Server using rtcHttpServer and it is finally the time to implement Authentication.
I was sure there was a variable in one of rtcHttpServer Connection events that would help me NOT accepting a client connection.
Is there any sample showing how to achieve this?

Basically the client must send an Authentication header that the server will handle and accept or deny the connection. I must return 401 Unauthorized for browsers or Applications.

Code:
procedure THTTP_Server.ServerHTTPConnecting(Sender: TRtcConnection);
  begin
  with TRtcDataServer(Sender) do
    begin
       if Request['Authorization']<>'' then begin
         {... Some checking ... }
       end
       else begin
          XLog('Unauthorized! '+PeerAddr);

          Response.Status(401,'Unauthorized');
          Write('Status 401 Unauthorized');

          Disconnect;
       end;
    end;

I try calling Disconnect in OnConnecting, OnConnect and OnClientConnect , but all I get is "The connection was reset". If I remove the Disconnect, then the cycle is triggered normally and the user has access to files it shouldn't. Anyway, it doesn't feel right to call disconnect on those events. What should be the best way to let the user know he is not welcome  Grin


TIA,
Clément
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #1 on: November 12, 2017, 10:13:46 AM »

Short answer ...

The code you've used for the "OnConnecting" event on the "TRtcHttpServer" component, actually belongs into the "OnCheckRequest" event of a "TRtcDataProvider" component (where you need to authenticate the Client on the Server), and ... there is no need for a Disconnect call, since the connection could be coming from a Proxy Server.

Long answer ...

There is NO mechanism in the RTC SDK that would allow you to DENY a connection before it has been established. Unless a Server is out of resources and has to deny connections from all Clients, there is no point in denying a connection anyway, since the Server has absolutely no information about a Client before a connection has been established.

Even after a connection was established, the Server only knows the Address and Port of the first remote Peer, which could be the actual Client, but ... it could also be a Proxy Server (used in most mobile networks and corporate LANs), a Load Balancer, a Data Router, or anything else used to forward HTTP/S traffic between HTTP/S Clients and Servers. This is why, in addition to opening a connection, a Client also has to SEND authentication information to the Server (using that open connection) and the Server has to receive and process that information to authenticate the Client.

Unless you are using HTTPS with Client-side SSL certificates for authentication (in which case you also need an open connection, but authentication is handled by the SSL/TLS layer, so you should contact the 3rd-party SSL/TLS component vendor for support), all the information required to authenticate the Client is sent by the Client in a HTTP/S Request (RTC Clients can send HTTP/S requests with a TRtcDataRequest component, linked to a TRtcHttpClient component).

To handle HTTP/S Requests from Clients, RTC Server uses a TRtcDataProvider component (unless you are using RTC remote functions, in which case it would be the TRtcServerModule component). The 1st event triggering on the TRtcDataProvider component is OnCheckRequest, where you can check Request headers and either (A) Accept the request, or (B) Disconnect the Client, or (C) do nothing and let other components handle that request. If you Accept the Request, you can send a Response back to the Client. If the Request does NOT have a Content Body (or if you are NOT interested in the Content Body), you can send a Response directly from the OnCheckRequest event.

How you want to handle Client authentication is entirely up to you, but please keep in mind that every single request you receive on the Server could be coming from a different Client, even if the TCP/IP connection was always the same (because of Proxy Servers, Load Balancers and anything else that might be in-between your Clients and your Server), so you will either need to ... (A) use Client-side SSL/TLS certificates for authentication with your Clients and Server (contact your SSL/TLS component vendor if you have questions about that), or (B) send Client-side information in every Request (to keep your Server state-less), or (C) send Client authentication info only in your "login" procedure, then use Sessions to manage Client-side information between Requests.

When using Sessions, the Server would create a Session object for the Client (after successful authentication) and send a "Session ID" back to the Client, which the Client would include in every other Request sent to the Server, and the Server would use to find and access Session information stored for that Client (for example, to check Clients permissions before doing anything that requires a permission). You could either roll your own implementation to manage Sessions, or ... you could use RTC Sessions - as explained in these FAQ topics:
-> What is a Session in RTC?
-> Is Session Management done automatically by the RTC?
-> Sessions and User Management
-> Web example using Sessions, Cookies and Form Post data (user input)
-> Using Sessions in Remote Functions

Best Regards,
Danijel Tkalcec
Logged
ClementDoss
RTC License
***
Posts: 36


« Reply #2 on: November 12, 2017, 05:26:36 PM »


Thanks for taking your time to give me such a detailed answer!
I understood the mechanism and I'll try to implement the Authentication (HTTP for now, HTTPS latter).

Anyway, thanks a lot!
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.025 seconds with 16 queries.