コード例 #1
0
        private PersonUser GetLocalUsers(string userName, string domain, WsSecurityContext wsSecurityContext)
        {
            // Invoke SSO Admin FindPersonUserAsync operation
            var personUser = wsSecurityContext.
                             InvokeOperation(() =>
                                             _ssoAdminBindingClient.FindPersonUserAsync(
                                                 new ManagedObjectReference {
                type  = "SsoAdminPrincipalDiscoveryService",
                Value = "principalDiscoveryService"
            },
                                                 new SsoPrincipalId {
                name   = userName,
                domain = domain
            })).Result;

            return(new PersonUser(this)
            {
                Name = personUser.id.name,
                Domain = personUser.id.domain,
                Description = personUser.details.description,
                FirstName = personUser.details.firstName,
                LastName = personUser.details.lastName,
                EmailAddress = personUser.details.emailAddress
            });
        }
コード例 #2
0
        /// <summary>
        /// Acquires Holder of Key Token by Username and Password.
        /// HoK token issuance requires Clients to
        /// 1. Sign AcquireToken Request with the  private key of their Signing Certificate
        /// 2. To present the public key of the Signing Certificate to the Authorization Server in the AcquireToken Request
        /// 3. Authorization Server validate the request signature is signed with the private key of the presented public key
        /// This way Authorization Server ensures request is not modified and the client has the private key corresponding the public key.
        /// HoK tokens are valid for longer period of time compared to the bearer tokens.
        /// HoK tokens can be used to acquire baerer tokens on behalf of the subject. This way servers
        /// can keep HoK and issue Bearer Tokens with which to present the Subject to other services.
        /// 4. HoK token can be delegetable to delegate authorization to other services to act on behalf of the subject.
        /// User authorizes one service to act on his behalf against another server
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="signingCertitificate">The Signing Certificate of the client that will be used to sign the request and present the public key to the Authorization Server</param>
        /// <param name="actAsSamlToken">Act As Saml token</param>
        /// <returns>Raw XML representation of the SAML 2.0 HoK Token</returns>
        public XmlElement IssueActAsHoKTokenByUserCredential(
            string username,
            SecureString password,
            X509Certificate2 signingCertitificate,
            XmlElement actAsSamlToken)
        {
            if (username == null)
            {
                throw new ArgumentNullException("username");
            }

            // SAML Token Request
            var securityTokenRequest = new RequestSecurityTokenType {
                RequestType          = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue",
                TokenType            = "urn:oasis:names:tc:SAML:2.0:assertion",
                KeyType              = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey",
                ActAs                = actAsSamlToken,
                DelegatableSpecified = true,
                Delegatable          = true,
                Renewing             = new RenewingType {
                    AllowSpecified = true,
                    Allow          = true,
                    OKSpecified    = true,
                    OK             = true
                },
                SignatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
            };

            // Security Token Request Authorization Header
            var securityContext = new WsSecurityContext {
                ClientChannel = _stsServiceClient.InnerChannel,
                Properties    =
                {
                    Credentials           =
                    {
                        User     = username,
                        Password = password,
                        // Certificate which will be used by the Authorization Server to validate the signature of the request
                        ClientCertificate = signingCertitificate
                    },
                    // This Key will be used to sign the request
                    SigningKey            = signingCertitificate.PrivateKey
                }
            };

            // Request Authorization Server to Issue HoK Token
            IssueResponse response =
                securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result);

            // Extract the Raw XML Token from the Authorizations Server's Response
            return((XmlElement)
                   response.
                   RequestSecurityTokenResponseCollection.
                   RequestSecurityTokenResponse.
                   Items[0]);
        }
