Vorgehensweise: Erstellen eines Sicherheitstokendiensts

Ein Sicherheitstokendienst implementiert das in der WS-Trust-Spezifikation definierte Protokoll. Dieses Protokoll definiert Meldungsformate und Meldungsaustauschmuster zum Herausgeben, Erneuern, Abbrechen und Überprüfen von Sicherheitstoken. Ein angegebener Sicherheitstokendienst stellt eine oder mehrere dieser Fähigkeiten zur Verfügung. Dieses Thema behandelt das am häufigsten verwendete Szenario: das Implementieren der Tokenausstellung.

Ausstellen von Token

WS-Trust definiert Meldungsformate basierend auf dem RequestSecurityToken-XSD-Schemaelement (XML Schema Definition Language) und dem RequestSecurityTokenResponse-XSD-Schemaelement zum Durchführen der Tokenausstellung. Außerdem definiert WS-Trust die zugeordneten Aktions-URIs (Action Uniform Resource Identifiers). Der der RequestSecurityToken Nachricht zugeordnete Aktions-URI ist http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue. Der der RequestSecurityTokenResponse Nachricht zugeordnete Aktions-URI ist http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue.

Anforderungsmeldungsstruktur

Die Anforderungsmeldungsstruktur für Probleme besteht normalerweise aus den folgenden Elementen:

  • Ein Anforderungstyp-URI mit dem Wert http://schemas.xmlsoap.org/ws/2005/02/trust/Issue.

  • Ein Tokentyp-URI Für SAML-Token (Security Assertions Markup Language) 1.1 ist der Wert dieses URI http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1.

  • Ein Schlüsselgrößenwert, der die Anzahl der Bits im Schlüssel angibt, der dem ausgestellten Token zugeordnet werden soll.

  • Ein Schlüsseltyp-URI Für symmetrische Schlüssel ist http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKeyder Wert dieses URI .

Außerdem könnten ein paar andere Elemente vorhanden sein:

  • Schlüsselmaterial, das vom Client bereitgestellt wird

  • Umfangsinformationen, die den Zieldienst angeben, mit dem das ausgestellte Token verwendet wird

Der Sicherheitstokendienst verwendet die Informationen in der Problemanforderungsmeldung für die Erstellung der Problemantwortmeldung.

Antwortmeldungsstruktur

Die Antwortmeldungsstruktur für Probleme besteht normalerweise aus den folgenden Elementen:

  • dem ausgestellten Sicherheitstoken, z. B. eine SAML 1.1-Assertion

  • einem dem Sicherheitstoken zugeordnete Prüftoken. Für symmetrische Schlüssel ist dies oft eine verschlüsselte Form des Schlüsselmaterials.

  • Verweise auf das ausgestellte Sicherheitstoken Der Sicherheitstokendienst gibt normalerweise einen Verweis zurück, der verwendet werden kann, wenn das ausgestellte Token in einer vom Client gesendeten nachfolgenden Meldung angezeigt wird, und einen Verweis, der verwendet werden kann, wenn das Token in nachfolgenden Meldungen nicht vorhanden ist.

Außerdem könnten ein paar andere Elemente vorhanden sein:

  • Vom Sicherheitstokendienst bereitgestelltes Schlüsselmaterial

  • Der zum Berechnen des freigegebenen Schlüssels benötigte Algorithmus

  • Lebensdauerinformationen für das ausgestellte Token.

Verarbeiten von Anforderungsmeldungen

Der Sicherheitstokendienst verarbeitet die Problemanforderung durch Untersuchen der verschiedenen Teile der Anforderungsmeldung und durch Sicherstellen der Ausstellung eines Tokens, das der Anforderung entspricht. Der Sicherheitstokendienst muss Folgendes bestimmen, bevor er das auszustellende Token erstellt:

  • Die Anforderung ist tatsächlich eine Anforderung für ein auszustellendes Token.

  • Der Sicherheitstokendienst unterstützt den angeforderten Tokentyp.

  • Der Anforderungsdienst wird zum Erstellen der Anforderungen autorisiert.

  • Der Sicherheitstokendienst kann den Erwartungen des Anforderungsdiensts in Bezug auf das Schlüsselmaterial entsprechen.

Zwei wichtige Teile beim Erstellen eines Tokens bestehen im Bestimmen des Schlüssels, mit dem das Token signiert werden soll, und des Schlüssels, mit dem der freigegebene Schlüssel verschlüsselt werden soll. Das Token muss signiert werden, damit der Dienst ermitteln kann, ob das Token von einem Sicherheitstokendienst ausgestellt wurde, dem er vertraut, wenn der Client dem Zieldienst das Token bereitstellt. Das Schlüsselmaterial muss in einer Art und Weise verschlüsselt werden, dass der Zieldienst das Schlüsselmaterial entschlüsseln kann.

Das Signieren einer SAML-Assertion schließt das Erstellen einer SigningCredentials-Instanz ein. Der Konstruktor für diese Klasse kann Folgendes sein:

  • Ein SecurityKey für den Schlüssel zum Signieren der SAML-Assertion

  • Eine Zeichenfolge, die den zu verwendenden Signaturalgorithmus identifiziert

  • Eine Zeichenfolge, die den zu verwendenden Hashwertalgorithmus identifiziert

  • Optional ein SecurityKeyIdentifier, der den Schlüssel identifiziert, der zum Signieren der Assertion verwendet werden soll.

