2016-04-08 14 views
0

Ok, also habe ich nach einer Lösung für mein Problem für ein paar Tage gesucht und habe fast nichts gefunden. Hier ist das Problem: Ich muss ein SSL-Zertifikat an eine Website in IIS 6 anhängen. Ich kann die HTTPS-Bindung festlegen, aber jedes Mal, wenn ich versuche, den Fingerabdruck des Zertifikats und den Zertifikatspeicher für die Bindung festzulegen, erhalte ich COM-Ausnahmen. Hier ist mein Code.Attach SSL-Zertifikat an der Website in IIS programmatisch

Private Const UnformattedMetabasePathForSiteProperties As String = "IIS://localhost/W3SVC/{0}" 
    Private metabasePath As String 
    Public Sub BindCertificateToSite(iisSiteId As Integer, ByVal aCertificate As X509Certificate2) Implements IIisSslHandler.BindCertificatetoSite 
     metabasePath = UnformattedMetabasePathForSiteProperties.FormatIt(iisSiteId) 
     Dim ipAddress As String = GetProperty(metabasePath, "ServerBindings") 
     Contract.Require(Not String.IsNullOrEmpty(ipAddress), New Exception("Failed to find the site's http binding and IP address. Can not bind certificate to site.")) 
     ipAddress = ipAddress.Split(":")(0) 
     SetProperty(metabasePath, "SecureBindings", ipAddress & ":443:", True) 
     SetProperty(metabasePath, "SSLStoreName", "MY", True) 
     SetBinaryProperty(metabasePath, "SSLCertHash", aCertificate.Thumbprint, True) 
    End Sub 

    Private Sub SetProperty(ByVal metabasePath As String, ByVal propertyName As String, ByVal newValue As Object, clearCurrentValue As Boolean) 
     Dim path As DirectoryEntry 
     path = New DirectoryEntry(metabasePath) 
     If clearCurrentValue Then path.Properties(propertyName).Clear() 
     path.Properties(propertyName).Add(newValue) 
     path.CommitChanges() 
    End Sub 

    Private Sub SetBinaryProperty(ByVal metabasePath As String, ByVal propertyName As String, ByVal newValue As Object, clearCurrentValue As Boolean) 
     Dim path As DirectoryEntry 
     path = New DirectoryEntry(metabasePath) 
     Dim propValues As PropertyValueCollection 
     propValues = path.Properties(propertyName) 
     If clearCurrentValue Then propValues.Clear() 
     propValues.Add(newValue) 
     path.CommitChanges() 
    End Sub 

Die Ausnahmen ich ocurrs am propValues.Add Ruf sowohl für die SSLStoreName und der SSLCertHash

SSLStoreName exception: An exception of type 'System.Runtime.InteropServices.COMException' occurred in System.DirectoryServices.dll but was not handled in user code. Additional information: A specified logon session does not exist. It may already have been terminated. (Exception from HRESULT: 0x80070520) 

SSLCertHash Exception: An exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll but was not handled in user code. Additional information: Exception from HRESULT: 0x8000500C 

ich andere Fragen hier auf den Stack und anderen Seiten im Netz gefunden haben, scheinen weisen auf einen Fehler im .Net-Framework hin, wenn es um IIS 6 geht, aber ich hoffe, dass das hier nicht der Fall ist. Also meine Frage: Warum funktioniert das nicht und wie kann ich es reparieren?

+0

Die Cert-Hash-Ausnahme, von dem, was ich gefunden habe, zeigt auf einen ungültigen Datentyp. Aber ich habe jeden Typ ausprobiert, an den ich denken kann. MSDN sagt seine Binärdaten ... –

Antwort

0

Ok, ich habe es endlich geschafft zu arbeiten. Als solche poste ich diesen Code für zukünftige Stapler und mich.

Private Const UnformattedMetabasePathForSiteProperties As String = "IIS://localhost/W3SVC/{0}" 
Private metabasePath As String 
Public Sub BindCertificateToSite(iisSiteId As Integer, ByVal aCertificate As X509Certificate2) Implements IIisSslHandler.BindCertificatetoSite 
    metabasePath = UnformattedMetabasePathForSiteProperties.FormatIt(iisSiteId) 
    Dim ipAddress As String = GetProperty(metabasePath, "ServerBindings") 
    Contract.Require(Not String.IsNullOrEmpty(ipAddress), New Exception("Failed to find the site's http binding and IP address. Can not bind certificate to site.")) 
    ipAddress = ipAddress.Split(":")(0) 
    SetProperty(metabasePath, "SecureBindings", ipAddress & ":443:", True) 
    SetProperty(metabasePath, "SSLStoreName", "MY", True) 
    SetBinaryProperty(metabasePath, "SSLCertHash", aCertificate.GetCertHash(), True) 
End Sub 

Private Sub SetProperty(ByVal metabasePath As String, ByVal propertyName As String, ByVal newValue As Object, clearCurrentValue As Boolean) 
    Dim path As DirectoryEntry 
    path = New DirectoryEntry(metabasePath) 
    If clearCurrentValue Then path.Properties(propertyName).Clear() 
    path.Invoke("Put", propertyName, newValue) 
    path.CommitChanges() 
End Sub 

Private Sub SetBinaryProperty(ByVal metabasePath As String, ByVal propertyName As String, ByVal newValue As Object, clearCurrentValue As Boolean) 
    Dim path As DirectoryEntry 
    path = New DirectoryEntry(metabasePath) 
    Dim propValues As PropertyValueCollection 
    propValues = path.Properties(propertyName) 
    If clearCurrentValue Then propValues.Clear() 
    path.Invoke("Put", propertyName, newValue) 
    path.CommitChanges() 
End Sub 
+0

Nur eine Anmerkung. Mit dem Tod von IIS 6 letzten Sommer sollten die meisten Programmierer zur Microsoft.Web.Administration.dll-basierten API für IIS 7+ wechseln. –

+0

Ich stimme Ihnen vollkommen zu. Wie auch immer meine Anforderungen lauten, verwende ich sowohl die IIS 6- als auch die 7-Code-Methodologie - also diese Lösung und benutze diese DLL, um die gleiche Aufgabe zu erledigen - IIS 7 war viel einfacher zu programmieren. –