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/SymmetricKey
der 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.