/// <summary>
        /// Makes a WSTrust call to the STS to obtain a <see cref="SecurityToken"/> first checking if the token is available in the cache.
        /// </summary>
        /// <returns>A <see cref="GenericXmlSecurityToken"/>.</returns>
        protected override SecurityToken GetTokenCore(TimeSpan timeout)
        {
            WsTrustRequest  request       = CreateWsTrustRequest();
            WsTrustResponse trustResponse = GetCachedResponse(request);

            if (trustResponse is null)
            {
                using (var memeoryStream = new MemoryStream())
                {
                    var writer     = XmlDictionaryWriter.CreateTextWriter(memeoryStream, Encoding.UTF8);
                    var serializer = new WsTrustSerializer();
                    serializer.WriteRequest(writer, _requestSerializationContext.TrustVersion, request);
                    writer.Flush();
                    var             reader  = XmlDictionaryReader.CreateTextReader(memeoryStream.ToArray(), XmlDictionaryReaderQuotas.Max);
                    IRequestChannel channel = ChannelFactory.CreateChannel();
                    Message         reply   = channel.Request(Message.CreateMessage(MessageVersion.Soap12WSAddressing10, _requestSerializationContext.TrustActions.IssueRequest, reader));
                    SecurityUtils.ThrowIfNegotiationFault(reply, channel.RemoteAddress);
                    trustResponse = serializer.ReadResponse(reply.GetReaderAtBodyContents());
                    CacheSecurityTokenResponse(request, trustResponse);
                }
            }

            // Create GenericXmlSecurityToken
            // Assumes that token is first and Saml2SecurityToken.
            using (var stream = new MemoryStream())
            {
                RequestSecurityTokenResponse response = trustResponse.RequestSecurityTokenResponseCollection[0];

                // Get attached and unattached references
                GenericXmlSecurityKeyIdentifierClause internalSecurityKeyIdentifierClause = null;
                if (response.AttachedReference != null)
                {
                    internalSecurityKeyIdentifierClause = GetSecurityKeyIdentifierForTokenReference(response.AttachedReference);
                }

                GenericXmlSecurityKeyIdentifierClause externalSecurityKeyIdentifierClause = null;
                if (response.UnattachedReference != null)
                {
                    externalSecurityKeyIdentifierClause = GetSecurityKeyIdentifierForTokenReference(response.UnattachedReference);
                }

                // Get proof token
                IdentityModel.Tokens.SecurityToken proofToken = GetProofToken(request, response);

                // Get lifetime
                DateTime created = response.Lifetime?.Created ?? DateTime.UtcNow;
                DateTime expires = response.Lifetime?.Expires ?? created.AddDays(1);

                return(new GenericXmlSecurityToken(response.RequestedSecurityToken.TokenElement,
                                                   proofToken,
                                                   created,
                                                   expires,
                                                   internalSecurityKeyIdentifierClause,
                                                   externalSecurityKeyIdentifierClause,
                                                   null));
            }
        }
        private SecurityToken CreateGenericXmlSecurityToken(WsTrustRequest request, WsTrustResponse trustResponse)
        {
            // Create GenericXmlSecurityToken
            // Assumes that token is first and Saml2SecurityToken.
            RequestSecurityTokenResponse response = trustResponse.RequestSecurityTokenResponseCollection[0];

            // Get attached and unattached references
            GenericXmlSecurityKeyIdentifierClause internalSecurityKeyIdentifierClause = null;

            if (response.AttachedReference != null)
            {
                internalSecurityKeyIdentifierClause = GetSecurityKeyIdentifierForTokenReference(response.AttachedReference);
            }

            GenericXmlSecurityKeyIdentifierClause externalSecurityKeyIdentifierClause = null;

            if (response.UnattachedReference != null)
            {
                externalSecurityKeyIdentifierClause = GetSecurityKeyIdentifierForTokenReference(response.UnattachedReference);
            }

            // Get proof token
            IdentityModel.Tokens.SecurityToken proofToken = GetProofToken(request, response);

            // Get lifetime
            DateTime created = response.Lifetime?.Created ?? DateTime.UtcNow;
            DateTime expires = response.Lifetime?.Expires ?? created.AddDays(1);

            return(new GenericXmlSecurityToken(response.RequestedSecurityToken.TokenElement,
                                               proofToken,
                                               created,
                                               expires,
                                               internalSecurityKeyIdentifierClause,
                                               externalSecurityKeyIdentifierClause,
                                               null));
        }