public ProjectDocumentRepository(IDocumentStorer documentStorer,
     IDocumentRetriever documentRetriever,
     IDocumentDeleter documentDeleter,
     IResultCreator resultCreator,
     IMapper mapper)
 {
     _documentStorer = documentStorer;
     _documentRetriever = documentRetriever;
     _documentDeleter = documentDeleter;
     _resultCreator = resultCreator;
     _mapper = mapper;
 }
 public TestDocumentRetriever(string primaryDocument, IDocumentRetriever fallback)
 {
     _primaryDocument = primaryDocument;
     _fallback = fallback;
 }
예제 #3
0
 public PostCacheTask(IDocumentRetriever dynamoTableRetriever)
 {
     this.dynamoTableRetriever = dynamoTableRetriever;
 }
 /// <inheritdoc/>
 public Task <WsFederationConfiguration> GetConfigurationAsync(string address, IDocumentRetriever retriever, CancellationToken cancel)
 {
     return(GetAsync(address, retriever, cancel));
 }
예제 #5
0
 public TestDocumentRetriever(string primaryDocument, IDocumentRetriever fallback)
 {
     _primaryDocument = primaryDocument;
     _fallback        = fallback;
 }
예제 #6
0
        /// <summary>
        /// Retrieves a populated <see cref="OpenIdConnectConfiguration"/> given an address and an <see cref="IDocumentRetriever"/>.
        /// </summary>
        /// <param name="address">address of the jwks uri.</param>
        /// <param name="retriever">the <see cref="IDocumentRetriever"/> to use to read the jwks</param>
        /// <param name="cancel"><see cref="CancellationToken"/>.</param>
        /// <returns>A populated <see cref="OpenIdConnectConfiguration"/> instance.</returns>
        public static async Task <OpenIdConnectConfiguration> GetAsync(string address, IDocumentRetriever retriever, CancellationToken cancel)
        {
            if (string.IsNullOrWhiteSpace(address))
            {
                throw LogHelper.LogArgumentNullException(nameof(address));
            }

            if (retriever == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(retriever));
            }

            var doc = await retriever.GetDocumentAsync(address, cancel).ConfigureAwait(false);

            LogHelper.LogVerbose("IDX21811: Deserializing the string: '{0}' obtained from metadata endpoint into openIdConnectConfiguration object.", doc);
            var jwks = new JsonWebKeySet(doc);
            var openIdConnectConfiguration = new OpenIdConnectConfiguration()
            {
                JsonWebKeySet = jwks,
                JwksUri       = address,
            };

            foreach (var securityKey in jwks.GetSigningKeys())
            {
                openIdConnectConfiguration.SigningKeys.Add(securityKey);
            }

            return(openIdConnectConfiguration);
        }
        /// <summary>
        /// Retrieves a populated <see cref="WsFederationConfiguration"/> given an address and an <see cref="IDocumentRetriever"/>.
        /// </summary>
        /// <param name="address">address of the metadata document.</param>
        /// <param name="retriever">the <see cref="IDocumentRetriever"/> to use to read the metadata document</param>
        /// <param name="cancel"><see cref="CancellationToken"/>.</param>
        /// <returns>A populated <see cref="WsFederationConfiguration"/> instance.</returns>
        /// <exception cref="ArgumentNullException">if <paramref name="address"/> is null or empty.</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="retriever"/> is null.</exception>
        public static async Task <WsFederationConfiguration> GetAsync(string address, IDocumentRetriever retriever, CancellationToken cancel)
        {
            if (string.IsNullOrEmpty(address))
            {
                throw LogArgumentNullException(nameof(address));
            }

            if (retriever == null)
            {
                throw LogArgumentNullException(nameof(retriever));
            }

            string document = await retriever.GetDocumentAsync(address, cancel).ConfigureAwait(false);

            using (var metaDataReader = XmlReader.Create(new StringReader(document), SafeSettings))
            {
                return((new WsFederationMetadataSerializer()).ReadMetadata(metaDataReader));
            }
        }
