public void _0001_NameID_Invalid_EmptyEmail() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Email; nameID.Value = " "; Saml20NameIDValidator validator = new Saml20NameIDValidator(); validator.ValidateNameID(nameID); }
public void _0001_NameID_Invalid_Email() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Email; Saml20NameIDValidator validator = new Saml20NameIDValidator(); string[] invalidEmails = new string[] { "thisisnotavalid.email@ ", "thisisnotavalidemail", "thisisnotavalidemail.com", "@thisisnotavalidemail.com", " @thisisnotavalidemail.com", "@ @thisisnotavalidemail.com", " @ @thisisnotavalidemail.com", " . @thisisnotavalidemail.com", @"\. @thisisnotavalidemail.com", @"\.\@thisisnotavalidemail.com", @"a.\@thisisnotavalidemail.com", @"*****@*****.**", @"<.>@thisisnotavalidemail.com", @"<*****@*****.**", "thisisnotavalid.email@", "thisisnotavalid.email@ @", "thisisnotavalid.email@ @ ", }; foreach (string email in invalidEmails) { nameID.Value = email; try { validator.ValidateNameID(nameID); Assert.Fail("Email address " + email + " is not supposed to be valid"); } catch (Saml20FormatException sfe) { Assert.AreEqual(sfe.Message, "Value of NameID is not a valid email address according to the IETF RFC 2822 specification"); } } }
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)"); } }
private Assertion CreateAssertion(User user, string receiver) { Assertion assertion = new Assertion(); { // Subject element assertion.Subject = new Subject(); assertion.ID = "id" + Guid.NewGuid().ToString("N"); assertion.IssueInstant = DateTime.Now.AddMinutes(10); assertion.Issuer = new NameID(); assertion.Issuer.Value = IDPConfig.ServerBaseUrl; SubjectConfirmation subjectConfirmation = new SubjectConfirmation(); subjectConfirmation.Method = SubjectConfirmation.BEARER_METHOD; subjectConfirmation.SubjectConfirmationData = new SubjectConfirmationData(); subjectConfirmation.SubjectConfirmationData.NotOnOrAfter = DateTime.Now.AddHours(1); subjectConfirmation.SubjectConfirmationData.Recipient = receiver; NameID nameId = new NameID(); nameId.Format = Saml20Constants.NameIdentifierFormats.Persistent; nameId.Value = user.ppid; assertion.Subject.Items = new object[] { nameId, subjectConfirmation }; } { // Conditions element assertion.Conditions = new Conditions(); assertion.Conditions.Items = new List<ConditionAbstract>(); assertion.Conditions.NotOnOrAfter = DateTime.Now.AddHours(1); AudienceRestriction audienceRestriction = new AudienceRestriction(); audienceRestriction.Audience = new List<string>(); audienceRestriction.Audience.Add(receiver); assertion.Conditions.Items.Add(audienceRestriction); } List<StatementAbstract> statements = new List<StatementAbstract>(2); { // AuthnStatement element AuthnStatement authnStatement = new AuthnStatement(); authnStatement.AuthnInstant = DateTime.Now; authnStatement.SessionIndex = Convert.ToString(new Random().Next()); authnStatement.AuthnContext = new AuthnContext(); authnStatement.AuthnContext.Items = new object[] {"urn:oasis:names:tc:SAML:2.0:ac:classes:X509"}; // Wow! Setting the AuthnContext is .... verbose. authnStatement.AuthnContext.ItemsElementName = new ItemsChoiceType5[] { ItemsChoiceType5.AuthnContextClassRef }; statements.Add(authnStatement); } { // Generate attribute list. AttributeStatement attributeStatement = new AttributeStatement(); List<SamlAttribute> attributes = new List<SamlAttribute>(user.Attributes.Count); foreach (KeyValuePair<string, string> att in user.Attributes) { SamlAttribute attribute = new SamlAttribute(); attribute.Name = att.Key; attribute.AttributeValue = new string[] { att.Value }; attribute.NameFormat = SamlAttribute.NAMEFORMAT_BASIC; attributes.Add(attribute); } attributeStatement.Items = attributes.ToArray(); statements.Add(attributeStatement); } assertion.Items = statements.ToArray(); return assertion; }
public void _0002_NameID_Valid_Transient() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Transient; Saml20NameIDValidator validator = new Saml20NameIDValidator(); nameID.Value = new string('f', 256); validator.ValidateNameID(nameID); nameID.Value = new string('f', 16); validator.ValidateNameID(nameID); }
public void _0002_NameID_Invalid_Persistent() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Persistent; nameID.Value = " "; Saml20NameIDValidator validator = new Saml20NameIDValidator(); validator.ValidateNameID(nameID); }
public void _0002_NameID_Invalid_Persistent_Length() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Persistent; nameID.Value = new string('f', 257); Saml20NameIDValidator validator = new Saml20NameIDValidator(); validator.ValidateNameID(nameID); }
public void _0002_NameID_Invalid_Entity_Length() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Entity; nameID.Value = new string('f', 1025); Saml20NameIDValidator validator = new Saml20NameIDValidator(); validator.ValidateNameID(nameID); }
public void _0002_NameID_Invalid_Entity_SPProvidedID() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Entity; nameID.Value = new string('f', 1024); nameID.SPProvidedID = "ksljdf"; Saml20NameIDValidator validator = new Saml20NameIDValidator(); validator.ValidateNameID(nameID); }
public void _0002_NameID_Valid_Kerberos() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Kerberos; nameID.Value = "a@b"; Saml20NameIDValidator validator = new Saml20NameIDValidator(); validator.ValidateNameID(nameID); }
public void _0002_NameID_Valid_WindowsDomainQualifiedName() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Windows; Saml20NameIDValidator validator = new Saml20NameIDValidator(); nameID.Value = "a"; validator.ValidateNameID(nameID); nameID.Value = "b\a"; validator.ValidateNameID(nameID); }
public void _0002_NameID_Invalid_X509SubjecName() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.X509SubjectName; nameID.Value = " "; Saml20NameIDValidator validator = new Saml20NameIDValidator(); validator.ValidateNameID(nameID); }
public void _0001_NameID_Valid_Email() { NameID nameID = new NameID(); nameID.Format = Saml20Constants.NameIdentifierFormats.Email; nameID.Value = "*****@*****.**"; Saml20NameIDValidator validator = new Saml20NameIDValidator(); validator.ValidateNameID(nameID); }
/// <summary> /// Performs the attribute query against the specified IdP endpoint and adds the resulting attributes to Saml20Identity.Current. /// </summary> /// <param name="context">The http context.</param> /// <param name="endPoint">The IdP to perform the query against.</param> /// <param name="nameIdFormat">The nameid format.</param> public void PerformQuery(HttpContext context, IDPEndPoint endPoint, string nameIdFormat) { Trace.TraceMethodCalled(GetType(), "PerformQuery()"); HttpSOAPBindingBuilder builder = new HttpSOAPBindingBuilder(context); NameID name = new NameID(); name.Value = Saml20Identity.Current.Name; name.Format = nameIdFormat; _attrQuery.Subject.Items = new object[] { name }; _attrQuery.SamlAttribute = _attributes.ToArray(); XmlDocument query = new XmlDocument(); query.LoadXml(Serialization.SerializeToXmlString(_attrQuery)); XmlSignatureUtils.SignDocument(query, ID); if(query.FirstChild is XmlDeclaration) query.RemoveChild(query.FirstChild); Stream s; if (Trace.ShouldTrace(TraceEventType.Information)) Trace.TraceData(TraceEventType.Information, string.Format(Tracing.SendAttrQuery, endPoint.metadata.GetAttributeQueryEndpointLocation(), query.OuterXml)); try { s = builder.GetResponse(endPoint.metadata.GetAttributeQueryEndpointLocation(), query.OuterXml, endPoint.AttributeQuery); }catch(Exception e) { Trace.TraceData(TraceEventType.Error, e.ToString()); throw; } HttpSOAPBindingParser parser = new HttpSOAPBindingParser(s); Status status = parser.GetStatus(); if (status.StatusCode.Value != Saml20Constants.StatusCodes.Success) { Trace.TraceData(TraceEventType.Error, string.Format(Tracing.AttrQueryStatusError, Serialization.SerializeToXmlString(status))); throw new Saml20Exception(status.StatusMessage); } bool isEncrypted; XmlElement xmlAssertion = Saml20SignonHandler.GetAssertion(parser.SamlMessage, out isEncrypted); if (isEncrypted) { Saml20EncryptedAssertion ass = new Saml20EncryptedAssertion( (RSA) FederationConfig.GetConfig().SigningCertificate.GetCertificate().PrivateKey); ass.LoadXml(xmlAssertion); ass.Decrypt(); xmlAssertion = ass.Assertion.DocumentElement; } Saml20Assertion assertion = new Saml20Assertion(xmlAssertion, null, AssertionProfile.Core, endPoint.QuirksMode); if(Trace.ShouldTrace(TraceEventType.Information)) { Trace.TraceData(TraceEventType.Information, string.Format(Tracing.AttrQueryAssertion, xmlAssertion == null ? string.Empty : xmlAssertion.OuterXml)); } if(!assertion.CheckSignature(Saml20SignonHandler.GetTrustedSigners(endPoint.metadata.Keys, endPoint))){ Trace.TraceData(TraceEventType.Error, Resources.SignatureInvalid); throw new Saml20Exception(Resources.SignatureInvalid); } foreach (SamlAttribute attr in assertion.Attributes) { Saml20Identity.Current.AddAttributeFromQuery(attr.Name, attr); } }