コード例 #3
0
        /// <summary>
        /// Acquires Bearer Token by Username and Password.
        /// Bearer Token is short lived token that can be presented to the resource server
        /// to authorize the request to access the resource. Typically used by
        /// clients to authorize their requests to the server.
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns>Raw XML representation of the SAML 2.0 Bearer Token</returns>
        public XmlElement IssueBearerTokenByUserCredential(
            string username,
            SecureString password)
        {
            if (username == null)
            {
                throw new ArgumentNullException("username");
            }

            if (password == null)
            {
                throw new ArgumentNullException("password");
            }

            // SAML Token Request
            var securityTokenRequest = new RequestSecurityTokenType {
                RequestType          = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue",
                TokenType            = "urn:oasis:names:tc:SAML:2.0:assertion",
                KeyType              = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer",
                Lifetime             = null,
                Delegatable          = true,
                DelegatableSpecified = true
            };

            // Security Token Request Authorization Header
            var securityContext = new WsSecurityContext {
                ClientChannel = _stsServiceClient.InnerChannel,
                Properties    =
                {
                    Credentials  =
                    {
                        User     = username,
                        Password = password
                    }
                }
            };

            // Request Authorization Server to Issue Bearer Token
            IssueResponse response =
                securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result);

            // Extract the Raw XML Token from the Authorizations Server's Response
            return((XmlElement)
                   response.
                   RequestSecurityTokenResponseCollection.
                   RequestSecurityTokenResponse.
                   Items[0]);
        }
コード例 #4
0
        /// <summary>
        /// Requests STS to validate given SAML Token
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public bool ValidateToken(XmlElement token)
        {
            var securityTokenRequest = new RequestSecurityTokenType {
                RequestType    = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Validate",
                TokenType      = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR/Status",
                ValidateTarget = token
            };

            var securityContext = new WsSecurityContext {
                ClientChannel = _stsServiceClient.InnerChannel
            };

            var response =
                securityContext.InvokeOperation(() => _stsServiceClient.ValidateAsync(securityTokenRequest).Result);

            // Check Saml Token Status is valid
            return(((StatusType)response.RequestSecurityTokenResponse.Items[0]).Code == "http://docs.oasis-open.org/ws-sx/ws-trust/200512/status/valid");
        }
コード例 #5
0
        private WsSecurityContext CreateAuthorizedInvocationContext()
        {
            // Issue Bearer token to authorize create solution user to SSO Admin service
            var bearerToken = _securityContext.GetToken();

            // Set WS Trust Header Serialization with issued bearer SAML token
            var securityContext = new WsSecurityContext {
                ClientChannel = _ssoAdminBindingClient.InnerChannel,
                Properties    =
                {
                    Credentials     =
                    {
                        BearerToken = bearerToken
                    }
                }
            };

            return(securityContext);
        }
コード例 #6
0
        /// <summary>
        /// Acquires Bearer Token by HoK Token.
        /// This is the use-case of server that holds HoK token to issue bearer token and
        /// use them to authorize requests to other services.
        /// </summary>
        /// <param name="hokToken"></param>
        /// <param name="signingCertitificate"></param>
        /// <returns></returns>
        public XmlElement IssueBearerTokenByHoKToken(
            XmlElement hokToken,
            X509Certificate2 signingCertitificate)
        {
            if (hokToken == null)
            {
                throw new ArgumentNullException("hokToken");
            }

            // SAML Token Request
            var securityTokenRequest = new RequestSecurityTokenType {
                RequestType          = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue",
                TokenType            = "urn:oasis:names:tc:SAML:2.0:assertion",
                KeyType              = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer",
                Lifetime             = null,
                Delegatable          = true,
                DelegatableSpecified = true
            };

            // Security Token Request Authorization Header
            var securityContext = new WsSecurityContext {
                ClientChannel = _stsServiceClient.InnerChannel,
                Properties    =
                {
                    Credentials          =
                    {
                        HolderOfKeyToken = hokToken
                    },
                    SigningKey           = signingCertitificate.PrivateKey
                }
            };

            // Request Authorization Server to Issue HoK Token
            IssueResponse response =
                securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result);

            // Extract the Raw XML Token from the Authorizations Server's Response
            return((XmlElement)
                   response.
                   RequestSecurityTokenResponseCollection.
                   RequestSecurityTokenResponse.
                   Items[0]);
        }
