/// <summary> /// [SAML2.0std] section 2.7.2.2 /// </summary> /// <param name="authnContext"></param> private void ValidateAuthnContext(AuthnContext authnContext) { if (authnContext == null) { throw new Saml2FormatException("AuthnStatement MUST have an AuthnContext element"); } // There must be at least one item if an authentication statement is present if (authnContext.Items == null || authnContext.Items.Length == 0) { throw new Saml2FormatException("AuthnContext element MUST contain at least one AuthnContextClassRef, AuthnContextDecl or AuthnContextDeclRef element"); } // Cannot happen when using .NET auto-generated serializer classes, but other implementations may fail to enforce the // correspondence on the size of the arrays involved if (authnContext.Items.Length != authnContext.ItemsElementName.Length) { throw new Saml2FormatException("AuthnContext parse error: Mismathing Items vs ItemElementNames counts"); } // Validate the anyUri xsi schema type demands on context reference types // We do not support by-value authentication types (since Geneva does not allow it) if (authnContext.Items.Length > 2) { throw new Saml2FormatException("AuthnContext MUST NOT contain more than two elements."); } bool authnContextDeclRefFound = false; for (int i = 0; i < authnContext.ItemsElementName.Length; ++i) { switch (authnContext.ItemsElementName[i]) { case ItemsChoiceType5.AuthnContextClassRef: if (i > 0) { throw new Saml2FormatException("AuthnContextClassRef must be in the first element"); } if (!Uri.IsWellFormedUriString((string)authnContext.Items[i], UriKind.Absolute)) { throw new Saml2FormatException("AuthnContextClassRef has a value which is not a wellformed absolute uri"); } break; case ItemsChoiceType5.AuthnContextDeclRef: if (authnContextDeclRefFound) { throw new Saml2FormatException("AuthnContextDeclRef MUST only be present once."); } authnContextDeclRefFound = true; if (!Uri.IsWellFormedUriString((string)authnContext.Items[i], UriKind.Absolute)) { throw new Saml2FormatException("AuthnContextDeclRef has a value which is not a wellformed absolute uri"); } break; case ItemsChoiceType5.AuthnContextDecl: throw new Saml2FormatException("AuthnContextDecl elements are not allowed in this implementation"); default: throw new Saml2FormatException(string.Format("Subelement {0} of AuthnContext is not supported", authnContext.ItemsElementName[i])); } } // No authenticating authorities? We are done if (authnContext.AuthenticatingAuthority == null || authnContext.AuthenticatingAuthority.Length == 0) { return; } // Values MUST have xsi schema type anyUri: foreach (string authnAuthority in authnContext.AuthenticatingAuthority) { if (!Uri.IsWellFormedUriString(authnAuthority, UriKind.Absolute)) { throw new Saml2FormatException("AuthenticatingAuthority array contains a value which is not a wellformed absolute uri"); } } }
/// <summary> /// Validate <c>AuthzContext</c>. /// </summary> /// <remarks> /// [SAML2.0 standard] section 2.7.2.2 /// </remarks> /// <param name="authnContext">The authentication context.</param> private void ValidateAuthnContext(AuthnContext authnContext) { if (authnContext == null) { throw new Saml20FormatException("AuthnStatement MUST have an AuthnContext element"); } // There must be at least one item if an authentication statement is present if (authnContext.Items == null || authnContext.Items.Length == 0) { throw new Saml20FormatException("AuthnContext element MUST contain at least one AuthnContextClassRef, AuthnContextDecl or AuthnContextDeclRef element"); } // Cannot happen when using .NET auto-generated serializer classes, but other implementations may fail to enforce the // correspondence on the size of the arrays involved if (authnContext.Items.Length != authnContext.ItemsElementName.Length) { throw new Saml20FormatException("AuthnContext parse error: Mismathing Items vs ItemElementNames counts"); } // Validate the anyUri xsi schema type demands on context reference types // We do not support by-value authentication types (since Geneva does not allow it) if (authnContext.Items.Length > 2) { throw new Saml20FormatException("AuthnContext MUST NOT contain more than two elements."); } var authnContextDeclRefFound = false; for (var i = 0; i < authnContext.ItemsElementName.Length; ++i) { switch (authnContext.ItemsElementName[i]) { case Schema.Core.AuthnContextType.AuthnContextClassRef: if (i > 0) { throw new Saml20FormatException("AuthnContextClassRef must be in the first element"); } if (!Uri.IsWellFormedUriString((string)authnContext.Items[i], UriKind.Absolute)) { throw new Saml20FormatException("AuthnContextClassRef has a value which is not a wellformed absolute uri"); } break; case Schema.Core.AuthnContextType.AuthnContextDeclRef: if (authnContextDeclRefFound) { throw new Saml20FormatException("AuthnContextDeclRef MUST only be present once."); } authnContextDeclRefFound = true; // There is some concern about this being a valid check. // See: https://lists.oasis-open.org/archives/security-services/200703/msg00004.html // http://saml2.codeplex.com/SourceControl/network/forks/etlerch/saml2/contribution/5740 if (!Uri.IsWellFormedUriString((string)authnContext.Items[i], UriKind.Absolute)) { throw new Saml20FormatException("AuthnContextDeclRef has a value which is not a wellformed absolute uri"); } break; case Schema.Core.AuthnContextType.AuthnContextDecl: throw new Saml20FormatException("AuthnContextDecl elements are not allowed in this implementation"); default: throw new Saml20FormatException(string.Format("Subelement {0} of AuthnContext is not supported", authnContext.ItemsElementName[i])); } } // No authenticating authorities? We are done if (authnContext.AuthenticatingAuthority == null || authnContext.AuthenticatingAuthority.Length == 0) { return; } // Values MUST have xsi schema type anyUri: foreach (var authnAuthority in authnContext.AuthenticatingAuthority) { if (!Uri.IsWellFormedUriString(authnAuthority, UriKind.Absolute)) { throw new Saml20FormatException("AuthenticatingAuthority array contains a value which is not a wellformed absolute uri"); } } }