Arbeiten mit SSL in der Web-API
Mehrere gängige Authentifizierungsschemas sind über einfaches HTTP nicht sicher. Insbesondere senden die einfache Authentifizierung und Formularauthentifizierung unverschlüsselte Anmeldeinformationen. Um sicher zu sein, müssen diese Authentifizierungsschemas SSL verwenden. Darüber hinaus können SSL-Clientzertifikate zum Authentifizieren von Clients verwendet werden.
Aktivieren von SSL auf dem Server
So richten Sie SSL in IIS 7 oder höher ein:
- Erstellen oder Abrufen eines Zertifikats. Zum Testen können Sie ein selbstsigniertes Zertifikat erstellen.
- Fügen Sie eine HTTPS-Bindung hinzu.
Ausführliche Informationen finden Sie unter Einrichten von SSL in IIS 7.
Für lokale Tests können Sie SSL in IIS Express von Visual Studio aktivieren. Legen Sie im Eigenschaftenfenster SSL Enabled auf True fest. Notieren Sie sich den Wert der SSL-URL. Verwenden Sie diese URL zum Testen von HTTPS-Verbindungen.
Enforcing SSL in a Web API Controller (Erzwingen von SSL in einem Web-API-Controller)
Wenn Sie sowohl über eine HTTPS- als auch über eine HTTP-Bindung verfügen, können Clients weiterhin HTTP verwenden, um auf die Website zuzugreifen. Sie können zulassen, dass einige Ressourcen über HTTP verfügbar sind, während andere Ressourcen SSL erfordern. Verwenden Sie in diesem Fall einen Aktionsfilter, um SSL für die geschützten Ressourcen zu erfordern. Der folgende Code zeigt einen Web-API-Authentifizierungsfilter mit Überprüfung auf SSL:
public class RequireHttpsAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
{
ReasonPhrase = "HTTPS Required"
};
}
else
{
base.OnAuthorization(actionContext);
}
}
}
Fügen Sie diesen Filter allen Web-API-Aktionen hinzu, die SSL erfordern:
public class ValuesController : ApiController
{
[RequireHttps]
public HttpResponseMessage Get() { ... }
}
SSL-Clientzertifikate
SSL ermöglicht die Authentifizierung mithilfe von Public Key Infrastructure-Zertifikaten. Der Server muss ein Zertifikat bereitstellen, das den Server beim Client authentifiziert. Es ist weniger üblich, dass der Client dem Server ein Zertifikat bereitstellt, aber dies ist eine Option zum Authentifizieren von Clients. Um Clientzertifikate mit SSL zu verwenden, benötigen Sie eine Möglichkeit, signierte Zertifikate an Ihre Benutzer zu verteilen. Für viele Anwendungstypen ist dies keine gute Benutzeroberfläche, aber in einigen Umgebungen (z. B. Unternehmen) ist dies möglicherweise möglich.
Vorteile | Nachteile |
---|---|
- Zertifikatanmeldeinformationen sind stärker als Benutzername/Kennwort. - SSL bietet einen vollständigen sicheren Kanal mit Authentifizierung, Nachrichtenintegrität und Nachrichtenverschlüsselung. | – Sie müssen PKI-Zertifikate abrufen und verwalten. – Die Clientplattform muss SSL-Clientzertifikate unterstützen. |
Um IIS zum Akzeptieren von Clientzertifikaten zu konfigurieren, öffnen Sie den IIS-Manager, und führen Sie die folgenden Schritte aus:
Klicken Sie in der Strukturansicht auf den Standortknoten.
Doppelklicken Sie im mittleren Bereich auf das Feature SSL-Einstellungen .
Wählen Sie unter Clientzertifikate eine der folgenden Optionen aus:
- Akzeptieren: IIS akzeptiert ein Zertifikat vom Client, erfordert jedoch kein Zertifikat.
- Erforderlich: Erfordert ein Clientzertifikat. (Um diese Option zu aktivieren, müssen Sie auch "SSL anfordern" auswählen.
Sie können diese Optionen auch in der ApplicationHost.config-Datei festlegen:
<system.webServer>
<security>
<access sslFlags="Ssl, SslNegotiateCert" />
<!-- To require a client cert: -->
<!-- <access sslFlags="Ssl, SslRequireCert" /> -->
</security>
</system.webServer>
Das SslNegotiateCert-Flag bedeutet, dass IIS ein Zertifikat vom Client akzeptiert, aber kein Zertifikat erfordert (entspricht der Option "Accept" im IIS-Manager). Um ein Zertifikat zu benötigen, legen Sie das SslRequireCert-Flag fest. Zum Testen können Sie diese Optionen auch in IIS Express in der lokalen datei applicationhost.Config festlegen, die sich in "Documents\IISExpress\config" befindet.
Erstellen eines Clientzertifikats zum Testen
Zu Testzwecken können Sie MakeCert.exe verwenden, um ein Clientzertifikat zu erstellen. Erstellen Sie zunächst eine Teststammautorität:
makecert.exe -n "CN=Development CA" -r -sv TempCA.pvk TempCA.cer
Makecert fordert Sie auf, ein Kennwort für den privaten Schlüssel einzugeben.
Fügen Sie als Nächstes das Zertifikat dem Speicher "Vertrauenswürdige Stammzertifizierungsstellen" des Testservers wie folgt hinzu:
- Öffnen Sie MMC.
- Wählen Sie unter Dateidie Option Snap-In hinzufügen/entfernen aus.
- Wählen Sie Computerkonto aus.
- Wählen Sie Lokaler Computer aus, und schließen Sie den Assistenten ab.
- Erweitern Sie im Navigationsbereich den Knoten "Vertrauenswürdige Stammzertifizierungsstellen".
- Zeigen Sie im Menü Aktion auf Alle Aufgaben, und klicken Sie dann auf Importieren , um den Zertifikatimport-Assistenten zu starten.
- Navigieren Sie zur Zertifikatdatei TempCA.cer.
- Klicken Sie auf Öffnen, dann auf Weiter , und schließen Sie den Assistenten ab. (Sie werden aufgefordert, das Kennwort erneut einzugeben.)
Erstellen Sie nun ein Clientzertifikat, das vom ersten Zertifikat signiert ist:
makecert.exe -pe -ss My -sr CurrentUser -a sha1 -sky exchange -n "CN=name"
-eku 1.3.6.1.5.5.7.3.2 -sk SignedByCA -ic TempCA.cer -iv TempCA.pvk
Verwenden von Clientzertifikaten in der Web-API
Auf der Serverseite können Sie das Clientzertifikat abrufen, indem Sie GetClientCertificate für die Anforderungsnachricht aufrufen. Die Methode gibt NULL zurück, wenn kein Clientzertifikat vorhanden ist. Andernfalls wird eine X509Certificate2-instance zurückgegeben. Verwenden Sie dieses Objekt, um Informationen aus dem Zertifikat abzurufen, z. B. Aussteller und Antragsteller. Anschließend können Sie diese Informationen für die Authentifizierung und/oder Autorisierung verwenden.
X509Certificate2 cert = Request.GetClientCertificate();
string issuer = cert.Issuer;
string subject = cert.Subject;