/// <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; }
/// <summary> /// Creates a SamlAuthenticationStatement for each AuthenticationInformation found in AuthenticationInformation. /// Override this method to provide a custom implementation. /// </summary> /// <param name="samlSubject">The SamlSubject of the Statement.</param> /// <param name="authInfo">AuthenticationInformation from which to generate the SAML Authentication statement.</param> /// <param name="tokenDescriptor">Contains all the other information that is used in token issuance.</param> /// <returns>SamlAuthenticationStatement</returns> /// <exception cref="ArgumentNullException">Thrown when 'samlSubject' or 'authInfo' is null.</exception> protected virtual SamlAuthenticationStatement CreateAuthenticationStatement( SamlSubject samlSubject, AuthenticationInformation authInfo, SecurityTokenDescriptor tokenDescriptor) { if (samlSubject == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("samlSubject"); } 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", "SAML11")); } else if (authenticationInstant == null) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4270, "AuthenticationInstant", "SAML11")); } DateTime authInstantTime = DateTime.ParseExact(authenticationInstant, DateTimeFormats.Accepted, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None).ToUniversalTime(); if (authInfo == null) { return new SamlAuthenticationStatement(samlSubject, DenormalizeAuthenticationType(authenticationMethod), authInstantTime, null, null, null); } else { return new SamlAuthenticationStatement(samlSubject, DenormalizeAuthenticationType(authenticationMethod), authInstantTime, authInfo.DnsName, authInfo.Address, null); } }