SAML Token Security
Policies
The
LoginByToken
sample creates a
custom policy assertion that is derived from the .NET class
SecurityPolicyAssertion
. The
assertion class gives the .NET framework access to the SAML token and the X509
certificate.
The sample performs the following operations to
set up the security policy and message handling.
- Sets theServicePointManagerproperties to specify SSL3 and HTTP 100-Continue response handling. 100-Continue response handling supports more efficient communication between the client and vCenter server. When the client-side .NET framework sends a request to the server, it sends the request header and waits for a 100-Continue response from the server. After it receives that response, it sends the request body to the server.
- Creates anX509Certificate2object, specifies the certificate file, and imports the certificate. The certificate file specification indicates a PKCS #12 format file (Public-Key Cryptography Standards) –PfxCertificateFile. The file contains the client’s private key and public certificate. ThePfxCertificateFilesetting is defined in theapp.configfile in theLoginByTokenproject. The definition specifies the location of the file.
- Creates a custom security assertion to store the SAML token and the certificate. The token and certificate will be included in the policy data for theLoginByTokenrequest.
- Defines a custom output filter that is derived from the .NET classSendSecurityFilter.
Custom Security
Assertion
The following example shows the
LoginByTokenSample
class
method
GetSecurityPolicyAssertionForHokToken
. The
method returns a
CustomSecurityAssertionHok
instance which overrides the .NET class
SecurityPolicyAssertion
. The
security assertion contains the SAML token and the X509 certificate token. This
code is taken from the
LoginByToken
project file
samples/LoginByToken/CustomSecurityAssertionHok.cs.
Setting Up Security Policies
private SecurityPolicyAssertion GetSecurityPolicyAssertionForHokToken(XmlElement xmlToken) { //When this property is set to true, client requests that use the POST method //expect to receive a 100-Continue response from the server to indicate that //the client should send the data to be posted. This mechanism allows clients //to avoid sending large amounts of data over the network when the server, //based on the request headers, intends to reject the request ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; X509Certificate2 certificateToBeAdded = new X509Certificate2(); string certificateFile = ConfigurationManager.AppSettings["PfxCertificateFile"]; string password = ConfigurationManager.AppSettings["PfxCertificateFilePassword"]; certificateToBeAdded.Import(certificateFile, password ?? string.Empty, X509KeyStorageFlags.MachineKeySet); var customSecurityAssertion = new CustomSecurityAssertionHok(); customSecurityAssertion.BinaryToken = xmlToken; customSecurityAssertion.TokenType = strSamlV2TokenType; customSecurityAssertion.SecurityToken = new X509SecurityToken(certificateToBeAdded); return customSecurityAssertion; }
Custom Output Filter
for a vCenter Single Sign-On Client
A vCenter Single Sign-On client provides a
custom output filter for the custom security assertion. The custom filter
provides three methods:
- CustomSecurityClientOutputFilterHok class constructor – Creates token and message signature objects for the SOAP message.
- SecureMessage—An override method for the .NET methodSendSecurityFilter.SecureMessage. The override method adds the SAML token and message signature to the .NET Security element.
- CreateKeyInfoSignatureElement – Creates an XML document that specifies the SAML token type and ID.
The following code example demonstrates how to
create a custom output filter.
Output Filter for the Custom
SecurityPolicyAssertion
internal class CustomSecurityClientOutputFilterHok : SendSecurityFilter { IssuedToken issuedToken = null; string samlAssertionId = null; MessageSignature messageSignature = null; /// Create a custom SOAP request filter. /// (Save the token and certificate.) public CustomSecurityClientOutputFilterHok(CustomSecurityAssertionHok parentAssertion) : base(parentAssertion.ServiceActor, true) { issuedToken = new IssuedToken(parentAssertion.BinaryToken, parentAssertion.TokenType); samlAssertionId = parentAssertion.BinaryToken.Attributes.GetNamedItem("ID").Value; messageSignature = new MessageSignature(parentAssertion.SecurityToken); } /// Secure the SOAP message before its sent to the server. public override void SecureMessage(SoapEnvelope envelope, Security security) { //create KeyInfo XML element messageSignature.KeyInfo = new KeyInfo(); messageSignature.KeyInfo.LoadXml(CreateKeyInfoSignatureElement()); security.Tokens.Add(issuedToken); security.Elements.Add(messageSignature); } /// Helper method to create a custom key info signature element. /// Returns Key info XML element. private XmlElement CreateKeyInfoSignatureElement() { var xmlDocument = new XmlDocument(); xmlDocument.LoadXml(@"<root><SecurityTokenReference xmlns=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"" xmlns:wsse=""http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"" wsse:TokenType=""http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0""> <KeyIdentifier xmlns=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"" ValueType=""http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID"">" + samlAssertionId + @"</KeyIdentifier></SecurityTokenReference></root>"); return xmlDocument.DocumentElement; } }