Partager via


Procédure : créer un service d’émission de jeton de sécurité

Un service de jeton de sécurité implémente le protocole défini dans la spécification WS-Trust. Ce protocole définit des formats de message et des modèles d’échange de message pour émettre, renouveler, annuler et valider des jetons de sécurité. Un service de jeton de sécurité donné fournit une ou plusieurs de ces fonctions. Cette rubrique examine le scénario le plus courant : l'implémentation de l'émission de jeton.

Émission de jetons

La spécification WS-Trust définit des formats de message, basés sur l'élément de schéma XSD (XML Schema Definition) RequestSecurityToken et sur l'élément de schéma XSD RequestSecurityTokenResponse pour réaliser une émission de jetons. De plus, elle définit les URI (Uniform Resource Identifier) d'action associés. L’URI d’action associé au message RequestSecurityToken est http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue. L’URI d’action associé au message RequestSecurityTokenResponse est http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue.

Structure d'un message de demande

La structure d'un message de demande d'émission se compose en général des éléments suivants :

  • URI de type de requête avec la valeur http://schemas.xmlsoap.org/ws/2005/02/trust/Issue.

  • Un URI de type de jeton. Pour les jetons SAML (Security Assertions Markup Language) 1.1, la valeur de cet URI est http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1.

  • Une valeur de taille de clé qui indique le nombre de bits inclus dans la clé à associer au jeton émis.

  • Un URI de type de clé. Pour les clés symétriques, la valeur de cet URI est http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey.

De plus, plusieurs autres éléments peuvent être présents :

  • Le matériel de clé fourni par le client.

  • Des informations d'étendue qui indiquent avec quel service cible le jeton émis sera utilisé.

Le service de jeton de sécurité utilise les informations incluses dans le message de demande d'émission lorsqu'il construit le message de réponse d'émission.

Structure d'un message de réponse

La structure d'un message de réponse d'émission se compose en général des éléments suivants :

  • Le jeton de sécurité émis, par exemple, une assertion SAML 1.1.

  • Un jeton de preuve associé au jeton de sécurité. Pour des clés symétriques, il s'agit souvent d'une forme chiffrée du matériel de clé.

  • Des références au jeton de sécurité émis. En général, le service de jeton de sécurité retourne une référence qui peut être utilisée lorsque le jeton émis apparaît dans un message ultérieur envoyé par le client et une autre référence qui peut être utilisée lorsque le jeton n'est pas présent dans les messages ultérieurs.

De plus, plusieurs autres éléments peuvent être présents :

  • Le matériel de clé fourni par le service de jeton de sécurité.

  • L'algorithme requis pour calculer la clé partagée.

  • Les informations de durée de vie du jeton émis.

Traitement des messages de demande

Le service de jeton de sécurité traite la demande d'émission en examinant les différents éléments du message de demande et en s'assurant qu'il peut émettre un jeton satisfaisant la demande. Le service de jeton de sécurité doit déterminer les éléments suivants avant de créer le jeton à émettre :

  • La demande est vraiment une demande d'émission de jeton.

  • Le service de jeton de sécurité prend en charge le type de jeton demandé.

  • Le demandeur est autorisé à faire la demande.

  • Le service de jeton de sécurité peut satisfaire les attentes du demandeur en ce qui concerne le matériel de clé.

Deux parties essentielles de la construction d'un jeton correspondent à la détermination de la clé utilisée pour signer le jeton et de la clé utilisée pour chiffrer la clé partagée. Le jeton doit être signé pour que, lorsque le client présente le jeton au service cible, ce service puisse déterminer que le jeton a été émis par un service de jeton de sécurité qu'il approuve. Le matériel de clé doit être chiffré de telle façon que le service cible puisse le déchiffrer.

La signature d'une assertion SAML implique la création d'une instance SigningCredentials. Le constructeur pour cette classe utilise les éléments suivants :

  • Un SecurityKey pour la clé à utiliser pour signer l'assertion SAML.

  • Une chaîne qui identifie l'algorithme de signature à utiliser.

  • Une chaîne qui identifie l’algorithme de condensat à utiliser.

  • En option, un SecurityKeyIdentifier qui identifie la clé à utiliser pour signer l'assertion.

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

Le chiffrement de la clé partagée implique le traitement du matériel de clé et son chiffrement avec une clé que le service cible peut utiliser pour déchiffrer la clé partagée. En général, la clé publique du service cible est utilisée.

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

De plus, un objet SecurityKeyIdentifier pour la clé chiffrée est requis.

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

Ensuite, cet objet SecurityKeyIdentifier est utilisé pour créer un SamlSubject dans le cadre du SamlToken.

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

Pour plus d’informations, consultez la section Exemple de fédération.

Création de messages de réponse

Une fois que le service de jeton de sécurité traite la demande d'émission et construit le jeton à émettre avec la clé de vérification, le message de réponse doit être construit, qui inclut au moins le jeton demandé, le jeton de preuve et des références au jeton émis. Le jeton émis est en général un SamlSecurityToken créé à partir de SamlAssertion, comme le montre l'exemple ci-dessous.

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

Dans le cas où le service de jeton de sécurité fournit le matériel de clé partagée, le jeton de preuve est construit en créant un BinarySecretSecurityToken.

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

End Function

Pour plus d’informations sur la façon de construire le jeton de preuve lorsque le client et le service de jeton de sécurité fournissent tous les deux du matériel de clé pour la clé partagée, consultez Exemple de fédération.

Les références au jeton émis sont construites en créant des instances de la classe SecurityKeyIdentifierClause.

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

Ensuite, ces différentes valeurs sont sérialisées dans le message de réponse retourné au client.

Exemple

Pour obtenir le code complet pour un service de jeton de sécurité, consultez Exemple de fédération.

Voir aussi