コード例 #7
0
        public void DeleteService(
            string ssoUsername,
            SecureString ssoPassword,
            string serviceId)
        {
            // Issue Bearer token by user and password fort service registration operation
            var bearerToken = _stsClient.IssueBearerTokenByUserCredential(ssoUsername, ssoPassword);

            // Retrieve Service Content
            var svcContent = _lsClient.RetrieveServiceContentAsync(RootMoRef).Result;

            // Set WS Trust Header Serialization with issued bearer SAML token
            var securityContext = new WsSecurityContext {
                ClientChannel = _lsClient.InnerChannel,
                Properties    =
                {
                    Credentials     =
                    {
                        BearerToken = bearerToken
                    }
                }
            };

            LookupServiceRegistrationInfo serviceFound = null;

            // Try Get Service with specified Id
            try {
                serviceFound = _lsClient.GetAsync(
                    svcContent.serviceRegistration,
                    serviceId).
                               Result;
            } catch (Exception) {
            }

            if (serviceFound != null)
            {
                // Delete Service
                securityContext.InvokeOperation(() => _lsClient.DeleteAsync(
                                                    svcContent.serviceRegistration,
                                                    serviceId).Wait());
            }
        }
コード例 #8
0
        /// <summary>
        /// Acquires Holder of Key Token by Certificate.
        /// HoK token issuance requires Clients to
        /// 1. Sign AcquireToken Request with the  private key of their Signing Certificate
        /// 2. To present the public key of the Signing Certificate to the Authorization Server in the AcquireToken Request
        /// 3. Authorization Server validate the request signature is signed with the private key of the presented public key
        /// This way Authorization Server ensures request is not modified and the client has the private key corresponding the public key.
        /// HoK tokens are valid for longer period of time compared to the bearer tokens.
        /// HoK tokens can be used to acquire bearer tokens on behalf of the subject. This way servers
        /// can keep HoK and issue Bearer Tokens with which to present the Subject to other services.
        /// 4. HoK token can be delegatable to delegate authorization to other services to act on behalf of the subject.
        /// User authorizes one service to act on his behalf against another server
        /// </summary>
        /// <param name="signingCertitificate">Solution user certificate</param>
        /// <param name="lifetimeSpan"></param>
        /// <returns>Raw XML representation of the SAML 2.0 HoK Token</returns>
        public XmlElement IssueHoKTokenByCertificate(
            X509Certificate2 signingCertitificate,
            TimeSpan?lifetimeSpan = null)
        {
            // SAML Token Request
            var securityTokenRequest = new RequestSecurityTokenType {
                RequestType          = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue",
                TokenType            = "urn:oasis:names:tc:SAML:2.0:assertion",
                KeyType              = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey",
                Lifetime             = GetLifetime(lifetimeSpan),
                DelegatableSpecified = true,
                Delegatable          = true,
                SignatureAlgorithm   = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
            };

            // Security Token Request Authorization Header
            var securityContext = new WsSecurityContext {
                ClientChannel = _stsServiceClient.InnerChannel,
                Properties    =
                {
                    Credentials           =
                    {
                        // Certificate which will be used by the Authorization Server to validate the signature of the request
                        ClientCertificate = signingCertitificate
                    },
                    // This Key will be used to sign the request
                    SigningKey            = signingCertitificate.PrivateKey
                }
            };

            // Request Authorization Server to Issue HoK Token
            IssueResponse response =
                securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result);

            // Extract the Raw XML Token from the Authorizations Server's Response
            return((XmlElement)
                   response.
                   RequestSecurityTokenResponseCollection.
                   RequestSecurityTokenResponse.
                   Items[0]);
        }
