具有自定义证书验证的 WCF Web 服务
WCF webservice with custom certificate validation
我正在托管一个带有自定义证书验证的 WCF 网络服务,但我无法正确配置它。当我尝试获取 WebService 的 WSDL 时,出现以下编译错误。我做错了什么?
谢谢
编辑:
我调查过:Custom certificate validation in WCF service and authentication of clientCertificate Element and How to: Create a Service that Employs a Custom Certificate Validator and X.509 Certificate Validator 和 none 这些链接描述了我遇到的问题。
编译错误信息:
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(修复):
将默认构造函数插入证书验证器class:
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。感谢您的帮助:)
我认为你必须改变这个
customCertificateValidatorType =
"MyProject.MyX509CertificateValidator, service"/>
到
customCertificateValidatorType =
"MyProject.MyX509CertificateValidator, MyProject"/>
因为'service'它不在您的命名空间中。也许您是从 MSDN 粘贴它,但您必须认为 MSDN WCF 演示项目('101 个样本')曾经被称为 'service'.
我正在托管一个带有自定义证书验证的 WCF 网络服务,但我无法正确配置它。当我尝试获取 WebService 的 WSDL 时,出现以下编译错误。我做错了什么?
谢谢
编辑:
我调查过:Custom certificate validation in WCF service and authentication of clientCertificate Element and How to: Create a Service that Employs a Custom Certificate Validator and X.509 Certificate Validator 和 none 这些链接描述了我遇到的问题。
编译错误信息:
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(修复):
将默认构造函数插入证书验证器class:
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。感谢您的帮助:)
我认为你必须改变这个
customCertificateValidatorType = "MyProject.MyX509CertificateValidator, service"/>
到
customCertificateValidatorType = "MyProject.MyX509CertificateValidator, MyProject"/>
因为'service'它不在您的命名空间中。也许您是从 MSDN 粘贴它,但您必须认为 MSDN WCF 演示项目('101 个样本')曾经被称为 'service'.