使用 ssl 加密创建 idhttpserver

creating idhttpserver with ssl encryption

我还不擅长 delphi,但是根据一些示例,我已经设法创建了不超过 10 个用户的简单 http 服务器。
有两个主要问题我还不知道如何解决。

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

我发现的与 idhttpserver 和 openssl 相关的任何示例都不是很完整或与旧版本的 Indy 相关。

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

proper way to authenticate, manage users - sessions

如果您将 TIdHTTPServer.SessionState 属性 设置为 true(默认情况下为 false),

TIdHTTPServer 会为您管理 HTTP sessions。 TIdHTTPServer 使用 cookie 进行 session 管理,因此您的客户需要启用 cookie。

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

对于 HTTP 身份验证,有 ARequestInfo.UserNameARequestInfo.Password 属性可用。如果无效,向客户端发送适当的 401 响应(如果您将 AResponseInfo.AuthRealm 属性 设置为 non-blank 字符串,TIdHTTPServer 将为您发送 401 响应) .默认情况下,TIdHTTPServer 仅支持 BASIC 身份验证。如果您想支持其他身份验证方案,您将不得不使用 TIdHTTPServer.OnParseAuthentication 事件,并手动发送 401 回复,以便您可以发回适当的 WWW-Authenticate headers。无论哪种方式,如果客户端经过验证,您可以使用 HTTP sessions 使客户端在请求之间保持登录状态。 AResponseInfo.SessionAResponseInfo.Session 属性指向当前 session。如果 TIdHTTPServer.AutoStartSession 为真(默认为假),TIdHTTPServer 会自动创建新的 session。否则,您可以在需要时自己调用 TIdHTTPServer.CreateSession()TIdHTTPSession 有一个 Content 属性,您可以在其中存储 session-specific 数据。或者您可以从 TIdHTTPSession 派生一个新的 class,然后使用TIdHTTPServer.OnCreateSession 事件以创建该 class 的实例。

对于 HTML 身份验证,您有两种选择,具体取决于您如何配置 HTML:

  1. 如果您的 HTML <form> 标签没有 enctype 属性,或者设置为 application/x-www-webform-urlencodedTIdHTTPServer将原始网络表单数据存储在 ARequestInfo.FormParams 属性 中,如果 TIdHTTPServer.ParseParams 为真(默认情况下为真),数据也将被解析为 ARequestInfo.Params 属性给你。

  2. 如果您的 HTML <form> 标记的 enctype 属性设置为 multipart/form-data,您将必须解析 ARequestInfo.PostStream 手动,因为 TIdHTTPServer 尚未为您解析该数据(之前在许多不同的论坛上多次发布了有关如何使用 Indy 的 TIdMessageDecoderMIME class 手动解析该数据的示例).默认情况下,ARequestInfo.PostStream 指向 TMemoryStream object。如果需要,您可以使用 TIdHTTPServer.OnCreatePostStream 事件创建不同 TStream 派生的 class 的实例。

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

激活服务器前:

  1. 分配一个TIdServerIOHandlerSSLBase派生的组件,例如TIdServerIOHandlerSSLOpenSSL,到TIdHTTPServer.IOHandler 属性并根据需要配置它(证书,对等验证、SSL 版本等)。在 OpenSSL 的情况下,您必须将 2 个 OpenSSL 库二进制文件 libeay32.dllssleay32.dll(或 non-Windows 平台等效项)与您的应用程序一起部署,如果它们尚未 pre-installed在目标 OS 上,或者如果您想确保您的应用程序使用特定版本的 OpenSSL。目前,OpenSSL 是 Indy 原生支持的唯一加密方式,但有 third-party 个与 Indy 兼容的可用解决方案,例如 EldoS SecureBlackbox

  2. TIdHTTPServer.Binding 属性 中填写您想要的 HTTPS 端口的绑定(443 是默认的 HTTPS 端口)。通常你应该创建 2 个绑定,一个用于 HTTP 端口 80,一个用于 HTTPS 端口 443。在你的 OnCommand... 处理程序中,如果你收到一个需要 SSL/TLS 加密的请求,你可以检查请求的端口是在 (AContext.Binding.Port) 上创建的,如果不是 HTTPS,则重定向 (AResponseInfo.Redirect()) 客户端以在 HTTPS 端口上重试请求。

  3. TIdHTTPServer.OnQuerySSLPort 事件分配一个处理程序,并在其 APort 参数与您的 HTTPS 端口匹配时将其 VUseSSL 参数设置为 True。 更新 从 SVN 修订版 5461 开始,一个 OnQuerySSLPort 处理程序 is no longer needed 如果你唯一的 HTTPS 端口是 443。