コード例 #9
0
        /// <summary>
        /// Renew token. This operation allows a long-lvide task operation to scheduled in a service
        /// giving the server a renewable token. Then the service can renew the token before use it
        /// to authorize access for the operation.
        /// Use-case: https://wiki.eng.vmware.com/SSO/UseCases#Scheduling_long_lived_task_.28delegation_.2B_renew.29
        /// </summary>
        /// <param name="renewableToken"></param>
        /// <param name="signingCertificate"></param>
        /// <param name="lifetime"></param>
        /// <returns></returns>
        public XmlElement RenewToken(
            XmlElement renewableToken,
            X509Certificate2 signingCertificate,
            TimeSpan?lifetime = null)
        {
            if (renewableToken == null)
            {
                throw new ArgumentNullException("renewableToken");
            }

            var securityTokenRequest = new RequestSecurityTokenType {
                RequestType = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Renew",
                TokenType   = "urn:oasis:names:tc:SAML:2.0:assertion",
                RenewTarget = renewableToken,
                Lifetime    = GetLifetime(lifetime)
            };

            var securityContext = new WsSecurityContext {
                ClientChannel = _stsServiceClient.InnerChannel,
                Properties    =
                {
                    Credentials           =
                    {
                        ClientCertificate = signingCertificate
                    },
                    SigningKey            = signingCertificate.PrivateKey
                }
            };


            RenewResponse response =
                securityContext.InvokeOperation(() => _stsServiceClient.RenewAsync(securityTokenRequest).Result);

            return((XmlElement)
                   response.
                   RequestSecurityTokenResponse.
                   Items[0]);

            #endregion
        }
コード例 #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="hokToken"></param>
        /// <param name="signingCertificate"></param>
        /// <returns></returns>
        public XmlElement IssueHoKTokenByHoKToken(
            XmlElement hokToken,
            X509Certificate2 signingCertificate)
        {
            if (hokToken == null)
            {
                throw new ArgumentNullException("hokToken");
            }

            var securityTokenRequest = new RequestSecurityTokenType {
                RequestType          = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue",
                TokenType            = "urn:oasis:names:tc:SAML:2.0:assertion",
                KeyType              = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey",
                SignatureAlgorithm   = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512",
                DelegatableSpecified = true,
                Delegatable          = true
            };

            var securityContext = new WsSecurityContext {
                ClientChannel = _stsServiceClient.InnerChannel,
                Properties    =
                {
                    Credentials          =
                    {
                        HolderOfKeyToken = hokToken
                    },
                    SigningKey           = signingCertificate.PrivateKey
                }
            };

            IssueResponse response =
                securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result);

            return((XmlElement)
                   response.
                   RequestSecurityTokenResponseCollection.
                   RequestSecurityTokenResponse.
                   Items[0]);
        }
コード例 #11
0
        private WsSecurityContext CreateAuthorizedInvocationContext(
            string authorizationUsername,
            SecureString authorizationPassword)
        {
            // Issue Bearer token to authorize create solution user to SSO Admin service
            var bearerToken = _stsClient.IssueBearerTokenByUserCredential(
                authorizationUsername,
                authorizationPassword);

            // Set WS Trust Header Serialization with issued bearer SAML token
            var securityContext = new WsSecurityContext {
                ClientChannel = _ssoAdminClient.InnerChannel,
                Properties    =
                {
                    Credentials     =
                    {
                        BearerToken = bearerToken
                    }
                }
            };

            return(securityContext);
        }
コード例 #12
0
        private DataTypes.Group FindGroup(string name, string domain, WsSecurityContext wsSecurityContext)
        {
            // Invoke SSO Admin FindGroupAsync operation
            var group = wsSecurityContext.
                        InvokeOperation(() =>
                                        _ssoAdminBindingClient.FindGroupAsync(
                                            new ManagedObjectReference
            {
                type  = "SsoAdminPrincipalDiscoveryService",
                Value = "principalDiscoveryService"
            },
                                            new SsoPrincipalId
            {
                name   = name,
                domain = domain
            })).Result;

            return(new DataTypes.Group(this)
            {
                Name = group.id.name,
                Domain = group.id.domain,
                Description = group.details.description
            });
        }
