使用SSL加密创建idhttpserver [英] creating idhttpserver with ssl encryption
问题描述
我对delphi并不满意,但是基于一些示例,我设法创建了一个不超过10个用户的简单http服务器.
有2个主要问题,我尚不知道如何解决.
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.
- 验证,管理用户的正确方法-会话
- 主要问题,连接必须安全,因此需要SSL加密,如何实现?
我发现与idhttpserver和openssl有关的任何示例都不完整或与Indy的旧版本有关.
Any example I found in relation with idhttpserver and openssl, was not quite complete or with older version of Indy.
我目前正在使用带有Indy 10组件的Delphi XE2.
I am currently working with Delphi XE2 with Indy 10 components.
推荐答案
验证,管理用户的正确方法-会话
proper way to authenticate, manage users - sessions
如果将TIdHTTPServer.SessionState
属性设置为true(默认情况下为false),则
TIdHTTPServer
将为您管理HTTP会话. TIdHTTPServer
使用cookie进行会话管理,因此您的客户端需要启用cookie.
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.
身份验证必须手动执行,但是如何执行取决于您的客户端使用的是基于HTTP的身份验证还是基于HTML的身份验证.
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身份验证,有ARequestInfo.UserName
和ARequestInfo.Password
属性可用.如果无效,则将适当的401响应发送回客户端(如果将AResponseInfo.AuthRealm
属性设置为非空白字符串,则TIdHTTPServer
将为您发送401响应).默认情况下,TIdHTTPServer
仅支持BASIC
身份验证.如果要支持其他身份验证方案,则必须使用TIdHTTPServer.OnParseAuthentication
事件,并手动发送401答复,以便可以发送回相应的WWW-Authenticate
标头.无论哪种方式,如果客户端都经过验证,则可以使用HTTP会话来保持客户端在两次请求之间登录. AResponseInfo.Session
和AResponseInfo.Session
属性指向当前会话.如果TIdHTTPServer.AutoStartSession
为true(默认情况下为false),则TIdHTTPServer
将自动创建新会话.否则,您可以在需要时自行致电TIdHTTPServer.CreateSession()
. TIdHTTPSession
具有一个Content
属性,您可以在其中存储特定于会话的数据.或者可以从TIdHTTPSession
派生一个新类,然后使用TIdHTTPServer.OnCreateSession
事件创建该类的实例.
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.
对于HTML身份验证,根据配置HTML的方式,您有两种选择:
For HTML authentication, you have two choices, depending on how you configure your HTML:
-
如果您的HTML
<form>
标记不具有enctype
属性,或者将其设置为application/x-www-webform-urlencoded
,则TIdHTTPServer
会将原始Web表单数据存储在ARequestInfo.FormParams
属性中,如果TIdHTTPServer.ParseParams
为true(默认情况下为true),数据也将为您解析为ARequestInfo.Params
属性.
if your HTML
<form>
tag does not have anenctype
attribute, or it is set toapplication/x-www-webform-urlencoded
,TIdHTTPServer
will store the raw webform data in theARequestInfo.FormParams
property, and ifTIdHTTPServer.ParseParams
is true (which it is by default), the data will also be parsed into theARequestInfo.Params
property for you.
如果HTML <form>
标记的enctype
属性设置为multipart/form-data
,则必须手动解析ARequestInfo.PostStream
的内容,因为TIdHTTPServer
尚未解析该数据以用于您(有关示例如何使用Indy的TIdMessageDecoderMIME
类手动解析数据的示例已经多次发布在许多不同的论坛上).默认情况下,ARequestInfo.PostStream
指向TMemoryStream
对象.如果需要,可以使用TIdHTTPServer.OnCreatePostStream
事件创建不同的TStream
派生类的实例.
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.
主要问题,连接必须安全,因此需要SSL加密,如何实现?
main problem, connection must be secure, so SSL encryption is needed, how to implement it?
在激活服务器之前:
-
将
TIdServerIOHandlerSSLBase
派生的组件(例如TIdServerIOHandlerSSLOpenSSL
)分配给TIdHTTPServer.IOHandler
属性,并根据需要进行配置(证书,对等验证,SSL版本等).对于OpenSSL,如果尚未在目标OS上预先安装2个OpenSSL库二进制文件libeay32.dll
和ssleay32.dll
(或非Windows平台等效文件),则必须将它们与您的应用程序一起部署.希望确保您的应用使用特定版本的OpenSSL.目前,OpenSSL是Indy本地支持的唯一加密方法,但是有一些与Indy兼容的第三方解决方案,例如
assign a
TIdServerIOHandlerSSLBase
-derived component, such asTIdServerIOHandlerSSLOpenSSL
, to theTIdHTTPServer.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 binarieslibeay32.dll
andssleay32.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.
在TIdHTTPServer.Binding
属性中填写所需HTTPS端口的绑定(默认为HTTPS端口443).通常,您应该创建2个绑定,一个用于HTTP端口80,一个用于HTTPS端口443.在您的OnCommand...
处理程序内部,如果收到要求进行SSL/TLS加密的请求,则可以检查该请求的端口( AContext.Binding.Port
),如果不是HTTPS,则重定向(AResponseInfo.Redirect()
)客户端以在HTTPS端口上重试该请求.
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.
将处理程序分配给TIdHTTPServer.OnQuerySSLPort
事件,并在其APort
参数与您的HTTPS端口匹配时,将其VUseSSL
参数设置为True. 更新从SVN版本5461(OnQuerySSLPort
处理程序 .
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.
这篇关于使用SSL加密创建idhttpserver的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!