예제 #1
0
        /// <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");
                    }
                }
            }
        }