简体   繁体   中英

creating idhttpserver with ssl encryption

I am not good with delphi yet, but based on some examples I have managed to create simple http server with no more than 10 users.
There are 2 main problems I don't know how to solve yet.

  1. proper way to authenticate, manage users - sessions
  2. main problem, connection must be secure, so SSL encryption is needed, how to implement it?

Any example I found in relation with idhttpserver and openssl, was not quite complete or with older version of Indy.

I am currently working with Delphi XE2 with Indy 10 components.

proper way to authenticate, manage users - sessions

TIdHTTPServer manages HTTP sessions for you if you set the TIdHTTPServer.SessionState property is true (it is false by default). TIdHTTPServer uses cookies for session management, so your clients need to have cookies enabled.

Authentication has to be performed manually, but how you do that depends on whether your clients are using HTTP-based or HTML-based authentication.

For HTTP authentication, there are ARequestInfo.UserName and ARequestInfo.Password properties available. If not valid, send an appropriate 401 response back to the client (if you set the AResponseInfo.AuthRealm property to a non-blank string, TIdHTTPServer will send a 401 response for you). By default, TIdHTTPServer only supports BASIC authentication. If you want to support other authentication schemes, you will have to use the TIdHTTPServer.OnParseAuthentication event, and send the 401 reply manually so you can send back appropriate WWW-Authenticate headers. Either way, if the client is validated, you can use HTTP sessions to keep the client logged in between requests. The AResponseInfo.Session and AResponseInfo.Session properties point at the current session. If TIdHTTPServer.AutoStartSession is true (it is false by default), TIdHTTPServer creates new sessions automatically. Otherwise, you can call TIdHTTPServer.CreateSession() yourself when needed. TIdHTTPSession has a Content property that you can store session-specific data in. Or you can derive a new class from TIdHTTPSession and then use the TIdHTTPServer.OnCreateSession event to create instances of that class.

For HTML authentication, you have two choices, depending on how you configure your HTML:

  1. if your HTML <form> tag does not have an enctype attribute, or it is set to application/x-www-webform-urlencoded , TIdHTTPServer will store the raw webform data in the ARequestInfo.FormParams property, and if TIdHTTPServer.ParseParams is true (which it is by default), the data will also be parsed into the ARequestInfo.Params property for you.

  2. if your HTML <form> tag has an enctype attribute set to multipart/form-data , you will have to parse the content of the ARequestInfo.PostStream manually, as TIdHTTPServer does not yet parse that data for you (examples have been posted many times before on many different forums on how to parse that data manually using Indy's TIdMessageDecoderMIME class). By default, ARequestInfo.PostStream points at a TMemoryStream object. You can use the TIdHTTPServer.OnCreatePostStream event to create an instance of a different TStream -derived class, if desired.

main problem, connection must be secure, so SSL encryption is needed, how to implement it?

Before activating the server:

  1. assign a TIdServerIOHandlerSSLBase -derived component, such as TIdServerIOHandlerSSLOpenSSL , to the TIdHTTPServer.IOHandler property and configure it as needed (certificate, peer validation, SSL version(s), etc). In the case of OpenSSL, you will have to deploy the 2 OpenSSL library binaries libeay32.dll and ssleay32.dll (or non-Windows platform equivalents) with your app if they are not already pre-installed on the target OS, or if you want to ensure your app uses a specific version of OpenSSL. At this time, OpenSSL is the only encryption that Indy supports natively, but there are third-party solutions available that are compatible with Indy, such as EldoS SecureBlackbox .

  2. fill in the TIdHTTPServer.Binding property with a binding for your desired HTTPS port (443 is the default HTTPS port). Typically you should create 2 bindings, one for HTTP port 80 and one for HTTPS port 443. Inside your OnCommand... handlers, if you receive a request that requires SSL/TLS encryption, you can check the port that the request was made on ( AContext.Binding.Port ) and if not HTTPS then redirect ( AResponseInfo.Redirect() ) the client to retry the request on the HTTPS port.

  3. assign a handler to the TIdHTTPServer.OnQuerySSLPort event and have it set its VUseSSL parameter to True when its APort parameter matches your HTTPS port. UPDATE starting with SVN rev 5461, an OnQuerySSLPort handler is no longer needed if your only HTTPS port is 443.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM