通过HTTPS从SQL Server存储过程调用WCF服务

时间:2018-05-14 07:35:12

标签: sql-server wcf https

我通过HTTPS服务从SQL Server存储过程调用一个WCF服务并获得以下错误:

  

证书颁发机构无效或不正确。

通过HTTP调用服务时服务调用成功,但是在通过HTTPS调用服务时问题就出现了。

当我通过SOAP UI调用它时,通过HTTPS进行的相同WCF服务调用是成功的。但是当从SQL Server Stored Prcoedure调用该服务时,该问题将通过HTTPS显示。

3 个答案:

答案 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