void AddSigningCredentials(SamlAssertion assertion, SecurityKey signingKey)
{
    SigningCredentials sc = new SigningCredentials(signingKey,
        SecurityAlgorithms.RsaSha1Signature, SecurityAlgorithms.Sha1Digest);
    assertion.SigningCredentials = sc;
}
Sub AddSigningCredentials(ByVal assertion As SamlAssertion, _
    ByVal signingKey As SecurityKey)
    Dim sc As New SigningCredentials(signingKey, _
    SecurityAlgorithms.RsaSha1Signature, SecurityAlgorithms.Sha1Digest)
    assertion.SigningCredentials = sc

End Sub

Das Verschlüsseln des freigegebenen Schlüssels schließt das Verschlüsseln des Schlüsselmaterials mit einem Schlüssel ein, den der Zieldienst zum Entschlüsseln des freigegeben Schlüssels verwenden kann. Normalerweise wird der öffentliche Schlüssel des Zieldiensts verwendet.

byte[] EncryptKey(byte[] plainTextKey, SecurityKey encryptingKey)
{
    return encryptingKey.EncryptKey(SecurityAlgorithms.RsaOaepKeyWrap, plainTextKey);
}
Function EncryptKey(ByVal plainTextKey() As Byte, _
        ByVal encryptingKey As SecurityKey) As Byte()
    Return encryptingKey.EncryptKey(SecurityAlgorithms.RsaOaepKeyWrap, plainTextKey)
End Function

Außerdem wird ein SecurityKeyIdentifier für den verschlüsselten Schlüssel benötigt.

SecurityKeyIdentifier GetKeyIdentifierForEncryptedKey(byte[] encryptedKey,
    SecurityToken encryptingToken)
{
    SecurityKeyIdentifier encryptingKeyIdentifier = new SecurityKeyIdentifier(encryptingToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>());
    return new SecurityKeyIdentifier(new EncryptedKeyIdentifierClause(encryptedKey, SecurityAlgorithms.RsaOaepKeyWrap, encryptingKeyIdentifier));
}
Function GetKeyIdentifierForEncryptedKey(ByVal encryptedKey() _
 As Byte, ByVal encryptingToken As SecurityToken) _
    As SecurityKeyIdentifier
    Dim encryptingKeyIdentifier As New SecurityKeyIdentifier( _
        encryptingToken.CreateKeyIdentifierClause(Of X509ThumbprintKeyIdentifierClause)())
    Return New SecurityKeyIdentifier(New EncryptedKeyIdentifierClause( _
        encryptedKey, SecurityAlgorithms.RsaOaepKeyWrap, encryptingKeyIdentifier))
End Function

Dieser SecurityKeyIdentifier wird dann zum Erstellen eines SamlSubject als Teil des SamlToken verwendet.

SamlSubject CreateSamlSubjectForProofKey(SecurityKeyIdentifier proofKeyIdentifier)
{
    List<string> confirmations = new List<string>();

    confirmations.Add("urn:oasis:names:tc:SAML:1.0:cm:holder-of-key");

    return new SamlSubject(null, null, "IssuerName", confirmations, null, proofKeyIdentifier);
}
Function CreateSamlSubjectForProofKey( _
    ByVal proofKeyIdentifier As SecurityKeyIdentifier) As SamlSubject
    Dim confirmations As List(Of String) = New List(Of String)()
    confirmations.Add("urn:oasis:names:tc:SAML:1.0:cm:holder-of-key")
    Return New SamlSubject(Nothing, Nothing, "IssuerName", _
        confirmations, Nothing, proofKeyIdentifier)
End Function

Weitere Informationen finden Sie unter Verbundbeispiel.

Erstellen von Antwortmeldungen

Sobald der Sicherheitstokendienst die Problemanforderung verarbeitet und das auszustellende Token zusammen mit dem Prüfschlüssel erstellt, muss die Antwortmeldung erstellt werden, die mindestens das angeforderte Token, das Prüftoken und die ausgestellten Tokenverweise enthalten muss. Das ausgestellte Token ist normalerweise ein aus der SamlSecurityToken erstelltes SamlAssertion, wie im folgenden Beispiel gezeigt.

SecurityToken CreateIssuedToken(SamlAssertion assertion)
{
    return new SamlSecurityToken(assertion);
}
Function CreateIssuedToken(ByVal assertion As SamlAssertion) As SecurityToken
    Return New SamlSecurityToken(assertion)
End Function

Wenn der Sicherheitstokendienst das freigegebene Schlüsselmaterial bereitstellt, wird das Prüftoken durch Erstellen eines BinarySecretSecurityToken erstellt.

BinarySecretSecurityToken CreateProofToken(byte[] proofKey)
{
    return new BinarySecretSecurityToken(proofKey);
}
Function CreateProofToken(ByVal proofKey() As Byte) As BinarySecretSecurityToken
    Return New BinarySecretSecurityToken(proofKey)

End Function

Weitere Informationen zum Erstellen des Nachweistokens, wenn der Client und der Sicherheitstokendienst beide Schlüsselmaterial für den freigegebenen Schlüssel bereitstellen, finden Sie unter Verbundbeispiel.

Die ausgestellten Tokenverweise werden durch Erstellen von Instanzen der SecurityKeyIdentifierClause-Klasse erstellt.

SecurityKeyIdentifierClause CreateTokenReference(SamlSecurityToken token)
{
    return token.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>();
}
Function CreateTokenReference(ByVal token As SamlSecurityToken) _
    As SecurityKeyIdentifierClause
    Return token.CreateKeyIdentifierClause( _
    Of SamlAssertionKeyIdentifierClause)()
End Function

Diese verschiedenen Werte werden dann in der Antwortmeldung, die an den Client zurückgegeben wird, serialisiert.

Beispiel

Den vollständigen Code für einen Sicherheitstokendienst finden Sie unter Verbundbeispiel.

Siehe auch