【问题标题】:WCF webservice with custom certificate validation具有自定义证书验证的 WCF Web 服务
【发布时间】:2015-05-24 06:55:07
【问题描述】:

我正在托管一个带有自定义证书验证的 WCF Web 服务,但我无法正确配置它。当我尝试获取 WebService 的 WSDL 时,出现以下编译错误。我做错了什么?

谢谢

编辑:

我已经调查过:Custom certificate validation in WCF serviceauthentication of clientCertificate ElementHow to: Create a Service that Employs a Custom Certificate ValidatorX.509 Certificate Validator 并且这些链接都没有描述我遇到的问题。

编译错误信息:

Could not load file or assembly 'service' or one of its dependencies. The system cannot find the file specified.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
Exception Details: System.IO.FileNotFoundException: Could not load file or assembly 'service' or one of its dependencies. The system cannot find the file specified.
Source Error: 
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

web.config:

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="TransportSecurity">
          <security mode="Message">
            <message clientCredentialType="Certificate" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyServiceBehavior">
          <serviceMetadata httpsGetEnabled="true" httpsGetUrl="" />
          <serviceDebug includeExceptionDetailInFaults ="true"/>
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="Custom" customCertificateValidatorType = "MyProject.MyX509CertificateValidator, service"/>
            </clientCertificate>
            <serviceCertificate findValue="hashvalue" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="clientBehavior">
          <clientCredentials>
            <serviceCertificate>
              <authentication certificateValidationMode="Custom"  customCertificateValidatorType="MyProject.MyX509CertificateValidator, client"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name="MyProject.MyProjectWCF" behaviorConfiguration="MyServiceBehavior">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="TransportSecurity" contract="MyProject.IMyProjectWCF" />
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>

WCF 代码:

Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports System.IdentityModel.Selectors
Imports System.Security.Cryptography.X509Certificates
Imports System.IdentityModel.Tokens
Imports System.ServiceModel.Security

Namespace MyProject
    ' NOTE: You can use the "Rename" command on the context menu to change the class name "MyProjectWCF" in code, svc and config file together.
    <ServiceBehavior()> _
    Public Class MyProjectWCF
        Implements IMyProjectWCF

        Public Function HelloWorld() As String Implements IMyProjectWCF.HelloWorld
            Return "nameSpace: [" + Me.GetType().Namespace + "]" + vbNewLine + "Normal response"
        End Function

        Sub New()
            Dim serviceHost As New ServiceHost(GetType(MyProjectWCF))
            Try
                serviceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom
                serviceHost.Credentials.ClientCertificate.Authentication.CustomCertificateValidator = New MyX509CertificateValidator("CN=MyCertificate")
                serviceHost.Open()
                'serviceHost.Close()
            Finally
                'serviceHost.Close()
            End Try
        End Sub
    End Class

    Public Class MyX509CertificateValidator
        Inherits X509CertificateValidator
        Private allowedIssuerName As String

        Public Sub New(ByVal allowedIssuerName As String)
            If allowedIssuerName Is Nothing Then
                Throw New ArgumentNullException("allowedIssuerName")
            End If
            Me.allowedIssuerName = allowedIssuerName
        End Sub

        Public Overrides Sub Validate(ByVal certificate As X509Certificate2)
            ' Check that there is a certificate.
            If certificate Is Nothing Then
                Throw New ArgumentNullException("certificate")
            End If
            ' Check that the certificate issuer matches the configured issuer.
            If allowedIssuerName <> certificate.IssuerName.Name Then
                Throw New SecurityTokenValidationException _
                  ("Certificate was not issued by a trusted issuer")
            End If
        End Sub
    End Class
End Namespace

接口代码:

Imports System.ServiceModel
Imports System.Security.Permissions

Namespace MyProject
    ' NOTE: You can use the "Rename" command on the context menu to change the interface name "IMyProjectWCF" in both code and config file together.
    <ServiceContract([Namespace]:="MyProject")> _
    Public Interface IMyProjectWCF
        <OperationContract()> _
        Function HelloWorld() As String
    End Interface
End Namespace

编辑 2(有修复):

将默认构造函数插入到证书验证器类中:

    Public Sub New()
        Me.New("CN=yourCertificate here")
    End Sub

然后我必须弄清楚我网站的项目名称是什么,即 App_Code,它与一堆其他页面编译成一个 DLL,即 APP_Code.dll。 web.config 中的最后一行如下所示:

<authentication certificateValidationMode="Custom" customCertificateValidatorType="MyProject.MyX509CertificateValidator, App_Code"/>

所以现在没有编译错误,我得到了我的 WSDL。谢谢你的帮助:)

【问题讨论】:

    标签: vb.net web-services wcf wcf-security x509certificate2


    【解决方案1】:

    我认为你必须改变这个

    customCertificateValidatorType = "MyProject.MyX509CertificateValidator, 服务"/>

    customCertificateValidatorType = "MyProject.MyX509CertificateValidator, MyProject"/>

    因为“服务”不在您的命名空间中。也许您是从 MSDN 粘贴的,但您不得不认为 MSDN WCF 演示项目(“101 个示例”)曾经被称为“服务”。

    【讨论】:

    • 没有用。我收到相同的消息,但我得到的是 MyProject 而不是服务
    • 尝试了各种组合:“MyProject.MyX509CertificateValidator, MyProject”, “MyX509CertificateValidator, MyProject”, “MyProject.MyX509CertificateValidator, MyProject.MyX509CertificateValidator”, “MyProject.MyX509CertificateValidator” 无济于事跨度>
    • 您的项目名称是什么?您的名称空间就在其中。试试 Project.namespace.class, 项目
    • 它是一个网站。如何找到项目名称?当我打开项目时,我将其作为网站打开,它位于这样的共享驱动器上:\\shareddrive\MyProject\Subscriber\MyProjectWCF.svc
    • 您正在编译的 dll 的名称。右键单击解决方案资源管理器上根级别的 + 属性。一个 ASP.NET 项目在 bin 文件夹中生成一些 aspx 文件和一个主 DLL。这就是你需要的名字。从 MSDN (microsoft.com/en-us/download/details.aspx?id=21459) 获取 wcf 示例,并查看此子文件夹的演示:WF_WCF_Samples\WCF\Extensibility\Security\X509CertificateValidator
    猜你喜欢
    • 2010-12-06
    • 2015-05-27
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 2011-09-28
    • 2011-01-14
    相关资源
    最近更新 更多