private IEnumerable <ClaimsIdentity> CreateClaims(SAML2AuthenticationOptions options) { Validate(options); if (status != Saml2StatusCode.Success) { throw new InvalidOperationException(string.Format("The Saml2Response must have status success to extract claims. Status: {0}.{1}" , status.ToString(), statusMessage != null ? " Message: " + statusMessage + "." : string.Empty)); } foreach (XmlElement assertionNode in AllAssertionElementNodes) { using (var reader = new FilteringXmlNodeReader(SignedXml.XmlDsigNamespaceUrl, "Signature", assertionNode)) { var handler = options.Saml2PSecurityTokenHandler; var token = (Saml2SecurityToken)handler.ReadToken(reader); handler.DetectReplayedToken(token); var validateAudience = token.Assertion.Conditions.AudienceRestrictions.Count > 0; handler.ValidateConditions(token.Assertion.Conditions, validateAudience); yield return(handler.CreateClaims(token)); } } }
private void ValidateInResponseTo(SAML2AuthenticationOptions options) { if (InResponseTo == null) { if (options.AllowUnsolicitedAuthnResponse) { return; } string msg = string.Format(CultureInfo.InvariantCulture, "Unsolicited responses are not allowed for idp \"{0}\".", Issuer.Id); throw new Saml2ResponseFailedValidationException(msg); } else { StoredRequestState storedRequestState; bool knownInResponseToId = PendingAuthnRequests.TryRemove(InResponseTo, out storedRequestState); if (!knownInResponseToId) { string msg = string.Format(CultureInfo.InvariantCulture, "Replayed or unknown InResponseTo \"{0}\".", InResponseTo); throw new Saml2ResponseFailedValidationException(msg); } requestState = storedRequestState; if (requestState.Idp.Id != Issuer.Id) { var msg = string.Format(CultureInfo.InvariantCulture, "Expected response from idp \"{0}\" but received response from idp \"{1}\".", requestState.Idp.Id, issuer.Id); throw new Saml2ResponseFailedValidationException(msg); } } }
private void Validate(SAML2AuthenticationOptions options) { if (!validated) { serviceCertificate = options.SPServiceCertificate; try { ValidateInResponseTo(options); ValidateSignature(options); } catch (Saml2ResponseFailedValidationException ex) { validationException = ex; throw; } finally { validated = true; } } else { if (validationException != null) { throw validationException; } } }
public Saml2PSecurityTokenHandler(SAML2AuthenticationOptions spOptions) { if (spOptions == null) { throw new ArgumentNullException(spOptions.GetType().Name); } var audienceRestriction = new AudienceRestriction(AudienceUriMode.Always); audienceRestriction.AllowedAudienceUris.Add( new Uri(spOptions.EntityId.Id, UriKind.RelativeOrAbsolute)); Configuration = new SecurityTokenHandlerConfiguration { IssuerNameRegistry = new ReturnRequestedIssuerNameRegistry(), AudienceRestriction = audienceRestriction, // SaveBootstrapContext = spOptions.SystemIdentityModelIdentityConfiguration.SaveBootstrapContext }; }
private void ValidateSignature(SAML2AuthenticationOptions options) { var idpKeys = options.SigningKeys; // If the response message is signed, we check just this signature because the whole content has to be correct then var responseSignature = xmlDocument.DocumentElement["Signature", SignedXml.XmlDsigNamespaceUrl]; if (responseSignature != null) { CheckSignature(XmlDocument.DocumentElement, idpKeys); } else { // If the response message is not signed, all assersions have to be signed correctly foreach (var assertionNode in AllAssertionElementNodes) { CheckSignature(assertionNode, idpKeys); } } }
public IEnumerable <ClaimsIdentity> GetClaims(SAML2AuthenticationOptions options) { if (createClaimsException != null) { throw createClaimsException; } if (claimsIdentities == null) { try { claimsIdentities = CreateClaims(options).ToList(); } catch (Exception ex) { createClaimsException = ex; throw; } } return(claimsIdentities); }
/// <summary> /// State stored by a corresponding request /// </summary> public StoredRequestState GetRequestState(SAML2AuthenticationOptions options) { Validate(options); return(requestState); }