/// <summary> /// Validates the Assertion's conditions /// Audience restrictions processing rules are: /// - Within a single audience restriction condition in the assertion, the service must be configured /// with an audience-list that contains at least one of the restrictions in the assertion ("OR" filter) /// - When multiple audience restrictions are present within the same assertion, all individual audience /// restriction conditions must be met ("AND" filter) /// </summary> private void ValidateConditions(Assertion assertion) { // Conditions are not required if (assertion.Conditions == null) { return; } bool oneTimeUseSeen = false; bool proxyRestrictionsSeen = false; ValidateConditionsInterval(assertion.Conditions); foreach (ConditionAbstract cat in assertion.Conditions.Items) { if (cat is OneTimeUse) { if (oneTimeUseSeen) { throw new Saml20FormatException("Assertion contained more than one condition of type OneTimeUse"); } oneTimeUseSeen = true; continue; } if (cat is ProxyRestriction) { if (proxyRestrictionsSeen) { throw new Saml20FormatException("Assertion contained more than one condition of type ProxyRestriction"); } proxyRestrictionsSeen = true; ProxyRestriction proxyRestriction = (ProxyRestriction)cat; if (!String.IsNullOrEmpty(proxyRestriction.Count)) { uint res; if (!UInt32.TryParse(proxyRestriction.Count, out res)) { throw new Saml20FormatException("Count attribute of ProxyRestriction MUST BE a non-negative integer"); } } if (proxyRestriction.Audience != null) { foreach (string audience in proxyRestriction.Audience) { if (!Uri.IsWellFormedUriString(audience, UriKind.Absolute)) { throw new Saml20FormatException("ProxyRestriction Audience MUST BE a wellformed uri"); } } } } // AudienceRestriction processing goes here (section 2.5.1.4 of [SAML2.0std]) if (cat is AudienceRestriction) { // No audience restrictions? No problems... AudienceRestriction audienceRestriction = (AudienceRestriction)cat; if (audienceRestriction.Audience == null || audienceRestriction.Audience.Count == 0) { continue; } // If there are no allowed audience uris configured for the service, the assertion is not // valid for this service if (_allowedAudienceUris == null || _allowedAudienceUris.Count < 1) { throw new Saml20FormatException("The service is not configured to meet any audience restrictions"); } string match = null; foreach (string audience in audienceRestriction.Audience) { //In QuirksMode this validation is omitted if (!_quirksMode) { // The given audience value MUST BE a valid URI if (!Uri.IsWellFormedUriString(audience, UriKind.Absolute)) { throw new Saml20FormatException("Audience element has value which is not a wellformed absolute uri"); } } match = _allowedAudienceUris.Find( delegate(string allowedUri) { return(allowedUri.Equals(audience)); }); if (match != null) { break; } } if (Trace.ShouldTrace(TraceEventType.Verbose)) { string intended = "Intended uris: " + Environment.NewLine + String.Join(Environment.NewLine, audienceRestriction.Audience.ToArray()); string allowed = "Allowed uris: " + Environment.NewLine + String.Join(Environment.NewLine, _allowedAudienceUris.ToArray()); Trace.TraceData(TraceEventType.Verbose, Trace.CreateTraceString(GetType(), "ValidateConditions"), intended, allowed); } if (match == null) { throw new Saml20FormatException("The service is not configured to meet the given audience restrictions"); } } } }