2016-04-12 3 views
0

Die funktionalen Anforderungen sind diese:Wie führe ich einen Client-authentifizierten HTTPS-POST innerhalb von VBA durch, wenn der Server ein selbstsigniertes Zertifikat verwendet?

  • Verwenden HTTP POST-Daten von „Inhaltssteuer“ in Word zu einer Apache-Website außerhalb des Unternehmens-Firewall zu übertragen, wenn der Benutzer auf eine Schaltfläche klickt.
  • Die externe Website wird von mir kontrolliert und befindet sich in der "Internet Zone".
  • Die Lösung kann keine Softwareinstallation auf dem Computer des Benutzers erfordern (daher die Auswahl von VBA und eines Makro-aktivierten Office-Dokuments).
  • Der VBA-Code muss für jeden in meiner Organisation mit den Standardsicherheitseinstellungen funktionieren, die von unserer IT-Abteilung bereitgestellt werden.
  • Die externe Website verwendet ein selbstsigniertes SSL-Zertifikat.
  • Benutzer authentifizieren die externe Website mit ihrer PIV-Karte
  • Die PIV-Karte jedes Benutzers verfügt über mehrere Zertifikate für genau das gleiche Thema (sie) ausgestellt, von denen nur einer die richtige Schlüsselverwendung für die Client-Authentifizierung hat.

die oben angegebene, muss die Lösung zwei Dinge handhaben, entweder automatisch oder durch Benutzerinteraktion:

  • Interact mit der Website trotz des selbstsignierten SSL-Zertifikats.
  • Wählen Sie das richtige Client-Zertifikat von der Smartcard des Benutzers zur Authentifizierung aus.

Mein erster Versuch war, das WinHTTPRequest-Objekt zu verwenden. Ich konnte es so konfigurieren, dass der Fehler des selbstsignierten Server-Certs ignoriert wurde. Die Methode "SetClientCertificate" sucht jedoch nur nach Zertifikatssubjekt (und Zertifikatspeicher, aber alle befinden sich im selben Zertifikatspeicher). Manchmal funktioniert dieser Ansatz, manchmal nicht, je nachdem, welches Zertifikat die Kriterien tatsächlich erfüllt. Diese Methode wird für mich funktionieren, wenn ich: 1) herausfinden kann, wie man nach anderen Zertifikatsattributen sucht (erweiterte Schlüsselverwendung, Betreff-Name); oder 2] herausfinden, wie WinHTTPRequest die Zertifikatsauswahl für den Benutzer anzeigen kann.

Zweiter Versuch ist, die WinHTTPRequest Zeug zu werfen und das InternetExplorer Objekt zu verwenden. Für diesen Ansatz muss ich sicherstellen, dass die Visible-Eigenschaft wahr ist, damit der Benutzer mit dem Prozess interagieren kann. Ich konnte nicht herausfinden, wie ich die IE-Seite "Es gibt ein Problem mit der Seite dieses Zertifikats" deaktivieren kann, daher muss der Benutzer das manuell behandeln. IE zeigt automatisch die Zertifikatauswahl an und fordert zur Eingabe der PIN auf. Leider wird beim Umleiten auf die SSL-Seite der POST in ein GET umgewandelt. Außerdem habe ich Event-Handler für BeforeNavigate2, NavigationComplete2, DocumentComplete und TitleChange installiert, alle mit einfachen Debug-Print-Anweisungen. Das einzige Ereignis, das ausgelöst werden kann, ist BeforeNavigate2.

Sofort den gleichen Aufruf der "IEPostStringRequest" -Methode erneut überspringt die SSL-Warnumleitung und verwendet ordnungsgemäß die POST-Methode anstelle von GET.

Die offensichtliche hacky Problemumgehung, um die beschriebene scattershot Funktionalität und Bugs zu ersetzen, ist die zweite Methode zu verwenden und die IEPostStringRequest Funktion zweimal aufzurufen. Ich möchte jedoch fragen, ob es einen besseren Weg gibt, um gleichzeitig mit den zwei Dingen umzugehen, die die Lösung bewältigen muss.

Also, gibt es eine Möglichkeit, diese Arbeit zu machen, die die beschriebene Problemumgehung nicht beinhaltet?

Meine Klassenmodul für die zweite Option:

Option Explicit 

Private WithEvents ie As InternetExplorer 

Public Sub Init() 
    Set ie = CreateObject("InternetExplorer.Application") 
    'You can uncoment Next line To see form results As HTML 
    ie.Visible = True 
End Sub 

Private Sub ie_TitleChange(ByVal sText As String) 
    Debug.Print "Title changed to: " + sText 
End Sub 


Private Sub ie_NavigateComplete2(ByVal pDisp As Object, Url As Variant) 
    Debug.Print "Navigation to " + Url + " Complete" 
End Sub 

Private Sub ie_BeforeNavigate2(ByVal pDisp As Object, _ 
    ByRef Url As Variant, _ 
    ByRef Flags As Variant, _ 
    ByRef TargetFrameName As Variant, _ 
    ByRef PostData As Variant, _ 
    ByRef Headers As Variant, _ 
    ByRef Cancel As Boolean) 

    Debug.Print "Going to " + Url 
    Debug.Print "Headers: " + Headers 
End Sub 

Private Sub ie_DocumentComplete(ByVal pDisp As Object, Url As Variant) 
    Debug.Print Url 
End Sub 

'sends URL encoded form data To the URL using IE 
Public Sub IEPostStringRequest(Url, FormData) 
    'Send the form data To URL As POST request 
    Dim bFormData() As Byte 
    ReDim bFormData(Len(FormData) - 1) 
    bFormData = StrConv(FormData, vbFromUnicode) 
    ie.Navigate Url, 2 + 4 + 8, Nothing, bFormData, _ 
     "Content-type: application/x-www-form-urlencoded" 
End Sub 

Antwort

0

nur eine Seite Kommentar. Warum verwenden Sie kein SSL-Zertifikat von Let's https://letsencrypt.org/ verschlüsseln. So erhalten Sie nicht die Selbstanzeige Warnung.

Verwandte Themen