コード例 #13
0
        public void RegisterService(
            string ssoUsername,
            SecureString ssoPassword,
            string nodeId,
            string ownerId,
            string serviceDescriptionResourceKey,
            string serviceId,
            string serviceNameResourceKey,
            string serviceVersion,
            string serviceTypeProduct,
            string serviceTypeType,
            string endpointUrl,
            string endpointProtocol,
            string endpointType,
            X509Certificate2 sslTrustCertificate)
        {
            // Issue Bearer token by user and password fort service registration operation
            var bearerToken = _stsClient.IssueBearerTokenByUserCredential(ssoUsername, ssoPassword);

            // Populate Register Service Spec
            var serviceRegistrationCreateSpec = new LookupServiceRegistrationCreateSpec
            {
                serviceType = new LookupServiceRegistrationServiceType
                {
                    product = serviceTypeProduct,
                    type    = serviceTypeType
                },
                nodeId  = nodeId,
                ownerId = ownerId,
                serviceDescriptionResourceKey = serviceDescriptionResourceKey,
                serviceNameResourceKey        = serviceNameResourceKey,
                serviceVersion   = serviceVersion,
                serviceEndpoints = new[] {
                    new LookupServiceRegistrationEndpoint {
                        url          = endpointUrl,
                        sslTrust     = new[] { Convert.ToBase64String(sslTrustCertificate.RawData) },
                        endpointType = new LookupServiceRegistrationEndpointType {
                            protocol = endpointProtocol,
                            type     = endpointType
                        }
                    }
                }
            };

            // Retrieve Service Content
            var svcContent = _lsClient.RetrieveServiceContentAsync(RootMoRef).Result;

            // Set WS Trust Header Serialization with issued bearer SAML token
            var securityContext = new WsSecurityContext
            {
                ClientChannel = _lsClient.InnerChannel,
                Properties    =
                {
                    Credentials     =
                    {
                        BearerToken = bearerToken
                    }
                }
            };

            // Register Service
            securityContext.InvokeOperation(() => _lsClient.CreateAsync(
                                                svcContent.serviceRegistration,
                                                serviceId,
                                                serviceRegistrationCreateSpec).Wait());
        }
コード例 #14
0
        /// <summary>
        /// Acquires delegate to HoK token by another solution HoK token.
        /// This method issues Token delegated to
        /// service with id <param name="delegateToServiceId"></param> which is registered in the
        /// SSO with solution user <param name="delegateToSolutionUser"></param>
        /// https://wiki.eng.vmware.com/SSO/UseCases#Executing_tasks_on_behalf_of_an_user_.28delegation.29
        /// </summary>
        /// <param name="hokToken"></param>
        /// <param name="signingCertitificate"></param>
        /// <param name="delegateToServiceId"></param>
        /// <param name="delegateToSolutionUser"></param>
        /// <param name="renewableOk">True to allow token to be renewed after it has expired. Default is false, it is recommended to remain with default value.</param>
        /// <returns>Raw XML representation of the SAML 2.0 DelegateTo token</returns>
        public XmlElement IssueDelegateToHoKTokenBySolutionHoK(
            XmlElement hokToken,
            X509Certificate2 signingCertificate,
            string delegateToServiceId,
            string delegateToSolutionUser,
            TimeSpan?lifetime = null,
            bool?renewable    = null,
            bool renewableOk  = false)
        {
            // SAML Token Request
            var securityTokenRequest = new RequestSecurityTokenType {
                RequestType = @"http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue",
                TokenType   = "urn:oasis:names:tc:SAML:2.0:assertion",
                KeyType     = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey",
                Lifetime    = GetLifetime(lifetime),
                DelegateTo  = new DelegateToType {
                    UsernameToken = new UsernameTokenType {
                        Id       = $"Id-{Guid.NewGuid().ToString()}",
                        Username = new AttributedString {
                            Id    = $"Id-{delegateToServiceId}",
                            Value = delegateToSolutionUser
                        }
                    },
                },
                DelegatableSpecified = true,
                Delegatable          = true,
                SignatureAlgorithm   = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
            };

            if (renewable != null)
            {
                securityTokenRequest.Renewing = new RenewingType {
                    Allow          = renewable.Value,
                    AllowSpecified = true,
                    OK             = renewableOk,
                    OKSpecified    = true,
                };
            }

            // Security Token Request Authorization Header
            var securityContext = new WsSecurityContext {
                ClientChannel = _stsServiceClient.InnerChannel,
                Properties    =
                {
                    Credentials          =
                    {
                        HolderOfKeyToken = hokToken
                    },
                    SigningKey           = signingCertificate.PrivateKey
                }
            };

            // Request Authorization Server to Issue HoK Token
            IssueResponse response =
                securityContext.InvokeOperation(() => _stsServiceClient.IssueAsync(securityTokenRequest).Result);

            // Extract the Raw XML Token from the Authorizations Server's Response
            return((XmlElement)
                   response.
                   RequestSecurityTokenResponseCollection.
                   RequestSecurityTokenResponse.
                   Items[0]);
        }
