/// <summary> /// Validates that all the required attributes are present on the assertion. /// Furthermore it validates validity of the Issuer element. /// </summary> /// <param name="assertion"></param> private void ValidateAssertionAttributes(Assertion assertion) { //There must be a Version if (!Saml20Utils.ValidateRequiredString(assertion.Version)) { throw new Saml20FormatException("Assertion element must have the Version attribute set."); } //Version must be 2.0 if (assertion.Version != Saml20Constants.Version) { throw new Saml20FormatException("Wrong value of version attribute on Assertion element"); } //Assertion must have an ID if (!Saml20Utils.ValidateRequiredString(assertion.ID)) { throw new Saml20FormatException("Assertion element must have the ID attribute set."); } // Make sure that the ID elements is at least 128 bits in length (SAML2.0 std section 1.3.4) if (!Saml20Utils.ValidateIDString(assertion.ID)) { throw new Saml20FormatException("Assertion element must have an ID attribute with at least 16 characters (the equivalent of 128 bits)"); } //IssueInstant must be set. if (!assertion.IssueInstant.HasValue) { throw new Saml20FormatException("Assertion element must have the IssueInstant attribute set."); } //There must be an Issuer if (assertion.Issuer == null) { throw new Saml20FormatException("Assertion element must have an issuer element."); } //The Issuer element must be valid NameIDValidator.ValidateNameID(assertion.Issuer); }
public void ValidateNameID(NameID nameID) { if (nameID == null) { throw new ArgumentNullException("nameID"); } if (string.IsNullOrEmpty(nameID.Format)) { return; } if (!Uri.IsWellFormedUriString(nameID.Format, UriKind.Absolute)) { throw new Saml20FormatException("NameID element has Format attribute which is not a wellformed absolute uri."); } // The processing rules from [SAML2.0std] section 8.3 are implemented here if (nameID.Format == Saml20Constants.NameIdentifierFormats.Email) { if (!Saml20Utils.ValidateRequiredString(nameID.Value)) { throw new Saml20FormatException("NameID with Email Format attribute MUST contain a Value that contains more than whitespace characters"); } try { new MailAddress(nameID.Value); } catch (FormatException fe) { throw new Saml20FormatException("Value of NameID is not a valid email address according to the IETF RFC 2822 specification", fe); } catch (IndexOutOfRangeException ie) { throw new Saml20FormatException("Value of NameID is not a valid email address according to the IETF RFC 2822 specification", ie); } } else if (nameID.Format == Saml20Constants.NameIdentifierFormats.X509SubjectName) { if (!Saml20Utils.ValidateRequiredString(nameID.Value)) { throw new Saml20FormatException("NameID with X509SubjectName Format attribute MUST contain a Value that contains more than whitespace characters"); } // TODO: Consider checking for correct encoding of the Value according to the // XML Signature Recommendation (http://www.w3.org/TR/xmldsig-core/) section 4.4.4 } else if (nameID.Format == Saml20Constants.NameIdentifierFormats.Windows) { // Required format is 'DomainName\UserName' but the domain name and the '\' are optional if (!Saml20Utils.ValidateRequiredString(nameID.Value)) { throw new Saml20FormatException("NameID with Windows Format attribute MUST contain a Value that contains more than whitespace characters"); } } else if (nameID.Format == Saml20Constants.NameIdentifierFormats.Kerberos) { // Required format is 'name[/instance]@REALM' if (!Saml20Utils.ValidateRequiredString(nameID.Value)) { throw new Saml20FormatException("NameID with Kerberos Format attribute MUST contain a Value that contains more than whitespace characters"); } if (nameID.Value.Length < 3) { throw new Saml20FormatException("NameID with Kerberos Format attribute MUST contain a Value with at least 3 characters"); } if (nameID.Value.IndexOf("@") < 0) { throw new Saml20FormatException("NameID with Kerberos Format attribute MUST contain a Value that contains a '@'"); } //TODO: Consider implementing the rules for 'name', 'instance' and 'REALM' found in IETF RFC 1510 (http://www.ietf.org/rfc/rfc1510.txt) here } else if (nameID.Format == Saml20Constants.NameIdentifierFormats.Entity) { if (!Saml20Utils.ValidateRequiredString(nameID.Value)) { throw new Saml20FormatException("NameID with Entity Format attribute MUST contain a Value that contains more than whitespace characters"); } if (nameID.Value.Length > 1024) { throw new Saml20FormatException("NameID with Entity Format attribute MUST have a Value that contains no more than 1024 characters"); } if (nameID.NameQualifier != null) { throw new Saml20FormatException("NameID with Entity Format attribute MUST NOT set the NameQualifier attribute"); } if (nameID.SPNameQualifier != null) { throw new Saml20FormatException("NameID with Entity Format attribute MUST NOT set the SPNameQualifier attribute"); } if (nameID.SPProvidedID != null) { throw new Saml20FormatException("NameID with Entity Format attribute MUST NOT set the SPProvidedID attribute"); } } else if (nameID.Format == Saml20Constants.NameIdentifierFormats.Persistent) { if (!Saml20Utils.ValidateRequiredString(nameID.Value)) { throw new Saml20FormatException("NameID with Persistent Format attribute MUST contain a Value that contains more than whitespace characters"); } if (nameID.Value.Length > 256) { throw new Saml20FormatException("NameID with Persistent Format attribute MUST have a Value that contains no more than 256 characters"); } } else if (nameID.Format == Saml20Constants.NameIdentifierFormats.Transient) { if (!Saml20Utils.ValidateRequiredString(nameID.Value)) { throw new Saml20FormatException("NameID with Transient Format attribute MUST contain a Value that contains more than whitespace characters"); } if (nameID.Value.Length > 256) { throw new Saml20FormatException("NameID with Transient Format attribute MUST have a Value that contains no more than 256 characters"); } if (!Saml20Utils.ValidateIDString(nameID.Value)) { throw new Saml20FormatException("NameID with Transient Format attribute MUST have a Value with at least 16 characters (the equivalent of 128 bits)"); } } }