예제 #8
0
 /// <summary>
 /// Initializes a new instance of <see cref="ConfigurationManagerStub" />
 /// </summary>
 /// <param name="metadataAddress">The address to obtain configuration.</param>
 /// <param name="configRetriever">The <see cref="IConfigurationRetriever{OpenIdConnectConfiguration}" /></param>
 /// <param name="docRetriever">The <see cref="IDocumentRetriever" /> that reaches out to obtain the configuration.</param>
 public ConfigurationManagerStub(
     string metadataAddress,
     IConfigurationRetriever <OpenIdConnectConfiguration> configRetriever,
     IDocumentRetriever docRetriever)
 {
 }
예제 #9
0
        private async Task <MetadataBase> GetAsync(FederationPartyConfiguration context, IDocumentRetriever retriever, CancellationToken cancel)
        {
            this._metadataSerialiser.Validator.SetFederationPartyId(context.FederationPartyId);
            if (string.IsNullOrWhiteSpace(context.MetadataAddress))
            {
                throw new ArgumentNullException("address");
            }
            if (retriever == null)
            {
                throw new ArgumentNullException("retriever");
            }
            var str = await retriever.GetDocumentAsync(context.MetadataAddress, cancel);

            var document = str;

            str = null;
            if (String.IsNullOrWhiteSpace(document))
            {
                throw new ArgumentNullException(nameof(document));
            }

            using (XmlReader reader = XmlReader.Create(new StringReader(document), this._safeSettings))
            {
                var federationConfiguration = this._metadataSerialiser.Deserialise(reader);
                if (this.MetadataReceivedCallback != null)
                {
                    this.MetadataReceivedCallback(federationConfiguration);
                }
                return(federationConfiguration);
            }
        }
예제 #10
0
 Task <TrustConfiguration> IConfigurationRetriever <TrustConfiguration> .GetConfigurationAsync(string address, IDocumentRetriever retriever, CancellationToken cancel)
 {
     return(GetAsync(address, retriever, cancel));
 }
