private static XElement ToXElement(Saml2AuthenticationStatement authnStatement)
        {
            var result = new XElement(Saml2Namespaces.Saml2 + "AuthnStatement",
                new XAttribute("AuthnInstant", authnStatement.AuthenticationInstant.ToSaml2DateTimeString()),
                new XElement(Saml2Namespaces.Saml2 + "AuthnContext",
                    new XElement(Saml2Namespaces.Saml2 + "AuthnContextClassRef",
                        authnStatement.AuthenticationContext.ClassReference.OriginalString)));

            if(authnStatement.SessionIndex != null)
            {
                result.Add(new XAttribute("SessionIndex", authnStatement.SessionIndex));
            }

            return result;
        }
        /// <summary>
        /// Writes the &lt;saml:AuthnStatement> element.
        /// </summary>
        /// <param name="writer">A <see cref="XmlWriter"/> to serialize the <see cref="Saml2AuthenticationStatement"/>.</param>
        /// <param name="data">The <see cref="Saml2AuthenticationStatement"/> to serialize.</param>
        protected virtual void WriteAuthenticationStatement(XmlWriter writer, Saml2AuthenticationStatement data)
        {
            if (null == writer)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

            if (null == data)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("data");
            }

            // <AuthnStatement>
            writer.WriteStartElement(Saml2Constants.Elements.AuthnStatement, Saml2Constants.Namespace);

            // @AuthnInstant - required
            writer.WriteAttributeString(Saml2Constants.Attributes.AuthnInstant, XmlConvert.ToString(data.AuthenticationInstant.ToUniversalTime(), DateTimeFormats.Generated));

            // @SessionIndex - optional
            if (null != data.SessionIndex)
            {
                writer.WriteAttributeString(Saml2Constants.Attributes.SessionIndex, data.SessionIndex);
            }

            // @SessionNotOnOrAfter - optional
            if (null != data.SessionNotOnOrAfter)
            {
                writer.WriteAttributeString(Saml2Constants.Attributes.SessionNotOnOrAfter, XmlConvert.ToString(data.SessionNotOnOrAfter.Value.ToUniversalTime(), DateTimeFormats.Generated));
            }

            // <SubjectLocality> 0-1
            if (null != data.SubjectLocality)
            {
                this.WriteSubjectLocality(writer, data.SubjectLocality);
            }

            // <AuthnContext> 1
            this.WriteAuthenticationContext(writer, data.AuthenticationContext);

            // </AuthnStatement>
            writer.WriteEndElement();
        }
        /// <summary>
        /// Reads the &lt;saml:AuthnStatement> element or a &lt;saml:Statement>
        /// element that specifies an xsi:type of saml:AuthnStatementType.
        /// </summary>
        /// <param name="reader">A <see cref="XmlReader"/> positioned at a <see cref="Saml2AuthenticationStatement"/> element.</param>
        /// <returns>A <see cref="Saml2AuthenticationStatement"/> instance.</returns>
        protected virtual Saml2AuthenticationStatement ReadAuthenticationStatement(XmlReader reader)
        {
            if (null == reader)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
            }

            // throw if wrong element
            bool isStatementElement = false;
            if (reader.IsStartElement(Saml2Constants.Elements.Statement, Saml2Constants.Namespace))
            {
                isStatementElement = true;
            }
            else if (!reader.IsStartElement(Saml2Constants.Elements.AuthnStatement, Saml2Constants.Namespace))
            {
                reader.ReadStartElement(Saml2Constants.Elements.AuthnStatement, Saml2Constants.Namespace);
            }

            try
            {
                // Must cache the individual data since the required 
                // AuthnContext comes last
                DateTime authnInstant;
                Saml2AuthenticationContext authnContext;
                string sessionIndex;
                DateTime? sessionNotOnOrAfter = null;
                Saml2SubjectLocality subjectLocality = null;

                // defer disallowing empty until after xsi:type
                bool isEmpty = reader.IsEmptyElement;

                // @attributes
                string value;

                // @xsi:type -- if we're a <Statement> element, this declaration must be present
                XmlUtil.ValidateXsiType(reader, Saml2Constants.Types.AuthnStatementType, Saml2Constants.Namespace, isStatementElement);

                // disallow empty, since xsi:type is ok
                if (isEmpty)
                {
                    throw DiagnosticUtility.ThrowHelperXml(reader, SR.GetString(SR.ID3061, Saml2Constants.Elements.AuthnStatement, Saml2Constants.Namespace));
                }

                // @AuthnInstant - required
                value = reader.GetAttribute(Saml2Constants.Attributes.AuthnInstant);
                if (string.IsNullOrEmpty(value))
                {
                    throw DiagnosticUtility.ThrowHelperXml(reader, SR.GetString(SR.ID0001, Saml2Constants.Attributes.AuthnInstant, Saml2Constants.Elements.AuthnStatement));
                }

                authnInstant = XmlConvert.ToDateTime(value, DateTimeFormats.Accepted);

                // @SessionIndex - optional
                sessionIndex = reader.GetAttribute(Saml2Constants.Attributes.SessionIndex);

                // @SessionNotOnOrAfter - optional
                value = reader.GetAttribute(Saml2Constants.Attributes.SessionNotOnOrAfter);
                if (!string.IsNullOrEmpty(value))
                {
                    sessionNotOnOrAfter = XmlConvert.ToDateTime(value, DateTimeFormats.Accepted);
                }

                // Content
                reader.Read();

                // <SubjectLocality> 0-1
                if (reader.IsStartElement(Saml2Constants.Elements.SubjectLocality, Saml2Constants.Namespace))
                {
                    subjectLocality = this.ReadSubjectLocality(reader);
                }

                // <AuthnContext> 1
                authnContext = this.ReadAuthenticationContext(reader);

                reader.ReadEndElement();

                // Construct the actual object
                Saml2AuthenticationStatement authnStatement = new Saml2AuthenticationStatement(authnContext, authnInstant);
                authnStatement.SessionIndex = sessionIndex;
                authnStatement.SessionNotOnOrAfter = sessionNotOnOrAfter;
                authnStatement.SubjectLocality = subjectLocality;

                return authnStatement;
            }
            catch (Exception e)
            {
                if (System.Runtime.Fx.IsFatal(e))
                    throw;
                
                Exception wrapped = TryWrapReadException(reader, e);
                if (null == wrapped)
                {
                    throw;
                }
                else
                {
                    throw wrapped;
                }
            }
        }
        /// <summary>
        /// Creates claims from a Saml2AuthenticationStatement.
        /// </summary>
        /// <param name="statement">The Saml2AuthenticationStatement.</param>
        /// <param name="subject">The subject.</param>
        /// <param name="issuer">The issuer.</param>
        protected virtual void ProcessAuthenticationStatement(Saml2AuthenticationStatement statement, ClaimsIdentity subject, string issuer)
        {
            if (subject == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("subject");
            }

            if (statement.AuthenticationContext.DeclarationReference != null)
            {
                throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4180));
            }

            if (statement.AuthenticationContext.ClassReference != null)
            {
                subject.AddClaim(
                        new Claim(
                            ClaimTypes.AuthenticationMethod,
                            this.NormalizeAuthenticationContextClassReference(statement.AuthenticationContext.ClassReference.AbsoluteUri),
                            ClaimValueTypes.String,
                            issuer));
            }

            subject.AddClaim(new Claim(ClaimTypes.AuthenticationInstant, XmlConvert.ToString(statement.AuthenticationInstant.ToUniversalTime(), DateTimeFormats.Generated), ClaimValueTypes.DateTime, issuer));
        }
        /// <summary>
        /// Given an AuthenticationInformation object, this routine creates a Saml2AuthenticationStatement
        /// to be added to the Saml2Assertion that is produced by the factory.
        /// </summary>
        /// <param name="authInfo">
        /// An AuthenticationInformation object containing the state to be wrapped as a Saml2AuthenticationStatement
        /// object.
        /// </param>
        /// <param name="tokenDescriptor">The token descriptor.</param>
        /// <returns>
        /// The Saml2AuthenticationStatement to add to the assertion being created or null to ignore the AuthenticationInformation
        /// being wrapped as a statement.
        /// </returns>
        protected virtual Saml2AuthenticationStatement CreateAuthenticationStatement(AuthenticationInformation authInfo, SecurityTokenDescriptor tokenDescriptor)
        {
            if (tokenDescriptor == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenDescriptor");
            }

            if (tokenDescriptor.Subject == null)
            {
                return null;
            }

            string authenticationMethod = null;
            string authenticationInstant = null;

            // Search for an Authentication Claim.
            IEnumerable<Claim> claimCollection = from c in tokenDescriptor.Subject.Claims where c.Type == ClaimTypes.AuthenticationMethod select c;
            if (claimCollection.Count<Claim>() > 0)
            {
                // We support only one authentication statement and hence we just pick the first authentication type
                // claim found in the claim collection. Since the spec allows multiple Auth Statements, 
                // we do not throw an error.
                authenticationMethod = claimCollection.First<Claim>().Value;
            }

            claimCollection = from c in tokenDescriptor.Subject.Claims where c.Type == ClaimTypes.AuthenticationInstant select c;

            if (claimCollection.Count<Claim>() > 0)
            {
                authenticationInstant = claimCollection.First<Claim>().Value;
            }

            if (authenticationMethod == null && authenticationInstant == null)
            {
                return null;
            }
            else if (authenticationMethod == null)
            {
                throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4270, "AuthenticationMethod", "SAML2"));
            }
            else if (authenticationInstant == null)
            {
                throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4270, "AuthenticationInstant", "SAML2"));
            }

            Uri saml2AuthenticationClass;
            if (!UriUtil.TryCreateValidUri(this.DenormalizeAuthenticationType(authenticationMethod), UriKind.Absolute, out saml2AuthenticationClass))
            {
                throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4185, authenticationMethod));
            }

            Saml2AuthenticationContext authCtx = new Saml2AuthenticationContext(saml2AuthenticationClass);
            DateTime authInstantTime = DateTime.ParseExact(authenticationInstant, DateTimeFormats.Accepted, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None).ToUniversalTime();
            Saml2AuthenticationStatement authnStatement = new Saml2AuthenticationStatement(authCtx, authInstantTime);

            if (authInfo != null)
            {
                if (!string.IsNullOrEmpty(authInfo.DnsName)
                    || !string.IsNullOrEmpty(authInfo.Address))
                {
                    authnStatement.SubjectLocality
                        = new Saml2SubjectLocality(authInfo.Address, authInfo.DnsName);
                }

                if (!string.IsNullOrEmpty(authInfo.Session))
                {
                    authnStatement.SessionIndex = authInfo.Session;
                }

                authnStatement.SessionNotOnOrAfter = authInfo.NotOnOrAfter;
            }

            return authnStatement;
        }
 protected override void ProcessAuthenticationStatement(Saml2AuthenticationStatement statement, ClaimsIdentity subject, string issuer)
 {
     if (statement.AuthenticationContext != null)
     {
         statement.AuthenticationContext.DeclarationReference = null;
     }
     base.ProcessAuthenticationStatement(statement, subject, issuer);
 }
        protected override void ProcessAuthenticationStatement(Saml2AuthenticationStatement statement, ClaimsIdentity subject, string issuer)
        {
            if (statement.AuthenticationContext != null)
            {
                statement.AuthenticationContext.DeclarationReference = null;
            }
            base.ProcessAuthenticationStatement(statement, subject, issuer);

            if(statement.SessionIndex != null)
            {
                var nameIdClaim = subject.FindFirst(ClaimTypes.NameIdentifier);

                subject.AddClaim(
                    new Claim(
                        AuthServicesClaimTypes.LogoutNameIdentifier,
                        DelimitedString.Join(
                            nameIdClaim.Properties.GetValueOrEmpty(ClaimProperties.SamlNameIdentifierNameQualifier),
                            nameIdClaim.Properties.GetValueOrEmpty(ClaimProperties.SamlNameIdentifierSPNameQualifier),
                            nameIdClaim.Properties.GetValueOrEmpty(ClaimProperties.SamlNameIdentifierFormat),
                            nameIdClaim.Properties.GetValueOrEmpty(ClaimProperties.SamlNameIdentifierSPProvidedId),
                            nameIdClaim.Value),
                        null,
                        issuer));

                subject.AddClaim(
                    new Claim(AuthServicesClaimTypes.SessionIndex, statement.SessionIndex, null, issuer));
            }
        }
        protected override void ProcessAuthenticationStatement(Saml2AuthenticationStatement statement, ClaimsIdentity subject, string issuer)
        {
            if (statement.AuthenticationContext != null)
            {
                statement.AuthenticationContext.DeclarationReference = null;
            }
            base.ProcessAuthenticationStatement(statement, subject, issuer);

            if(statement.SessionIndex != null)
            {
                subject.AddClaim(
                    new Claim(AuthServicesClaimTypes.SessionIndex, statement.SessionIndex, null, issuer));
            }
        }
 private void AddAuthenticationStatement()
 {
     var authenticationStatement = new Saml2AuthenticationStatement(new Saml2AuthenticationContext(AuthnContextClassTypes.UserNameAndPassword));
     Saml2SecurityToken.Assertion.Statements.Add(authenticationStatement);
 }