我对delphi不太满意,但是基于一些示例,我设法创建了一个不超过10个用户的简单http服务器。
有2个主要问题,我尚不知道如何解决。


验证,管理用户的正确方法-会话
主要问题是,连接必须安全,因此需要SSL加密,如何实现?


我发现的与idhttpserver和openssl有关的任何示例都不十分完整,也与Indy的旧版本无关。

我目前正在使用带有Indy 10组件的Delphi XE2。

最佳答案

验证,管理用户的正确方法-会话


如果将TIdHTTPServer属性设置为true(默认情况下为false),则TIdHTTPServer.SessionState将为您管理HTTP会话。 TIdHTTPServer使用cookie进行会话管理,因此您的客户端需要启用cookie。

身份验证必须手动执行,但是如何执行取决于您的客户端使用的是基于HTTP的身份验证还是基于HTML的身份验证。

对于HTTP身份验证,有ARequestInfo.UserNameARequestInfo.Password属性可用。如果无效,则将适当的401响应发送回客户端(如果将AResponseInfo.AuthRealm属性设置为非空白字符串,则TIdHTTPServer将为您发送401响应)。默认情况下,TIdHTTPServer仅支持BASIC身份验证。如果要支持其他身份验证方案,则必须使用TIdHTTPServer.OnParseAuthentication事件,并手动发送401答复,以便可以发送回适当的WWW-Authenticate标头。无论哪种方式,如果客户端均已验证,则可以使用HTTP会话来使客户端在两次请求之间保持登录状态。 AResponseInfo.SessionAResponseInfo.Session属性指向当前会话。如果TIdHTTPServer.AutoStartSession为true(默认情况下为false),则TIdHTTPServer自动创建新会话。否则,您可以在需要时自行呼叫TIdHTTPServer.CreateSession()TIdHTTPSession具有一个Content属性,您可以在其中存储特定于会话的数据。或者,您可以从TIdHTTPSession派生一个新类,然后使用TIdHTTPServer.OnCreateSession事件创建该类的实例。

对于HTML身份验证,根据配置HTML的方式,您有两种选择:


如果您的HTML <form>标记没有enctype属性,或者将其设置为application/x-www-webform-urlencoded,则TIdHTTPServer会将原始Web表单数据存储在ARequestInfo.FormParams属性中,并且TIdHTTPServer.ParseParams为true( (默认情况下),数据也将为您解析为ARequestInfo.Params属性。
如果您的HTML <form>标记的enctype属性设置为multipart/form-data,则必须手动解析ARequestInfo.PostStream的内容,因为TIdHTTPServer尚未为您解析该数据(示例已发布)之前在许多不同的论坛上有很多次关于如何使用Indy的TIdMessageDecoderMIME类手动解析数据的信息)。默认情况下,ARequestInfo.PostStream指向TMemoryStream对象。如果需要,可以使用TIdHTTPServer.OnCreatePostStream事件创建不同的TStream派生类的实例。



  主要问题是,连接必须安全,因此需要SSL加密,如何实现?


激活服务器之前:


TIdServerIOHandlerSSLBase派生的组件(例如TIdServerIOHandlerSSLOpenSSL)分配给TIdHTTPServer.IOHandler属性,并根据需要进行配置(证书,对等验证,SSL版本等)。对于OpenSSL,如果尚未在目标OS上预先安装2个OpenSSL库二进制文件libeay32.dllssleay32.dll(或非Windows平台等效文件),则必须在应用程序中部署它们。希望确保您的应用使用特定版本的OpenSSL。目前,OpenSSL是Indy本地支持的唯一加密方法,但是存在与Indy兼容的第三方解决方案,例如EldoS SecureBlackbox
TIdHTTPServer.Binding属性中填写所需的HTTPS端口的绑定(443是默认的HTTPS端口)。通常,您应该创建2个绑定,一个用于HTTP端口80,一个用于HTTPS端口443。在您的OnCommand...处理程序中,如果您收到要求进行SSL / TLS加密的请求,则可以检查该请求的端口( AContext.Binding.Port),如果不是HTTPS,则重定向(AResponseInfo.Redirect())客户端,以在HTTPS端口上重试该请求。
TIdHTTPServer.OnQuerySSLPort事件分配一个处理程序,并在其VUseSSL参数与您的HTTPS端口匹配时,将其APort参数设置为True。如果您的唯一HTTPS端口是443,则从SVN版本5461(为OnQuerySSLPort处理程序is no longer needed)开始的UPDATE。

10-07 13:08