방법: 보안 토큰 서비스 만들기
보안 토큰 서비스에서는 WS-Trust 사양에 정의된 프로토콜을 구현합니다. 이 프로토콜은 보안 토큰의 발행, 갱신, 취소 및 유효성 검사를 위한 메시지 형식 및 메시지 교환 패턴을 정의합니다. 지정된 보안 토큰 서비스에서는 하나 이상의 이러한 기능을 제공합니다. 이 항목에서는 가장 일반적인 시나리오인 토큰 발급 구현에 대해 살펴봅니다.
토큰 발급
WS-Trust는 RequestSecurityToken XSD(XML 스키마 정의 언어) 스키마 요소에 따라 메시지 형식을 정의하고, 토큰 발행을 수행하기 위한 RequestSecurityTokenResponse XSD 스키마 요소를 정의합니다. 또한 연결된 동작 URI(Uniform Resource Identifier)도 정의합니다. RequestSecurityToken 메시지와 연결된 동작 URI는 https://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue입니다. RequestSecurityTokenResponse 메시지와 연결된 동작 URI는 https://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue입니다.
요청 메시지 구조
일반적으로 발행 요청 메시지 구조는 다음과 같은 항목으로 구성됩니다.
https://schemas.xmlsoap.org/ws/2005/02/trust/Issue의 값이 있는 요청 형식 URI
토큰 형식 URI. SAML(Security Assertions Markup Language) 1.1 토큰의 경우 이 URI의 값은 http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1\#SAMLV1.1입니다.
발행된 토큰과 연결될 키의 비트 수를 나타내는 키 크기 값
키 형식 URI. 대칭 키의 경우 이 URI의 값은 https://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey입니다.
또한 다음과 같은 몇 가지 다른 항목이 있을 수 있습니다.
클라이언트에서 제공하는 키 자료
발행된 토큰이 함께 사용될 대상 서비스를 나타내는 범위 정보
보안 토큰 서비스에서는 발행 응답 메시지를 만들 때 발행 요청 메시지의 정보를 사용합니다.
응답 메시지 구조
일반적으로 발행 응답 메시지 구조는 다음과 같은 항목으로 구성됩니다.
발행된 보안 토큰(예: SAML 1.1 어설션)
보안 토큰에 연결된 증명 토큰. 대칭 키의 경우 이 토큰이 키 자료의 암호화된 형식인 경우가 있습니다.
발행된 보안 토큰에 대한 참조. 일반적으로 보안 토큰 서비스에서는 발행된 토큰이 클라이언트가 보낸 다음 메시지에 나타나는 경우 사용할 수 있는 참조 및 해당 토큰이 다음 메시지에 나타나지 않는 경우 사용할 수 있는 다른 참조를 반환합니다.
또한 다음과 같은 몇 가지 다른 항목이 있을 수 있습니다.
보안 토큰 서비스에서 제공한 키 자료
공유 키를 계산하는 데 필요한 알고리즘
발행된 토큰에 대한 수명 정보
요청 메시지 처리
보안 토큰 서비스에서는 여러 요청 메시지를 조사하고 이 메시지에서 요청을 만족하는 토큰을 발행할 수 있음을 확인하여 발행 요청을 처리합니다. 보안 토큰 서비스는 발행할 토큰을 만들기 전에 다음 사항을 결정해야 합니다.
요청이 발행할 토큰에 대한 요청이 맞는지 여부
보안 토큰 서비스에서 요청된 토큰 형식을 지원하는지 여부
요청자가 요청을 할 수 있는 권한이 있는지 여부
보안 토큰 서비스가 키 자료에 대한 요청자의 기대치를 충족할 수 있는지 여부
토큰을 만드는 데 있어 중요한 두 가지 사항은 토큰을 서명할 때 사용할 키와 공유 키를 암호화할 때 사용할 키를 결정하는 것입니다. 클라이언트가 대상 서비스에 토큰을 제공하는 경우 해당 서비스가 신뢰하는 보안 토큰 서비스에서 토큰을 발행했음을 확인할 수 있도록 토큰에 서명해야 합니다. 키 자료는 대상 서비스에서 해당 키 자료를 해독할 수 있는 방식으로 암호화해야 합니다.
SAML 어설션에 서명하려면 SigningCredentials 인스턴스를 만들어야 합니다. 이 클래스의 생성자는 다음 항목이 필요합니다.
SAML 어설션에 서명하는 데 사용할 키에 대한 SecurityKey
사용할 서명 알고리즘을 식별하는 문자열
사용할 다이제스트 알고리즘을 식별하는 문자열
필요한 경우 어설션을 서명하는 데 사용할 키를 식별하는 SecurityKeyIdentifier
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
void AddSigningCredentials(SamlAssertion assertion, SecurityKey signingKey)
{
SigningCredentials sc = new SigningCredentials(signingKey,
SecurityAlgorithms.RsaSha1Signature, SecurityAlgorithms.Sha1Digest);
assertion.SigningCredentials = sc;
}
공유 키를 암호화하려면 키 자료가 필요하며, 대상 서비스에서 공유 키를 해독하는 데 사용할 수 있는 키를 사용하여 공유 키를 암호화해야 합니다. 일반적으로 대상 서비스의 공개 키가 사용됩니다.
Function EncryptKey(ByVal plainTextKey() As Byte, _
ByVal encryptingKey As SecurityKey) As Byte()
Return encryptingKey.EncryptKey(SecurityAlgorithms.RsaOaepKeyWrap, plainTextKey)
End Function
byte[] EncryptKey(byte[] plainTextKey, SecurityKey encryptingKey)
{
return encryptingKey.EncryptKey(SecurityAlgorithms.RsaOaepKeyWrap, plainTextKey);
}
또한 암호화된 키에 대한 SecurityKeyIdentifier가 필요합니다.
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 GetKeyIdentifierForEncryptedKey(byte[] encryptedKey,
SecurityToken encryptingToken)
{
SecurityKeyIdentifier encryptingKeyIdentifier = new SecurityKeyIdentifier(encryptingToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>());
return new SecurityKeyIdentifier(new EncryptedKeyIdentifierClause(encryptedKey, SecurityAlgorithms.RsaOaepKeyWrap, encryptingKeyIdentifier));
}
이 SecurityKeyIdentifier는 SamlSubject를 만드는 데 SamlToken의 일부로 사용됩니다.
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
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);
}
자세한 내용은 다음 항목을 참조하십시오. Federation 샘플을 참조하십시오.
응답 메시지 만들기
보안 토큰 서비스에서 발행 요청을 처리하고 증명 키와 함께 발행될 토큰을 만들면 적어도 요청된 토큰, 증명 토큰 및 발행된 토큰 참조를 포함하여 응답 메시지를 만들어야 합니다. 일반적으로 발행된 토큰은 다음 예제에서처럼 SamlAssertion에서 만들어진 SamlSecurityToken입니다.
Function CreateIssuedToken(ByVal assertion As SamlAssertion) As SecurityToken
Return New SamlSecurityToken(assertion)
End Function
SecurityToken CreateIssuedToken(SamlAssertion assertion)
{
return new SamlSecurityToken(assertion);
}
보안 토큰 서비스에서 공유 키 자료를 제공하는 경우에는 BinarySecretSecurityToken을 만들어 증명 토큰을 만듭니다.
Function CreateProofToken(ByVal proofKey() As Byte) As BinarySecretSecurityToken
Return New BinarySecretSecurityToken(proofKey)
End Function
BinarySecretSecurityToken CreateProofToken(byte[] proofKey)
{
return new BinarySecretSecurityToken(proofKey);
}
클라이언트와 보안 토큰 서비스에서 모두 공유 키 자료를 제공하는 경우 증명 토큰을 만드는 방법에 대한 자세한 내용은 Federation 샘플을 참조하십시오.
SecurityKeyIdentifierClause 클래스의 인스턴스를 만들어 발행된 토큰 참조를 만듭니다.
Function CreateTokenReference(ByVal token As SamlSecurityToken) _
As SecurityKeyIdentifierClause
Return token.CreateKeyIdentifierClause( _
Of SamlAssertionKeyIdentifierClause)()
End Function
SecurityKeyIdentifierClause CreateTokenReference(SamlSecurityToken token)
{
return token.CreateKeyIdentifierClause<SamlAssertionKeyIdentifierClause>();
}
이러한 여러 값은 클라이언트에 반환되는 응답 메시지로 serialize됩니다.
예제
보안 토큰 서비스의 전체 코드를 보려면 Federation 샘플을 참조하십시오.
참고 항목
작업
참조
SigningCredentials
SecurityKey
SecurityKeyIdentifier
SamlSecurityToken
SamlAssertion
BinarySecretSecurityToken
SecurityKeyIdentifierClause