我通过HTTPS服务从SQL Server存储过程调用一个WCF服务并获得以下错误:
证书颁发机构无效或不正确。
通过HTTP调用服务时服务调用成功,但是在通过HTTPS调用服务时问题就出现了。
当我通过SOAP UI调用它时,通过HTTPS进行的相同WCF服务调用是成功的。但是当从SQL Server Stored Prcoedure调用该服务时,该问题将通过HTTPS显示。
答案 0 :(得分:2)
在我看来,错误是关于“证书颁发机构”,即服务器证书的颁发者。您可能使用自签名证书。在这种情况下,您还需要在“受信任的根证书颁发机构”中在客户端计算机上安装CA证书。否则,客户端将无法完全验证服务器证书,因为它无法验证其颁发者(证书颁发机构)。
答案 1 :(得分:1)
谢谢,我让它正常工作。实际上,需要在存储过程中明确指定证书名称,如下所示,这在我的实现中是缺少的。
EXEC @hResult = sp_OAMethod
@objectID,
'setOption',
NULL,
3,
'LOCAL_MACHINE\My\'Certificate Name';
下面是从存储过程调用Web服务的完整存储过程实现。
CREATE PROCEDURE [dbo].[Usp_INT_SendHttpRequest]
@URI VARCHAR(2000) = '',
@methodName VARCHAR(50) = '',
@requestBody VARCHAR(8000) = '',
@SoapAction VARCHAR(255),
@UserName NVARCHAR(100), -- Domain\UserName or UserName
@Password NVARCHAR(100),
@responseText VARCHAR(8000) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
IF @methodName = ''
BEGIN
SELECT FailPoint = 'Method Name must be set';
RETURN;
END;
SET @responseText = 'FAILED';
DECLARE @objectID INT;
DECLARE @hResult INT;
DECLARE @source VARCHAR(255), @desc VARCHAR(255);
EXEC @hResult = sp_OACreate
'MSXML2.ServerXMLHTTP',
@objectID OUT;
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objectID,
@source OUT,
@desc OUT;
SELECT hResult = CONVERT(VARBINARY(4), @hResult),
source = @source,
description = @desc,
FailPoint = 'Create failed',
MedthodName = @methodName;
GOTO destroy;
RETURN;
END;
EXEC @hResult = sp_OAMethod
@objectID,
'setOption',
NULL,
3,
'LOCAL_MACHINE\My\ClientSignedByDevCA';
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objectID,
@source OUT,
@desc OUT;
SELECT hResult = CONVERT(VARBINARY(4), @hResult),
source = @source,
description = @desc,
FailPoint = 'Set Certificate failed',
MedthodName = @methodName;
GOTO destroy;
RETURN;
END;
-- open the destination URI with Specified method
EXEC @hResult = sp_OAMethod
@objectID,
'open',
NULL,
@methodName,
@URI,
'false',
@UserName,
@Password;
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objectID,
@source OUT,
@desc OUT;
SELECT hResult = CONVERT(VARBINARY(4), @hResult),
source = @source,
description = @desc,
FailPoint = 'Open failed',
MedthodName = @methodName;
GOTO destroy;
RETURN;
END;
-- set request headers
EXEC @hResult = sp_OAMethod
@objectID,
'setRequestHeader',
NULL,
'Content-Type',
'text/xml;charset=UTF-8';
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objectID,
@source OUT,
@desc OUT;
SELECT hResult = CONVERT(VARBINARY(4), @hResult),
source = @source,
description = @desc,
FailPoint = 'SetRequestHeader failed',
MedthodName = @methodName;
GOTO destroy;
RETURN;
END;
-- set soap action
EXEC @hResult = sp_OAMethod
@objectID,
'setRequestHeader',
NULL,
'SOAPAction',
@SoapAction;
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objectID,
@source OUT,
@desc OUT;
SELECT hResult = CONVERT(VARBINARY(4), @hResult),
source = @source,
description = @desc,
FailPoint = 'SetRequestHeader failed',
MedthodName = @methodName;
GOTO destroy;
RETURN;
END;
DECLARE @len INT;
SET @len = LEN(@requestBody);
EXEC @hResult = sp_OAMethod
@objectID,
'setRequestHeader',
NULL,
'Content-Length',
@len;
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objectID,
@source OUT,
@desc OUT;
SELECT hResult = CONVERT(VARBINARY(4), @hResult),
source = @source,
description = @desc,
FailPoint = 'SetRequestHeader failed',
MedthodName = @methodName;
GOTO destroy;
RETURN;
END;
EXEC @hResult = sp_OAMethod
@objectID,
'send',
NULL,
@requestBody;
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objectID,
@source OUT,
@desc OUT;
SELECT hResult = CONVERT(VARBINARY(4), @hResult),
source = @source,
description = @desc,
FailPoint = 'Send failed',
MedthodName = @methodName;
GOTO destroy;
RETURN;
END;
DECLARE @statusText VARCHAR(1000), @status VARCHAR(1000);
-- Get status text
EXEC sp_OAGetProperty
@objectID,
'StatusText',
@statusText OUT;
EXEC sp_OAGetProperty
@objectID,
'Status',
@status OUT;
SELECT @status,
@statusText,
@methodName;
-- Get response text
EXEC sp_OAGetProperty
@objectID,
'responseText',
@responseText OUT;
IF @hResult <> 0
BEGIN
EXEC sp_OAGetErrorInfo
@objectID,
@source OUT,
@desc OUT;
SELECT hResult = CONVERT(VARBINARY(4), @hResult),
source = @source,
description = @desc,
FailPoint = 'ResponseText failed',
MedthodName = @methodName;
GOTO destroy;
RETURN;
END;
destroy:
EXEC sp_OADestroy
@objectID;
SET @responseText = 'SUCCESS'
SET NOCOUNT OFF;
END;
答案 2 :(得分:0)
也许您需要授予对包含运行WCF的帐户的私钥的文件的读访问权限。这里有分步说明https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-make-x-509-certificates-accessible-to-wcf