【问题标题】:How to create WebServices with a certificate in .NET如何在 .NET 中使用证书创建 WebServices
【发布时间】:2015-03-03 18:53:18
【问题描述】:

给我的任务是在 VB.net 中构建 WebServices(使用 MS Visual WebDeveloper 2010 Express)。我之前已经构建过 WS,但是这一次,要求是使用服务器认证来保护 WS。我用谷歌搜索和搜索,找不到解决方案或解释。

到目前为止,我已经研究了 IIS 需要重新配置,但仅此而已。我找不到托管 Web 服务的示例。

这是我目前拥有的服务器代码:

Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Runtime.InteropServices
Imports System.Security.Cryptography.X509Certificates
Imports System.Net.Security
Imports System.Diagnostics
Imports System.Net

' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
' <System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class MyWS
    Inherits System.Web.Services.Protocols.SoapHttpClientProtocol
    'Inherits System.Web.Services.WebService
    Dim _log As String = ""

    <System.Web.Services.WebMethod(BufferResponse:=False)> _
    Public Function HelloWorld2() As String
        Dim resp As String = ""
        Try
            _log &= "Enter HelloWorld2" & vbCrLf



            If String.IsNullOrEmpty(resp) Then
                resp = "STRING IS EMPTY" & vbCrLf
            End If
        Catch ex As Exception
            resp = "SYSTEM ERROR: " & vbCrLf & ex.ToString & vbCrLf ' & "LOG:" & vbCrLf & _log
        End Try

        Return "LOG:" & vbCrLf & _log & vbCrLf & vbCrLf & resp
    End Function

    Public Sub New()
        ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateCertificate)
        ServicePointManager.SecurityProtocol = [Enum].Parse(GetType(SecurityProtocolType), GetAppSetting("SecurityProtocol", "Tls"))
        SetProxy()
    End Sub

    <ComVisible(False)> Public Sub SetProxy()
        WebRequest.DefaultWebProxy = New System.Net.WebProxy()
    End Sub

Private Function ValidateCertificate(ByVal sender As Object, _
                         ByVal certificate As System.Security.Cryptography.X509Certificates.X509Certificate, _
                         ByVal chain As System.Security.Cryptography.X509Certificates.X509Chain, _
                         ByVal sslPolicyErrors As System.Net.Security.SslPolicyErrors) As Boolean
    _log &= "Enter ValidateCertificate: " & certificate.Subject & vbCrLf
    Log("Validating Certificate: " & certificate.Subject)
    Dim status As System.Security.Cryptography.X509Certificates.X509ChainStatus

    '' If the certificate is a valid, signed certificate, return true.
    If sslPolicyErrors = System.Net.Security.SslPolicyErrors.None Then
        Return True
    End If
    '' If there are errors in the certificate chain, look at each error to determine the cause.
    If (sslPolicyErrors And System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) Then
        If (Not chain Is Nothing) And (Not chain.ChainStatus Is Nothing) Then
            For Each status In chain.ChainStatus
                If (certificate.Subject = certificate.Issuer) And (status.Status = System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot) Then
                    '' Self-signed certificates with an untrusted root are valid.
                    Continue For
                Else
                    If status.Status <> System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError Then
                        '' If there are any other errors in the certificate chain, the certificate is invalid, so the method returns false.
                        Return False
                    End If
                End If
            Next
        End If
        '' When processing reaches this line, the only errors in the certificate chain are untrusted root errors for self-signed certificates.
        '' These certificates are valid for default Exchange server installations, so return true.
        Return True
    Else
        '' In all other cases, return false.
        Return False
    End If
End Function
End Class

这是我的客户端代码:

Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Runtime.InteropServices
Imports System.Security.Cryptography.X509Certificates
Imports System.Net.Security
Imports System.Diagnostics
Imports System.Net

Partial Class TestPages_testWS
    Inherits System.Web.UI.Page


    Public Sub New()
        ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateCertificate)
        ServicePointManager.SecurityProtocol = [Enum].Parse(GetType(SecurityProtocolType), GetAppSetting("SecurityProtocol", "Tls"))
        SetProxy()
    End Sub

    Protected Sub btnTestWS_Click(sender As Object, e As System.EventArgs) Handles btnTestWS.Click
        Dim ws As New MyWS
        Try
            ws.ClientCertificates.AddRange(GetCertificate("CertificateName"))
            txtOut.Text = ws.HelloWorld2()
        Catch ex As Exception
            txtOut.text = String.Format("EXCEPTION: [{0}]", ex.tostring)
        End Try
    End Sub

    <ComVisible(False)> Public Function GetCertificate(ByVal certName As String) As X509Certificate2Collection
        Dim result As X509Certificate2Collection = Nothing
        Dim store As X509Store = New X509Store(StoreName.My, StoreLocation.LocalMachine)
        store.Open(OpenFlags.ReadOnly)
        result = store.Certificates.Find(X509FindType.FindBySubjectName, certName, False)
        Return result
    End Function

    <ComVisible(False)> Public Function ValidateCertificate(ByVal sender As Object, ByVal certificate As X509Certificate, ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
        'Return True to force the certificate to be accepted.
        Return True
    End Function

    <ComVisible(False)> Public Sub SetProxy()
        WebRequest.DefaultWebProxy = New System.Net.WebProxy()
    End Sub
End Class

这不起作用,因为我什至无法正确设置 IIS。当我尝试设置 IIS 时,用于绑定 https 类型的 SSL 证书列表为空。我完全不知道该做什么以及如何进行。

我是否需要配置 IIS 才能使用带有证书的 WS?我怎么做?我的服务器代码会如何处理证书?

感谢您的任何见解。

编辑 1: 我修复了一个问题,这是一个合乎逻辑的问题,现在我在尝试在不提供证书的情况下查看页面时正确收到 403 - Forbidden: Access is denied. 消息。但是,现在还有另一个问题。我似乎可以访问带有我在 PC 上安装的一半证书的页面(我一次提供一个,在 oneToOneMappings 我添加了一个证书。其他证书怎么也可以工作?

此外,即使证书@oneToOneMappings 部分上有用户名和密码,我是否在调用 WS 之前在凭据对象中提供该信息似乎并不重要:ws.Credentials = New NetworkCredential(userName, userPass)

【问题讨论】:

    标签: .net vb.net web-services iis x509certificate


    【解决方案1】:

    除非您使用客户端证书进行身份验证,否则您的 Web 服务与任何证书无关。无需更改任何代码。

    您应该只在 IIS 中使用 TSL(SSL) 来保护客户端和您的服务之间的传输层。

    有大量关于在 iis 上设置 SSL 的信息,例如How to Set Up SSL on IIS

    【讨论】:

    • 在发布我的原始请求之前,我浏览了该指南。我仍然无法弄清楚。我已经设置了我的 WS 以启用 SSL 并需要证书。但是,每当我从测试页面(无论是在同一台机器上还是在不同的机器上)调用我的 web 服务时,即使我没有提供证书,web 服务也会做出积极响应
    • 好的,我的代码中有一个逻辑错误(客户端调用与服务器代码在同一个项目上,它直接调用服务器代码,而不是实例化 Web 服务引用并从那里执行函数)和我修好了。现在我遇到了相反的问题,我无法从 WS 得到正确的回应 - 我总是被禁止
    猜你喜欢
    • 2020-12-28
    • 2020-06-15
    • 2016-06-27
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 2011-04-13
    • 1970-01-01
    相关资源
    最近更新 更多