コード例 #15
0
        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            // Retrieve the security context if specified
            var securityContext = WsSecurityContext.GetProperties(request);

            if (securityContext == null)
            {
                // exit with unmodified message
                return(null);
            }

            ValidateSecurityContext(securityContext);

            // Working with the message in XML form
            XmlDocument soapRequest = GetXmlMessage(request);

            // Setting an ID to the body to be able to reference it in the signature (to be able to sign it)
            string bodyId = CreateElementId(BODY_ID_PREFIX);

            SetIdToBodyElement(soapRequest.DocumentElement, bodyId);

            SecurityHeader wsSecurityHeader = GetBasicUnsignedHeader();

            if (!String.IsNullOrEmpty(securityContext.Credentials.User))
            {
                AppendUserNameToken(
                    wsSecurityHeader,
                    securityContext.Credentials.User,
                    securityContext.Credentials.Password);
            }

            // A SecurityTokenReference XmlElement which contains the reference to signing client certificate.
            XmlElement keyIdentifierClause = null;

            if (securityContext.Credentials.BearerToken != null)
            {
                // No signature is used for Bearer token security context
                wsSecurityHeader.SamlToken = securityContext.Credentials.BearerToken;
            }
            else if (securityContext.Credentials.HolderOfKeyToken != null)
            {
                // For HoK token context, the signing certificate is contained within the HoK SAML token
                XmlElement hokToken = securityContext.Credentials.HolderOfKeyToken;
                wsSecurityHeader.SamlToken = hokToken;
                keyIdentifierClause        = GetKeyIdentifierClause(hokToken);
            }
            else if (securityContext.Credentials.ClientCertificate != null)
            {
                // Append local certificate info as a BinarySecurityToken child
                // element of the WS Security header and save a reference to it.
                keyIdentifierClause = AppendBinarySecurityToken(wsSecurityHeader, securityContext.Credentials.ClientCertificate);
            }

            // Converting the sso header from object to xml to easily assign xml values to properties.
            XmlElement securityHeaderXml = Util.ToXmlElement(wsSecurityHeader);

            // Attaching the header without the signature
            var ssoHeaderElement = MergeMessageWithHeader(
                soapRequest.DocumentElement,
                securityHeaderXml);

            if (keyIdentifierClause != null)
            {
                // This should already be ensured by ValidateSecurityContext() method
                Debug.Assert(securityContext.SigningKey != null);

                // Compute signature for timestamp and body elements and add the signature element to the security header.

                var signature = Util.ComputeSignature(
                    soapRequest,
                    keyIdentifierClause,
                    securityContext.SigningKey,
                    bodyId,
                    wsSecurityHeader.Timestamp.Id);

                ssoHeaderElement.AppendChild(signature);
            }

            // Convert the SOAP request back to a message that replaces the original message
            request = ToMessage(soapRequest, request.Version, request.Headers.Action, request.Properties);


            // No need to correlate requests with replays for this inspector.
            return(null);
        }