wsdl - DelphiXE8 和 WSDL,禁用通过 Smart Card Reader 的身份验证
问题描述
使用 Delphi XE8,我导入了一个 WSDL 并使用 HTTPRIO 组件进行身份验证:
property HTTPRIO:
HTTPWebNode ->
ClientCertificate -> CertName = ServiceSSL.cer
InvokeOptions [soIgnoreInvalidCerts,soPickFirstClientCertificate]
Event HTTPRIO
HTTPWebNode -> OnBeforePost = HTTPRIO1HTTPWebNode1BeforePost
procedure HTTPRIO1HTTPWebNode1BeforePost(const HTTPReqResp: THTTPReqResp;
Data: Pointer);
var
auth: String;
FUserName, FPassword : string;
begin
FUserName:=UtenteTS;
FPassword:=PassTS;
auth := 'Authorization: Basic ' + TNetEncoding.Base64.Encode(FUserName + ':' + FPassword);
HttpAddRequestHeaders(Data, PChar(auth), Length(auth), HTTP_ADDREQ_FLAG_ADD);
end;
效果很好。
问题是:当带有数字签名卡的智能卡读卡器插入 PC 时,在身份验证期间它与智能卡通信,打开 PIN 请求窗口。
我不想要这个,我想优先通过 HTTPRIO1HTTPWebNode1BeforePost 进行身份验证!
笔记:
运行调试,HTTPRIO1HTTPWebNode1BeforePost,它被处理,然后开始与智能卡的通信。如何禁用智能卡读卡器读取?
我需要将带有数字签名的卡连接到 PC,因为我的程序必须对文档进行数字签名。
我添加细节。
我注意到在调用 HTTPRIO1HTTPWebNode1BeforePost 之后
此代码执行两次
{ line 1151 of soap.SOAPHTTPtrans.pas Posting Data Event }
if Assigned(FOnPostingData) then
FOnPostingData(DatStr.Size, BuffSize);
RetVal := ERROR_SUCCESS;
{$IFDEF UNICODE}
HttpSendRequest(Request, nil, 0,
DatStr.Bytes, DatStr.Size);
{$ELSE}
HttpSendRequest(Request, nil, 0,
@DatStr.DataString[1],
Length(DatStr.DataString));
{$ENDIF}
RetVal := HandleWinInetError(GetLastError, Request, True);
case RetVal of
ERROR_SUCCESS: break;
ERROR_CANCELLED: System.SysUtils.Abort;
ERROR_INTERNET_FORCE_RETRY: {Retry the operation};
end;
第一个 RetVal pass 的值为 12032 = ERROR_INTERNET_FORCE_RETRY: {Retry the operation};
第二步 HttpSendRequest(Request, nil, 0, DatStr.Bytes, DatStr.Size); 启动智能卡读卡器并打开消息登录窗口,该窗口要求输入读卡器中数字签名的 PIN。RetVal = 0
我尝试使用 InternetSetOption(Data, INTERNET_FLAG_NO_AUTH, ????, ????) 但我不知道该怎么做。
我不想打开登录消息框,请求智能卡 PIN。我能怎么做?
更新我的请求
读完后:我试过这个:发布“用WinHTTP组件替换WinINet。两者都有非常接近的API,第二个不会创建任何UI交互,但会返回错误代码,就像任何其他API一样。WinINet的UI部分可能对于某些软件来说是个好主意,但听起来好像不符合您的需求。”
如何将 winHttp 与 HttpRio 一起使用?我试过了:
uses winHTTP;
...
procedure HTTPRIOHTTPWebNode1BeforePost(const HTTPReqResp: THTTPReqResp; Data: Pointer);
auth := 'Authorization: Basic ' + TNetEncoding.Base64.Encode(FUserName + ':' + FPassword);
if not WinHttpAddRequestHeaders(Data, PChar(auth), Length(auth), WinHTTP_ADDREQ_FLAG_ADD) then ShowMessage('demat WinHttpAddRequestHeaders: ' + SysErrorMessage(GetLastError()));
如果我使用 HttpAddRequestHeaders(在 winInet.dll 中)它可以工作:
HttpAddRequestHeaders(Data, PChar(auth), Length(auth), HTTP_ADDREQ_FLAG_ADD)
如果我使用 WinHttpAddRequestHeaders(在 winhttp.dll 中)它不起作用,并且我收到错误:无效句柄。:
句柄是数据类型点。
在关于 HINTERNET 句柄的帖子中 “Microsoft Win32 Internet (WinInet) 函数也使用 HINTERNET 句柄。但是,WinInet 函数中使用的句柄不能与 WinHTTP 函数中使用的句柄互换。有关 WinInet 的更多信息,请参阅关于 WinINet。”
所以我不能将 WinHttpAddRequestHeaders 与 Httprio 一起使用。对不起。
" WinHttpAddRequestHeaders(Data, PChar(auth), Length(auth), WinHTTP_ADDREQ_FLAG_ADD) 我想尝试使用带有 HttpRio 而不是 winInet 的 winHttp。正如我所读到的,使用 winHttp,我不会收到 Windows 安全窗口(PIN 请求)。我不知道如何在 HttpRio 中使用 winHttp。”你能帮帮我吗?
解决方案
推荐阅读
- ruby - 下面的动态方法调用代码怎么写?
- json-deserialization - WriteValueAsString 正在将 INT 转换为字符串,scala
- java - Java HttpClient 4.x Runnng 出现一些随机错误
- c++ - GTK3 OpenGL 视频渲染多为绿色(YUV420P)
- angular - 如何在 Angular 页面中编写重定向代码?
- r - 从R中的同一行分配值
- python - 如何在 Python Web 脚本中使用 Windows 环境变量作为 shebang
- docker - Spark 执行器结果“通过 BlockManager 发送”是什么意思?
- android - 如何在 Android 中使用 Dagger2 将字符串传递给 ViewModel/Repository 类?
- docusignapi - DocuSign Payments REST API 创建选项卡并保存付款方式