【发布时间】: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