예제 #11
0
 public Task <IDictionary <string, HashSet <string> > > GetConfigurationAsync(string address, IDocumentRetriever retriever, CancellationToken cancellationToken)
 {
     return(Task.FromResult(EndorsementTable));
 }
        public async Task <IDictionary <string, string[]> > GetConfigurationAsync(string address, IDocumentRetriever retriever, CancellationToken cancellationToken)
        {
            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }

            if (retriever == null)
            {
                throw new ArgumentNullException(nameof(retriever));
            }

            var jsonDocument = await retriever.GetDocumentAsync(address, cancellationToken);

            var configurationRoot = JObject.Parse(jsonDocument);

            var keys = configurationRoot["keys"]?.Value <JArray>();

            if (keys == null)
            {
                return(new Dictionary <string, string[]>(0));
            }

            var results = new Dictionary <string, string[]>(keys.Count);

            foreach (var key in keys)
            {
                var keyId = key[AuthenticationConstants.KeyIdHeader]?.Value <string>();

                if (keyId != null
                    &&
                    !results.ContainsKey(keyId))
                {
                    var endorsementsToken = key["endorsements"];

                    if (endorsementsToken != null)
                    {
                        results.Add(keyId, endorsementsToken.Values <string>().ToArray());
                    }
                }
            }

            return(results);
        }
        /// <summary>
        /// Retrieves a populated <see cref="WsFederationConfiguration"/> given an address and an <see cref="IDocumentRetriever"/>.
        /// </summary>
        /// <param name="address">address of the metadata document.</param>
        /// <param name="retriever">the <see cref="IDocumentRetriever"/> to use to read the metadata document</param>
        /// <param name="cancel"><see cref="CancellationToken"/>.</param>
        /// <returns>A populated <see cref="WsFederationConfiguration"/> instance.</returns>
        public static async Task <WsFederationConfiguration> GetAsync(string address, IDocumentRetriever retriever, CancellationToken cancel)
        {
            if (string.IsNullOrWhiteSpace(address))
            {
                throw new ArgumentNullException("address");
            }

            if (retriever == null)
            {
                throw new ArgumentNullException("retriever");
            }

            WsFederationConfiguration configuration = new WsFederationConfiguration();

            string document = await retriever.GetDocumentAsync(address, cancel);

            using (XmlReader metaDataReader = XmlReader.Create(new StringReader(document), SafeSettings))
            {
                var serializer = new MetadataSerializer {
                    CertificateValidationMode = X509CertificateValidationMode.None
                };

                MetadataBase metadataBase     = serializer.ReadMetadata(metaDataReader);
                var          entityDescriptor = (EntityDescriptor)metadataBase;

                if (!string.IsNullOrWhiteSpace(entityDescriptor.EntityId.Id))
                {
                    configuration.Issuer = entityDescriptor.EntityId.Id;
                }

                SecurityTokenServiceDescriptor stsd = entityDescriptor.RoleDescriptors.OfType <SecurityTokenServiceDescriptor>().First();
                if (stsd != null)
                {
                    configuration.TokenEndpoint = stsd.PassiveRequestorEndpoints.First().Uri.AbsoluteUri;
                    foreach (KeyDescriptor keyDescriptor in stsd.Keys)
                    {
                        if (keyDescriptor.KeyInfo != null && (keyDescriptor.Use == KeyType.Signing || keyDescriptor.Use == KeyType.Unspecified))
                        {
                            foreach (SecurityKeyIdentifierClause clause in keyDescriptor.KeyInfo)
                            {
                                X509RawDataKeyIdentifierClause x509Clause = clause as X509RawDataKeyIdentifierClause;
                                if (x509Clause != null)
                                {
                                    var key = new X509SecurityKey(new X509Certificate2(x509Clause.GetX509RawData()));
                                    configuration.SigningKeys.Add(key);
                                }
                            }
                        }
                    }
                }
            }

            return(configuration);
        }
            /// <summary>
            /// Retrieves the OpenID 2.0 configuration from the specified address.
            /// </summary>
            /// <param name="address">The address of the discovery document.</param>
            /// <param name="retriever">The object used to retrieve the discovery document.</param>
            /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
            /// <returns>An <see cref="OpenIdAuthenticationConfiguration"/> instance.</returns>
            public async Task <OpenIdAuthenticationConfiguration> GetConfigurationAsync(
                [NotNull] string address, [NotNull] IDocumentRetriever retriever, CancellationToken cancellationToken)
            {
                if (string.IsNullOrEmpty(address))
                {
                    throw new ArgumentException("The address cannot be null or empty.", nameof(address));
                }

                if (retriever == null)
                {
                    throw new ArgumentNullException(nameof(retriever));
                }

                using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                {
                    // If the final authentication endpoint cannot be found after 30 seconds, abort the discovery operation.
                    cancellationTokenSource.CancelAfter(HttpClient.Timeout < TimeSpan.FromSeconds(30) ?
                                                        HttpClient.Timeout : TimeSpan.FromSeconds(30));

                    do
                    {
                        // application/xrds+xml MUST be the preferred content type to avoid a second round-trip.
                        // See http://openid.net/specs/yadis-v1.0.pdf (chapter 6.2.4)
                        var request = new HttpRequestMessage(HttpMethod.Get, address);
                        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(OpenIdAuthenticationConstants.Media.Xrds));
                        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(OpenIdAuthenticationConstants.Media.Html));
                        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(OpenIdAuthenticationConstants.Media.Xhtml));

                        var response = await HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationTokenSource.Token);

                        if (!response.IsSuccessStatusCode)
                        {
                            throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture,
                                                                              "The Yadis discovery failed because an invalid response was received: the identity provider " +
                                                                              "returned returned a {0} response with the following payload: {1} {2}.",
                                                                              /* Status: */ response.StatusCode,
                                                                              /* Headers: */ response.Headers.ToString(),
                                                                              /* Body: */ await response.Content.ReadAsStringAsync()));
                        }

                        // Note: application/xrds+xml is the standard content type but text/xml is frequent.
                        // See http://openid.net/specs/yadis-v1.0.pdf (chapter 6.2.6)
                        var media = response.Content.Headers.ContentType?.MediaType;
                        if (string.Equals(media, OpenIdAuthenticationConstants.Media.Xrds, StringComparison.OrdinalIgnoreCase) ||
                            string.Equals(media, OpenIdAuthenticationConstants.Media.Xml, StringComparison.OrdinalIgnoreCase))
                        {
                            using (var stream = await response.Content.ReadAsStreamAsync())
                                using (var reader = XmlReader.Create(stream))
                                {
                                    var document = XDocument.Load(reader);

                                    var endpoint = (from service in document.Root.Element(XName.Get("XRD", "xri://$xrd*($v*2.0)"))
                                                    .Descendants(XName.Get("Service", "xri://$xrd*($v*2.0)"))
                                                    where service.Descendants(XName.Get("Type", "xri://$xrd*($v*2.0)"))
                                                    .Any(type => type.Value == "http://specs.openid.net/auth/2.0/server")
                                                    orderby service.Attribute("priority")?.Value
                                                    select service.Element(XName.Get("URI", "xri://$xrd*($v*2.0)"))?.Value).FirstOrDefault();

                                    Uri uri;
                                    if (!string.IsNullOrEmpty(endpoint) && Uri.TryCreate(endpoint, UriKind.Absolute, out uri))
                                    {
                                        return(new OpenIdAuthenticationConfiguration
                                        {
                                            AuthenticationEndpoint = uri.AbsoluteUri
                                        });
                                    }

                                    throw new InvalidOperationException(
                                              "The Yadis discovery failed because the XRDS document returned by the " +
                                              "identity provider was invalid or didn't contain the endpoint address.");
                                }
                        }

                        // Try to extract the XRDS location from the response headers before parsing the body.
                        // See http://openid.net/specs/yadis-v1.0.pdf (chapter 6.2.6)
                        var location = (from header in response.Headers
                                        where string.Equals(header.Key, OpenIdAuthenticationConstants.Headers.XrdsLocation, StringComparison.OrdinalIgnoreCase)
                                        from value in header.Value
                                        select value).FirstOrDefault();

                        if (!string.IsNullOrEmpty(location))
                        {
                            Uri uri;
                            if (!Uri.TryCreate(location, UriKind.Absolute, out uri))
                            {
                                throw new InvalidOperationException(
                                          "The Yadis discovery failed because the X-XRDS-Location " +
                                          "header returned by the identity provider was invalid.");
                            }

                            // Retry the discovery operation, but using the XRDS location extracted from the header.
                            address = uri.AbsoluteUri;

                            continue;
                        }

                        // Only text/html or application/xhtml+xml can be safely parsed.
                        // See http://openid.net/specs/yadis-v1.0.pdf
                        if (string.Equals(media, OpenIdAuthenticationConstants.Media.Html, StringComparison.OrdinalIgnoreCase) ||
                            string.Equals(media, OpenIdAuthenticationConstants.Media.Xhtml, StringComparison.OrdinalIgnoreCase))
                        {
                            IHtmlDocument document = null;

                            try
                            {
                                using (var stream = await response.Content.ReadAsStreamAsync())
                                {
                                    document = await HtmlParser.ParseAsync(stream, cancellationTokenSource.Token);
                                }
                            }

                            catch (Exception exception)
                            {
                                throw new InvalidOperationException("An exception occurred while parsing the HTML document.", exception);
                            }

                            var endpoint = (from element in document.Head.GetElementsByTagName(OpenIdAuthenticationConstants.Metadata.Meta)
                                            let attribute = element.Attributes[OpenIdAuthenticationConstants.Metadata.HttpEquiv]
                                                            where string.Equals(attribute?.Value, OpenIdAuthenticationConstants.Metadata.XrdsLocation, StringComparison.OrdinalIgnoreCase)
                                                            select element.Attributes[OpenIdAuthenticationConstants.Metadata.Content]?.Value).FirstOrDefault();

                            if (!string.IsNullOrEmpty(endpoint))
                            {
                                Uri uri;
                                if (!Uri.TryCreate(endpoint, UriKind.Absolute, out uri))
                                {
                                    throw new InvalidOperationException(
                                              "The Yadis discovery failed because the X-XRDS-Location " +
                                              "metadata returned by the identity provider was invalid.");
                                }

                                // Retry the discovery operation, but using the XRDS
                                // location extracted from the parsed HTML document.
                                address = uri.AbsoluteUri;

                                continue;
                            }
                        }

                        throw new InvalidOperationException("The Yadis discovery failed because the XRDS document location was not found.");
                    }while (!cancellationTokenSource.IsCancellationRequested);
                }

                throw new InvalidOperationException("The OpenID 2.0 configuration cannot be retrieved.");
            }
        /// <summary>
        /// Retrieves a populated <see cref="OpenIdConnectConfiguration"/> given an address and an <see cref="IDocumentRetriever"/>.
        /// </summary>
        /// <param name="address">address of the discovery document.</param>
        /// <param name="retriever">the <see cref="IDocumentRetriever"/> to use to read the discovery document</param>
        /// <param name="cancel"><see cref="CancellationToken"/>.</param>
        /// <returns>A populated <see cref="OpenIdConnectConfiguration"/> instance.</returns>
        public static async Task <OpenIdConnectConfiguration> GetAsync(string address, IDocumentRetriever retriever, CancellationToken cancel)
        {
            if (string.IsNullOrWhiteSpace(address))
            {
                throw new ArgumentNullException("address");
            }

            if (retriever == null)
            {
                throw new ArgumentNullException("retriever");
            }

            string doc = await retriever.GetDocumentAsync(address, cancel).ConfigureAwait(false);

            OpenIdConnectConfiguration openIdConnectConfiguration = new OpenIdConnectConfiguration(doc);

            if (!string.IsNullOrEmpty(openIdConnectConfiguration.JwksUri))
            {
                string keys = await retriever.GetDocumentAsync(openIdConnectConfiguration.JwksUri, cancel).ConfigureAwait(false);

                openIdConnectConfiguration.JsonWebKeySet = new JsonWebKeySet(keys);
                foreach (SecurityToken token in openIdConnectConfiguration.JsonWebKeySet.GetSigningTokens())
                {
                    openIdConnectConfiguration.SigningTokens.Add(token);
                }
            }

            return(openIdConnectConfiguration);
        }
예제 #16
0
        public async Task <IDictionary <string, string[]> > GetConfigurationAsync(string address, IDocumentRetriever retriever, CancellationToken cancel)
        {
            var res = await retriever.GetDocumentAsync(address, cancel);

            var obj = Newtonsoft.Json.JsonConvert.DeserializeObject <JObject>(res);

            if (obj != null && obj.HasValues && obj["keys"] != null)
            {
                var keys         = obj.SelectToken("keys").Value <JArray>();
                var endorsements = keys.Where(key => key["endorsements"] != null).Select(key => Tuple.Create(key.SelectToken("kid").Value <string>(), key.SelectToken("endorsements").Values <string>()));
                return(endorsements.Distinct(new EndorsementsComparer()).ToDictionary(item => item.Item1, item => item.Item2.ToArray()));
            }
            else
            {
                return(new Dictionary <string, string[]>());
            }
        }