private static void AddProxyOAuthSecurityService(ListedCapabilityStatement statement, IUrlResolver urlResolver, string authorizeRouteName, string tokenRouteName)
        {
            EnsureArg.IsNotNull(statement, nameof(statement));
            EnsureArg.IsNotNull(urlResolver, nameof(urlResolver));
            EnsureArg.IsNotNullOrWhiteSpace(authorizeRouteName, nameof(authorizeRouteName));
            EnsureArg.IsNotNullOrWhiteSpace(tokenRouteName, nameof(tokenRouteName));

            ListedRestComponent restComponent = statement.Rest.Server();
            SecurityComponent   security      = restComponent.Security ?? new SecurityComponent();

            var codableConceptInfo = new Core.Models.CodableConceptInfo();

            security.Service.Add(codableConceptInfo);
            codableConceptInfo.Coding.Add(Constants.RestfulSecurityServiceOAuth.ToCoding());

            Uri tokenEndpoint         = urlResolver.ResolveRouteNameUrl(tokenRouteName, null);
            Uri authorizationEndpoint = urlResolver.ResolveRouteNameUrl(authorizeRouteName, null);

            var smartExtension = new
            {
                url       = Constants.SmartOAuthUriExtension,
                extension = new[]
                {
                    new
                    {
                        url      = Constants.SmartOAuthUriExtensionToken,
                        valueUri = tokenEndpoint,
                    },
                    new
                    {
                        url      = Constants.SmartOAuthUriExtensionAuthorize,
                        valueUri = authorizationEndpoint,
                    },
                },
            };

            security.Extension.Add(JObject.FromObject(smartExtension));
            restComponent.Security = security;
        }
        private static void AddOAuthSecurityService(ListedCapabilityStatement statement, string authority, IHttpClientFactory httpClientFactory, ILogger logger)
        {
            EnsureArg.IsNotNull(statement, nameof(statement));
            EnsureArg.IsNotNull(authority, nameof(authority));
            EnsureArg.IsNotNull(httpClientFactory, nameof(httpClientFactory));

            ListedRestComponent restComponent = statement.Rest.Server();
            SecurityComponent   security      = restComponent.Security ?? new SecurityComponent();

            var codableConceptInfo = new Core.Models.CodableConceptInfo();

            security.Service.Add(codableConceptInfo);
            codableConceptInfo.Coding.Add(Constants.RestfulSecurityServiceOAuth.ToCoding());

            var openIdConfigurationUrl = $"{authority}/.well-known/openid-configuration";

            HttpResponseMessage openIdConfigurationResponse;

            using (HttpClient httpClient = httpClientFactory.CreateClient())
            {
                try
                {
                    openIdConfigurationResponse = httpClient.GetAsync(new Uri(openIdConfigurationUrl)).GetAwaiter().GetResult();
                }
                catch (Exception ex)
                {
                    logger.LogWarning(ex, $"There was an exception while attempting to read the OpenId Configuration from \"{openIdConfigurationUrl}\".");
                    throw new OpenIdConfigurationException();
                }
            }

            if (openIdConfigurationResponse.IsSuccessStatusCode)
            {
                JObject openIdConfiguration = JObject.Parse(openIdConfigurationResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult());

                string tokenEndpoint, authorizationEndpoint;

                try
                {
                    tokenEndpoint         = openIdConfiguration["token_endpoint"].Value <string>();
                    authorizationEndpoint = openIdConfiguration["authorization_endpoint"].Value <string>();
                }
                catch (Exception ex)
                {
                    logger.LogWarning(ex, $"There was an exception while attempting to read the endpoints from \"{openIdConfigurationUrl}\".");
                    throw new OpenIdConfigurationException();
                }

                var smartExtension = new
                {
                    url       = Constants.SmartOAuthUriExtension,
                    extension = new[]
                    {
                        new
                        {
                            url      = Constants.SmartOAuthUriExtensionToken,
                            valueUri = tokenEndpoint,
                        },
                        new
                        {
                            url      = Constants.SmartOAuthUriExtensionAuthorize,
                            valueUri = authorizationEndpoint,
                        },
                    },
                };

                security.Extension.Add(JObject.FromObject(smartExtension));
            }
            else
            {
                logger.LogWarning($"The OpenId Configuration request from \"{openIdConfigurationUrl}\" returned an {openIdConfigurationResponse.StatusCode} status code.");
                throw new OpenIdConfigurationException();
            }

            restComponent.Security = security;
        }