private async Task <bool> EnableOauth2IdentityProvider(
            AuthenticationProviderResponse authProvider,
            HttpContext context)
        {
            var option = ExtractOAuthOptions(authProvider, _dataProtectionProvider);

            if (option == null)
            {
                return(false);
            }

            var handler = new OAuthHandler <OAuthOptions>(new HttpClient());
            await handler.InitializeAsync(option, context, _logger, UrlEncoder.Default);

            return(await handler.HandleRequestAsync());
        }
        private async Task <bool> EnableWsFederationAuthentication(
            AuthenticationProviderResponse authProvider,
            HttpContext httpContext,
            string redirectPath)
        {
            var eidOptions = ExtractWsFederationOptions(authProvider, redirectPath);

            if (eidOptions == null)
            {
                return(false);
            }

            var handler = new WsFedAuthenticationHandler();
            await handler.InitializeAsync(eidOptions, httpContext, _logger, UrlEncoder.Default);

            return(await handler.HandleRequestAsync());
        }
        private async Task <bool> EnableOpenIdIdentityProvider(
            AuthenticationProviderResponse authProvider,
            HttpContext context)
        {
            HttpClient httpClient;
            var        option = ExtractOpenIdConfiguration(authProvider, _dataProtectionProvider, out httpClient);

            if (option == null)
            {
                return(false);
            }

            var handler = new OpenIdConnectHandler(httpClient, _htmlEncoder);
            await handler.InitializeAsync(option, context, _logger, UrlEncoder.Default);

            return(await handler.HandleRequestAsync());
        }
        /// <summary>
        /// Extract WS-Federation configuration
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        private WsFedAuthenticationOptions ExtractWsFederationOptions(
            AuthenticationProviderResponse authProvider,
            string redirectPath)
        {
            var idEndPoint = authProvider.Options.FirstOrDefault(o => o.Key == "IdPEndpoint");
            var realm      = authProvider.Options.FirstOrDefault(o => o.Key == "Realm");
            var code       = authProvider.Code;
            var nameSpace  = authProvider.Namespace;
            var className  = authProvider.ClassName;

            if (idEndPoint == null ||
                realm == null ||
                string.IsNullOrWhiteSpace(code) ||
                string.IsNullOrWhiteSpace(nameSpace) ||
                string.IsNullOrWhiteSpace(className))
            {
                return(null);
            }

            return(new WsFedAuthenticationOptions
            {
                IdPEndpoint = idEndPoint.Value,
                Realm = realm.Value,
                AuthenticationScheme = authProvider.Name,
                DisplayName = authProvider.Name,
                SignInScheme = Constants.CookieName,
                AutomaticChallenge = true,
                AutomaticAuthenticate = true,
                CallbackPath = new PathString(authProvider.CallbackPath),
                RedirectPath = new PathString(redirectPath),
                Events =
                {
                    OnClaimsReceived = xmlNode => _claimsParser.Parse(nameSpace, className, code, xmlNode)
                }
            });
        }
        /// <summary>
        /// Extract OPENID configuration
        /// </summary>
        /// <param name="options"></param>
        /// <param name="dataProtectionProvider"></param>
        /// <param name="httpClient"></param>
        /// <returns></returns>
        private OpenIdConnectOptions ExtractOpenIdConfiguration(
            AuthenticationProviderResponse authProvider,
            IDataProtectionProvider dataProtectionProvider,
            out HttpClient httpClient)
        {
            httpClient = null;
            var scopes                 = authProvider.Options.Where(o => o.Key == "Scope").ToList();
            var clientId               = authProvider.Options.FirstOrDefault(o => o.Key == "ClientId");
            var clientSecret           = authProvider.Options.FirstOrDefault(o => o.Key == "ClientSecret");
            var wellKnownConfiguration = authProvider.Options.Find(o => o.Key == "WellKnownConfigurationEndPoint");

            if (clientId == null ||
                clientSecret == null ||
                wellKnownConfiguration == null)
            {
                return(null);
            }

            httpClient = new HttpClient(new HttpClientHandler());
            httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Microsoft ASP.NET Core OpenIdConnect middleware");
            httpClient.MaxResponseContentBufferSize = 1024 * 1024 * 10;

            var dataProtector = dataProtectionProvider.CreateProtector(
                typeof(AuthenticationManager).FullName, Constants.IdentityProviderNames.Microsoft, "v1");

            var openIdOptions = new OpenIdConnectOptions
            {
                AuthenticationScheme      = Constants.IdentityProviderNames.Microsoft,
                SignInScheme              = Constants.CookieName,
                DisplayName               = Constants.IdentityProviderNames.Microsoft,
                ClientId                  = clientId.Value,
                ClientSecret              = clientSecret.Value,
                CallbackPath              = new PathString(authProvider.CallbackPath),
                StateDataFormat           = new PropertiesDataFormat(dataProtector),
                StringDataFormat          = new SecureDataFormat <string>(new StringSerializer(), dataProtector),
                MetadataAddress           = wellKnownConfiguration.Value,
                TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer   = false,
                    ValidateAudience = true,
                    ValidAudience    = clientId.Value
                },
                ConfigurationManager = new ConfigurationManager <OpenIdConnectConfiguration>(wellKnownConfiguration.Value,
                                                                                             new OpenIdConnectConfigurationRetriever(),
                                                                                             new HttpDocumentRetriever(httpClient)
                {
                    RequireHttps = true
                })
            };

            openIdOptions.Scope.Clear();
            if (scopes != null)
            {
                foreach (var scope in scopes.Select(s => s.Value))
                {
                    openIdOptions.Scope.Add(scope);
                }
            }

            return(openIdOptions);
        }
        /// <summary>
        /// Extract OAUTH Options
        /// </summary>
        /// <param name="authProvider"></param>
        /// <param name="dataProtectionProvider"></param>
        /// <returns></returns>
        private OAuthOptions ExtractOAuthOptions(
            AuthenticationProviderResponse authProvider,
            IDataProtectionProvider dataProtectionProvider)
        {
            var clientId                = authProvider.Options.FirstOrDefault(o => o.Key == "ClientId");
            var clientSecret            = authProvider.Options.FirstOrDefault(o => o.Key == "ClientSecret");
            var authorizationEndPoint   = authProvider.Options.FirstOrDefault(o => o.Key == "AuthorizationEndpoint");
            var tokenEndpoint           = authProvider.Options.FirstOrDefault(o => o.Key == "TokenEndpoint");
            var userInformationEndpoint = authProvider.Options.FirstOrDefault(o => o.Key == "UserInformationEndpoint");
            var code      = authProvider.Code;
            var nameSpace = authProvider.Namespace;
            var className = authProvider.ClassName;

            var scopes = authProvider.Options.Where(o => o.Key == "Scope").ToList();

            if (clientId == null ||
                clientSecret == null ||
                string.IsNullOrWhiteSpace(code) ||
                string.IsNullOrWhiteSpace(nameSpace) ||
                string.IsNullOrWhiteSpace(className))
            {
                return(null);
            }

            var dataProtector = dataProtectionProvider.CreateProtector(
                typeof(AuthenticationManager).FullName, Constants.IdentityProviderNames.Microsoft, "v1");

            var result = new OAuthOptions
            {
                ClientId                = clientId.Value,
                ClientSecret            = clientSecret.Value,
                AuthenticationScheme    = authProvider.Name,
                DisplayName             = authProvider.Name,
                ClaimsIssuer            = authProvider.Name,
                SignInScheme            = Constants.CookieName,
                CallbackPath            = new PathString(authProvider.CallbackPath),
                AuthorizationEndpoint   = authorizationEndPoint.Value,
                TokenEndpoint           = tokenEndpoint.Value,
                UserInformationEndpoint = userInformationEndpoint.Value,
                StateDataFormat         = new PropertiesDataFormat(dataProtector),
                Events = new OAuthEvents
                {
                    OnCreatingTicket = async context =>
                    {
                        var endpoint = QueryHelpers.AddQueryString(context.Options.UserInformationEndpoint, "access_token", context.AccessToken);
                        var request  = new HttpRequestMessage(HttpMethod.Get, endpoint);
                        request.Headers.Add("User-Agent", "SimpleIdentityServer");
                        request.Headers.Add("Authorization", "Bearer " + context.AccessToken);
                        var response = await context.Backchannel.SendAsync(request, context.HttpContext.RequestAborted);

                        response.EnsureSuccessStatusCode();
                        var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
                        var claims  = _claimsParser.Parse(nameSpace, className, code, payload);
                        foreach (var claim in claims)
                        {
                            context.Identity.AddClaim(claim);
                        }
                    }
                }
            };

            result.Scope.Clear();
            if (scopes != null)
            {
                foreach (var scope in scopes.Select(s => s.Value))
                {
                    result.Scope.Add(scope);
                }
            }

            return(result);
        }