Instrukcje: Tworzenie usługi tokenów zabezpieczeń
Usługa tokenu zabezpieczającego implementuje protokół zdefiniowany w specyfikacji WS-Trust. Ten protokół definiuje formaty komunikatów i wzorce wymiany komunikatów na potrzeby wystawiania, odnawiania, anulowania i weryfikowania tokenów zabezpieczających. Dana usługa tokenu zabezpieczającego zapewnia co najmniej jedną z tych funkcji. W tym temacie przedstawiono najbardziej typowy scenariusz: implementowanie wystawiania tokenów.
Tokeny wystawiające
WS-Trust definiuje formaty komunikatów na RequestSecurityToken
podstawie elementu schematu XML schema language (XSD) i RequestSecurityTokenResponse
elementu schematu XSD do wystawiania tokenów. Ponadto definiuje skojarzone identyfikatory URI (Action Uniform Resource Identifiers). Identyfikator URI akcji skojarzony z komunikatem RequestSecurityToken
to http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue
. Identyfikator URI akcji skojarzony z komunikatem RequestSecurityTokenResponse
to http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue
.
Struktura komunikatów żądania
Struktura komunikatów żądania problemu zwykle składa się z następujących elementów:
Identyfikator URI typu żądania z wartością
http://schemas.xmlsoap.org/ws/2005/02/trust/Issue
.Identyfikator URI typu tokenu. W przypadku tokenów SAML (Security Assertions Markup Language) 1.1 wartość tego identyfikatora URI to
http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1
.Wartość rozmiaru klucza wskazująca liczbę bitów w kluczu do skojarzenia z wystawionym tokenem.
Identyfikator URI typu klucza. W przypadku kluczy symetrycznych wartość tego identyfikatora URI to
http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey
.
Ponadto może istnieć kilka innych elementów:
Kluczowy materiał dostarczony przez klienta.
Informacje o zakresie wskazujące usługę docelową, z którą będzie używany wystawiony token.
Usługa tokenu zabezpieczającego używa informacji w komunikacie żądania problemu podczas konstruowania komunikatu odpowiedzi na problem.
Struktura komunikatów odpowiedzi
Struktura komunikatów odpowiedzi na problem zwykle składa się z następujących elementów;
Wystawiony token zabezpieczający, na przykład asercji SAML 1.1.
Token dowodowy skojarzony z tokenem zabezpieczającym. W przypadku kluczy symetrycznych jest to często zaszyfrowana forma materiału klucza.
Odwołania do wystawionego tokenu zabezpieczającego. Zazwyczaj usługa tokenu zabezpieczającego zwraca odwołanie, które może być używane, gdy wystawiony token pojawia się w kolejnym komunikacie wysłanym przez klienta i innym, który może być używany, gdy token nie jest obecny w kolejnych komunikatach.
Ponadto może istnieć kilka innych elementów:
Materiał klucza udostępniany przez usługę tokenu zabezpieczającego.
Algorytm potrzebny do obliczenia klucza współużytkowanego.
Informacje o okresie istnienia wystawionego tokenu.
Przetwarzanie komunikatów żądań
Usługa tokenu zabezpieczającego przetwarza żądanie problemu, sprawdzając różne elementy komunikatu żądania i upewniając się, że może wystawiać token spełniający żądanie. Usługa tokenu zabezpieczającego musi określić następujące elementy, zanim skonstruuje token do wystawienia:
Żądanie jest naprawdę żądaniem wystawienia tokenu.
Usługa tokenu zabezpieczającego obsługuje żądany typ tokenu.
Osoba żądający ma autoryzację do wykonania żądania.
Usługa tokenu zabezpieczającego może spełniać oczekiwania żądającego w odniesieniu do kluczowych materiałów.
Dwie istotne części konstruowania tokenu określają klucz do podpisania tokenu za pomocą i klucz do zaszyfrowania klucza współużytkowanego. Token musi być podpisany, aby gdy klient przedstawi token usłudze docelowej, usługa może określić, że token został wystawiony przez usługę tokenu zabezpieczającego, któremu ufa. Materiał klucza musi być zaszyfrowany w taki sposób, aby usługa docelowa mogła odszyfrować ten materiał klucza.
Podpisywanie asercji SAML obejmuje utworzenie SigningCredentials wystąpienia. Konstruktor dla tej klasy przyjmuje następujące elementy:
Wartość SecurityKey dla klucza używanego do podpisywania asercji SAML.
Ciąg identyfikujący algorytm podpisu do użycia.
Ciąg identyfikujący algorytm mieszania do użycia.
Opcjonalnie element SecurityKeyIdentifier identyfikujący klucz używany do podpisywania asercji.
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
Szyfrowanie klucza wspólnego obejmuje pobranie materiału klucza i zaszyfrowanie go za pomocą klucza, którego usługa docelowa może użyć do odszyfrowania klucza wspólnego. Zazwyczaj jest używany klucz publiczny usługi docelowej.
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
Ponadto SecurityKeyIdentifier potrzebny jest element dla zaszyfrowanego klucza.
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
Następnie SecurityKeyIdentifier jest on używany do utworzenia SamlSubject
elementu w ramach elementu 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
Aby uzyskać więcej informacji, zobacz Przykład federacji.
Tworzenie komunikatów odpowiedzi
Gdy usługa tokenu zabezpieczającego przetworzy żądanie problemu i skonstruuje token, który ma zostać wystawiony wraz z kluczem dowodowym, należy skonstruować komunikat odpowiedzi, w tym co najmniej żądany token, token dowodowy i wystawione odwołania do tokenu. Wystawiony token jest zazwyczaj tworzony na SamlSecurityToken podstawie SamlAssertionelementu , jak pokazano w poniższym przykładzie.
SecurityToken CreateIssuedToken(SamlAssertion assertion)
{
return new SamlSecurityToken(assertion);
}
Function CreateIssuedToken(ByVal assertion As SamlAssertion) As SecurityToken
Return New SamlSecurityToken(assertion)
End Function
W przypadku, gdy usługa tokenu zabezpieczającego udostępnia materiał klucza współużytkowanego, token dowodowy jest konstruowany przez utworzenie elementu BinarySecretSecurityToken.
BinarySecretSecurityToken CreateProofToken(byte[] proofKey)
{
return new BinarySecretSecurityToken(proofKey);
}
Function CreateProofToken(ByVal proofKey() As Byte) As BinarySecretSecurityToken
Return New BinarySecretSecurityToken(proofKey)
End Function
Aby uzyskać więcej informacji na temat konstruowania tokenu dowodowego, gdy klient i usługa tokenu zabezpieczającego zapewniają materiał klucza dla klucza współużytkowanego, zobacz Przykład federacji.
Wystawione odwołania do tokenu są tworzone przez utworzenie wystąpień SecurityKeyIdentifierClause klasy.
SecurityKeyIdentifierClause CreateTokenReference(SamlSecurityToken token)
{
return token.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>();
}
Function CreateTokenReference(ByVal token As SamlSecurityToken) _
As SecurityKeyIdentifierClause
Return token.CreateKeyIdentifierClause( _
Of SamlAssertionKeyIdentifierClause)()
End Function
Te różne wartości są następnie serializowane w komunikacie odpowiedzi zwróconym do klienta.
Przykład
Pełny kod usługi tokenu zabezpieczającego można znaleźć w temacie Federation Sample (Przykład federacji).