简体   繁体   English

使用SSL加密创建idhttpserver

[英]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. 我对delphi不太满意,但是基于一些示例,我设法创建了一个不超过10个用户的简单http服务器。
There are 2 main problems I don't know how to solve yet. 有2个主要问题,我尚不知道如何解决。

  1. proper way to authenticate, manage users - sessions 验证,管理用户的正确方法-会话
  2. main problem, connection must be secure, so SSL encryption is needed, how to implement it? 主要问题是,连接必须安全,因此需要SSL加密,如何实现?

Any example I found in relation with idhttpserver and openssl, was not quite complete or with older version of Indy. 我发现的与idhttpserver和openssl有关的任何示例都不十分完整,也与Indy的旧版本无关。

I am currently working with Delphi XE2 with Indy 10 components. 我目前正在使用带有Indy 10组件的Delphi XE2。

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为您管理HTTP会话,如果你设置的TIdHTTPServer.SessionState属性为true(这是默认为false)。 TIdHTTPServer uses cookies for session management, so your clients need to have cookies enabled. TIdHTTPServer使用cookie进行会话管理,因此您的客户端需要启用cookie。

Authentication has to be performed manually, but how you do that depends on whether your clients are using HTTP-based or HTML-based authentication. 身份验证必须手动执行,但是如何执行取决于您的客户端使用的是基于HTTP的身份验证还是基于HTML的身份验证。

For HTTP authentication, there are ARequestInfo.UserName and ARequestInfo.Password properties available. 对于HTTP身份验证,有可用的ARequestInfo.UserNameARequestInfo.Password属性。 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). 如果无效,则将适当的401响应发送回客户端(如果将AResponseInfo.AuthRealm属性设置为非空字符串, TIdHTTPServer将为您发送401响应)。 By default, TIdHTTPServer only supports BASIC authentication. 默认情况下, TIdHTTPServer仅支持BASIC身份验证。 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. 如果要支持其他身份验证方案,则必须使用TIdHTTPServer.OnParseAuthentication事件,并手动发送401答复,以便可以发送回适当的WWW-Authenticate标头。 Either way, if the client is validated, you can use HTTP sessions to keep the client logged in between requests. 无论哪种方式,如果客户端均已验证,则可以使用HTTP会话来使客户端在两次请求之间保持登录状态。 The AResponseInfo.Session and AResponseInfo.Session properties point at the current session. AResponseInfo.SessionAResponseInfo.Session属性指向当前会话。 If TIdHTTPServer.AutoStartSession is true (it is false by default), TIdHTTPServer creates new sessions automatically. 如果TIdHTTPServer.AutoStartSession为true(默认情况下为false),则TIdHTTPServer自动创建新会话。 Otherwise, you can call TIdHTTPServer.CreateSession() yourself when needed. 否则,您可以在需要时自己调用TIdHTTPServer.CreateSession() 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. TIdHTTPSession具有一个Content属性,您可以在其中存储特定于会话的数据。或者您可以从TIdHTTPSession派生一个新类,然后使用TIdHTTPServer.OnCreateSession事件创建该类的实例。

For HTML authentication, you have two choices, depending on how you configure your HTML: 对于HTML身份验证,根据配置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. 如果您的HTML <form>标记不具有enctype属性,或者将其设置为application/x-www-webform-urlencoded ,则TIdHTTPServer会将原始ARequestInfo.FormParams表单数据存储在ARequestInfo.FormParams属性中,并且TIdHTTPServer.ParseParams为true (默认情况下),数据也将为您解析到ARequestInfo.Params属性中。

  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). 如果您的HTML <form>标记的enctype属性设置为multipart/form-data ,那么您将必须手动解析ARequestInfo.PostStream的内容,因为TIdHTTPServer尚未为您解析该数据(示例已发布多次)在许多不同的论坛上讨论过如何使用Indy的TIdMessageDecoderMIME类手动解析该数据)。 By default, ARequestInfo.PostStream points at a TMemoryStream object. 默认情况下, ARequestInfo.PostStream指向TMemoryStream对象。 You can use the TIdHTTPServer.OnCreatePostStream event to create an instance of a different TStream -derived class, if desired. 如果需要,可以使用TIdHTTPServer.OnCreatePostStream事件创建不同的TStream派生类的实例。

main problem, connection must be secure, so SSL encryption is needed, how to implement it? 主要问题是,连接必须安全,因此需要SSL加密,如何实现?

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). TIdServerIOHandlerSSLBase派生的组件(例如TIdServerIOHandlerSSLOpenSSL分配给TIdHTTPServer.IOHandler属性,并根据需要进行配置(证书,对等验证,SSL版本等)。 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. 对于OpenSSL,如果尚未在目标OS上预先安装2个OpenSSL库二进制文件libeay32.dllssleay32.dll (或非Windows平台等效文件),则必须将它们与应用程序一起部署。希望确保您的应用使用特定版本的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 . 目前,OpenSSL是Indy本地支持的唯一加密方法,但是有可用的与Indy兼容的第三方解决方案,例如EldoS SecureBlackbox

  2. fill in the TIdHTTPServer.Binding property with a binding for your desired HTTPS port (443 is the default HTTPS port). 填写TIdHTTPServer.Binding属性,并TIdHTTPServer.Binding绑定所需的HTTPS端口(443是默认的HTTPS端口)。 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. 通常,您应该创建2个绑定,一个用于HTTP端口80,一个用于HTTPS端口443。在OnCommand...处理程序中,如果收到要求进行SSL / TLS加密的请求,则可以检查该请求是在哪个端口上进行的。 ( AContext.Binding.Port ),如果不是HTTPS,则重定向( AResponseInfo.Redirect() ),客户端在HTTPS端口上重试请求。

  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. TIdHTTPServer.OnQuerySSLPort事件分配一个处理程序,并使其APort参数与您的HTTPS端口匹配时,将其VUseSSL参数设置为True。 UPDATE starting with SVN rev 5461, an OnQuerySSLPort handler is no longer needed if your only HTTPS port is 443. 从SVN版本5461开始更新 ,如果您唯一的HTTPS端口是443 不再需要 OnQuerySSLPort处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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