方法: セキュリティ トークン サービスを作成する
セキュリティ トークン サービスは、WS-Trust 仕様に定義されているプロトコルを実装します。 このプロトコルでは、セキュリティ トークンの発行、更新、キャンセル、および検証を行うためのメッセージ形式とメッセージ交換パターンが定義されています。 セキュリティ トークン サービスでは、これらの機能が 1 つ以上提供されます。 ここでは、最も一般的なシナリオであるトークンの発行の実装について説明します。
トークンの発行
WS-Trust は、トークンを発行するための RequestSecurityToken
XML スキーマ定義言語 (XSD: XML Schema Definition Language) スキーマ要素および RequestSecurityTokenResponse
XSD スキーマ要素に基づいたメッセージ形式を定義しています。 また、関連するアクション URI (Uniform Resource Identifier) も定義しています。 RequestSecurityToken
メッセージに関連付けられているアクション URI は http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue
です。 RequestSecurityTokenResponse
メッセージに関連付けられているアクション URI は http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue
です。
要求メッセージの構造
発行要求メッセージの構造は、通常、次の項目で構成されます。
値が
http://schemas.xmlsoap.org/ws/2005/02/trust/Issue
である "要求の種類" URI。"トークンの種類" URI。 Security Assertion Markup Language (SAML) 1.1 トークンの場合、この URI の値は
http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1
です。発行済みトークンに関連付けられるキーのビット数を示すキー サイズの値。
"キーの種類" URI。 対称キーの場合、この URI の値は
http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey
です。
さらに、2 つの項目が含まれている必要があります。
クライアントによって提供されたキー マテリアル。
発行済みトークンが使用されるターゲット サービスを示すスコープ情報。
セキュリティ トークン サービスは、発行応答メッセージを作成する際に、発行要求メッセージの情報を使用します。
応答メッセージの構造
発行応答メッセージの構造は、通常、次の項目で構成されます。
発行済みセキュリティ トークン (例 : SAML 1.1 アサーション)。
セキュリティ トークンに関連付けられた証明トークン。 対称キーでは、多くの場合、これは暗号化されたキー マテリアルです。
発行済みセキュリティ トークンへの参照。 通常、セキュリティ トークン サービスが返す参照は、2 とおりに使用できます。1 つは、クライアントによって送信された後続のメッセージ内に、発行済みトークンが存在する場合で、もう 1 つは、後続のメッセージ内にトークンが存在しない場合です。
さらに、2 つの項目が含まれている必要があります。
セキュリティ トークン サービスによって提供されたキー マテリアル。
共有キーを計算するために必要なアルゴリズム。
発行済みトークンの有効期間情報。
要求メッセージの処理
セキュリティ トークン サービスは、要求メッセージのさまざまな部分を検査し、要求を満たすトークンを発行できることを確認することによって発行要求を処理します。 セキュリティ トークン サービスは、発行するトークンを作成する前に次のことを確認する必要があります。
要求が、実際に発行されるトークンに対する要求であること。
要求されたトークンの種類をセキュリティ トークン サービスがサポートしていること。
要求を行う権限が要求者にあること。
キー マテリアルに関する要求者の期待にセキュリティ トークン サービスが応えられること。
トークンを作成する際には、トークンの署名に使用されるキーと共有キーの暗号化に使用されるキーの 2 つを決定することが重要です。 トークンに署名が必要なのは、クライアントがターゲット サービスにトークンを提示する際に、そのサービスが、そのトークンを発行したのが信頼されるセキュリティ トークン サービスであると判定できるようにするためです。 キー マテリアルは、ターゲット サービスが復号化できる方法で暗号化される必要があります。
SAML アサーションに署名する処理では、SigningCredentials インスタンスを作成します。 このクラスのコンストラクターは、次のものを受け取ります
SAML アサーションに署名するために使用する SecurityKey。
使用する署名アルゴリズムを識別する文字列。
使用するダイジェスト アルゴリズムを識別する文字列。
アサーションの署名に使用されるキーを識別する SecurityKeyIdentifier (必要な場合)。
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
共有キーを暗号化する処理では、キー マテリアルを受け取り、それをターゲット サービスが共有キーの復号化に使用できるキーで暗号化します。 通常は、ターゲット サービスの公開キーが使用されます。
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
さらに、暗号化されたキーの SecurityKeyIdentifier も必要です。
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
最後に、この SecurityKeyIdentifier を使用して、SamlSubject
を 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
詳細については、「フェデレーション サンプル」を参照してください。
応答メッセージの作成
セキュリティ トークン サービスによって発行要求が処理され、発行されるトークンと証明キーが作成されたら、少なくとも、要求されたトークン、証明トークン、および発行されたトークンの参照を含む応答メッセージを作成する必要があります。 発行済みトークンは、通常、SamlSecurityToken から作成された SamlAssertion です。次の例を参照してください。
SecurityToken CreateIssuedToken(SamlAssertion assertion)
{
return new SamlSecurityToken(assertion);
}
Function CreateIssuedToken(ByVal assertion As SamlAssertion) As SecurityToken
Return New SamlSecurityToken(assertion)
End Function
セキュリティ トークン サービスによって共有キー マテリアルが提供される場合は、BinarySecretSecurityToken を作成することにより、証明トークンが作成されます。
BinarySecretSecurityToken CreateProofToken(byte[] proofKey)
{
return new BinarySecretSecurityToken(proofKey);
}
Function CreateProofToken(ByVal proofKey() As Byte) As BinarySecretSecurityToken
Return New BinarySecretSecurityToken(proofKey)
End Function
クライアントとセキュリティ トークン サービスの両方によって共有キーのキー マテリアルが提供される場合の証明トークンの作成方法については、「フェデレーション サンプル」を参照してください。
発行済みトークンの参照を作成するには、SecurityKeyIdentifierClause クラスのインスタンスを作成します。
SecurityKeyIdentifierClause CreateTokenReference(SamlSecurityToken token)
{
return token.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>();
}
Function CreateTokenReference(ByVal token As SamlSecurityToken) _
As SecurityKeyIdentifierClause
Return token.CreateKeyIdentifierClause( _
Of SamlAssertionKeyIdentifierClause)()
End Function
最後に、これらの値を、クライアントに返される応答メッセージにシリアル化します。
例
セキュリティ トークン サービスの完全なコードについては、「フェデレーション サンプル」を参照してください。