在IIS中使用wsHttpBinding托管WCF服务时出现问题

时间:2010-07-27 19:11:22

标签: wcf wcf-binding wcf-security

我正在尝试使用以下配置来托管我的服务。

<system.serviceModel>
    <services>
        <service name="Test.MyService" behaviorConfiguration="MyServiceBehavior">
            <!--         Service Endpoints -->
            <endpoint address="MyTestService" binding="wsHttpBinding" bindingConfiguration="WebserviceHttpBinding" contract="Test.IMyService"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
    <bindings>
        <wsHttpBinding>
            <binding name="WebserviceHttpBinding">
                <security mode="Message">
                    <message clientCredentialType="UserName" negotiateServiceCredential="false"/>
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="MyServiceBehavior">
                <serviceCredentials>
                    <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Test.CredentialValidator, Test"/>
                    <serviceCertificate findValue="RPKey" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
                </serviceCredentials>
                <!--           To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
                <serviceMetadata httpGetEnabled="true"/>
                <!--           To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

当我调试此服务时,我没有问题。我使用网站在IIS中托管此服务。当我从IIS浏览此服务时,我遇到异常。

'/ MyTestService'中的服务器错误 应用

密钥集不存在

描述:未处理的异常 在执行期间发生 当前的网络请求。请查看 堆栈跟踪以获取更多信息 错误及其来源 代码。

异常详细信息: System.Security.Cryptography.CryptographicException: 键集不存在

来源错误:

生成了未处理的异常 在执行当前 网络请求。有关的信息 异常的起源和位置 可以使用例外来识别 堆栈跟踪下面。

堆栈追踪:

[CryptographicException:Keyset不存在 ]    System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters,Boolean randomKeyContainer)+369    System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType,CspParameters parameters,Boolean randomKeyContainer,Int32 dwKeySize,SafeProvHandle&amp; safeProvHandle,SafeKeyHandle&amp; safeKeyHandle)+151    System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair()+85    System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize,CspParameters parameters,Boolean useDefaultKeySize)+280    System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()+ 468    System.ServiceModel.Security.SecurityUtils.EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate)+85

[ArgumentException:证书'CN = RPKey'必须有一个能够进行密钥交换的私钥。该进程必须具有私钥的访问权限。]    System.ServiceModel.Security.SecurityUtils.EnsureCertificateCanDoKeyExchange(X509Certificate2 certificate)+15832031    System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateServerX509TokenProvider()+45    System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateLocalSecurityTokenProvider(RecipientServiceModelSecurityTokenRequirement recipientRequirement)+73    System.ServiceModel.Security.ServiceCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement requirements)+65    System.ServiceModel.Security.SessionRenewSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement requirements)+14    System.ServiceModel.Security.SymmetricSecurityProtocolFactory.OnOpen(TimeSpan timeout)+15334232    System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)+23    System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)+563    System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout)+101    System.ServiceModel.Channels.SecurityChannelListener 1.OnOpen(TimeSpan timeout) +203 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +563 System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout) +87 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +563 System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) +110 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +563 System.ServiceModel.Security.SecuritySessionSecurityTokenAuthenticator.OnOpen(TimeSpan timeout) +149 System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) +23 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +563 System.ServiceModel.Security.SecurityUtils.OpenCommunicationObject(ICommunicationObject obj, TimeSpan timeout) +24 System.ServiceModel.Security.SecuritySessionServerSettings.OnOpen(TimeSpan timeout) +878 System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout) +23 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) +563 System.ServiceModel.Security.SecurityListenerSettingsLifetimeManager.Open(TimeSpan timeout) +153 System.ServiceModel.Channels.SecurityChannelListener 1.OnOpen(TimeSpan超时)+203    System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)+563    System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)+87    System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)+563    System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)+110    System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)+563    System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath)+135    System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)+654

[ServiceActivationException:由于编译期间发生异常,无法激活服务'/AtlasServices/Service.svc'。异常消息是:证书'CN = RPKey'必须具有能够进行密钥交换的私钥。该进程必须具有私钥的访问权限..]    System.ServiceModel.AsyncResult.End(IAsyncResult result)+15700960    System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result)+15623609    System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(HttpApplication context,Boolean flowContext)+265    System.ServiceModel.Activation.HttpModule.ProcessRequest(Object sender,EventArgs e)+227    System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+80    System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously)+171

4 个答案:

答案 0 :(得分:4)

这是可行的,因为在IIS上,帐户设置与用于运行本地服务器的帐户不同。

你正在使用X.509证书吗? 如果是这样,您确定您为运行包含私钥的文件的进程(即运行IIS)的帐户提供了读访问权限吗?

因此,如果IIS在Saghar帐户下运行,那么Saghar是否已读取密钥文件的特权?

@Update

ArgumentException:证书'CN = RPKey'必须具有能够进行密钥交换的私钥。该进程必须具有私钥的访问权限。

这告诉我您的IIS帐户没有私钥的权限

答案 1 :(得分:1)

基于异常报告,这听起来像是可能发生的两件事之一。您引用的证书要么仅使用公钥安装到密钥库中,要么已安装的证书受到限制,而运行应用程序池的帐户无权访问密钥。

如果x.509证书未导出为.pfx,而是作为.cer导出,则前一种情况很容易发生。要交换包含私钥的证书,.cer格式不足,因为它只能包含DER编码的x.509公钥证书。您必须将证书从证书服务器(或具有两个密钥的商店)导出为.pfx文件,并确保包含私钥。

如果是后一种情况,那么您需要确保您的服务在IIS下运行的应用程序池的帐户有权访问其中包含密钥的证书存储区。本文可能会有所帮助:Make X.509 Certificates Accessible to WCF

答案 2 :(得分:1)

IIS应用程序池标识无权访问证书

  1. 将应用程序池标识设置为NETWORK SERVICE
  2. 安装rktools
  3. 运行“c:\ Program Files(x86)\ Windows Resource Kits \ Tools \ winhttpcertcfg.exe”-g -c LOCAL_MACHINE \ My -s WSE2QuickStartServer -a“NETWORK SERVICE”

答案 3 :(得分:0)

如果您不需要wshttpbinding,只需尝试更改为basichttpbinding,您的问题可能就会消失。

我们在客户从网络外部的网站连接时遇到了麻烦。由于连接超过了vpn,我们可以选择放弃绑定的安全性。