private async Task <IEndpointResult> ExecuteDiscoDocAsync(HttpContext context) { _logger.LogDebug("Start discovery request"); if (!_options.Endpoints.EnableDiscoveryEndpoint) { _logger.LogInformation("Discovery endpoint disabled. 404."); return(new StatusCodeResult(404)); } var baseUrl = context.GetIdentityServerBaseUrl().EnsureTrailingSlash(); var allScopes = await _scopes.GetEnabledScopesAsync(publicOnly : true); var showScopes = new List <Scope>(); var document = new DiscoveryDocument { issuer = context.GetIssuerUri(), subject_types_supported = new[] { "public" }, id_token_signing_alg_values_supported = new[] { Constants.SigningAlgorithms.RSA_SHA_256 }, code_challenge_methods_supported = new[] { OidcConstants.CodeChallengeMethods.Plain, OidcConstants.CodeChallengeMethods.Sha256 } }; // scopes var theScopes = allScopes as Scope[] ?? allScopes.ToArray(); if (_options.DiscoveryOptions.ShowIdentityScopes) { showScopes.AddRange(theScopes.Where(s => s.Type == ScopeType.Identity)); } if (_options.DiscoveryOptions.ShowResourceScopes) { showScopes.AddRange(theScopes.Where(s => s.Type == ScopeType.Resource)); } if (showScopes.Any()) { document.scopes_supported = showScopes.Where(s => s.ShowInDiscoveryDocument).Select(s => s.Name).ToArray(); } // claims if (_options.DiscoveryOptions.ShowClaims) { var claims = new List <string>(); foreach (var s in theScopes) { claims.AddRange(from c in s.Claims where s.Type == ScopeType.Identity select c.Name); } document.claims_supported = claims.Distinct().ToArray(); } // grant types if (_options.DiscoveryOptions.ShowGrantTypes) { var standardGrantTypes = new List <string> { OidcConstants.GrantTypes.AuthorizationCode, OidcConstants.GrantTypes.ClientCredentials, OidcConstants.GrantTypes.RefreshToken, OidcConstants.GrantTypes.Implicit }; if (!(_resourceOwnerValidator is NotSupportedResouceOwnerPasswordValidator)) { standardGrantTypes.Add(OidcConstants.GrantTypes.Password); } var showGrantTypes = new List <string>(standardGrantTypes); if (_options.DiscoveryOptions.ShowExtensionGrantTypes) { showGrantTypes.AddRange(_extensionGrants.GetAvailableGrantTypes()); } document.grant_types_supported = showGrantTypes.ToArray(); } // response types if (_options.DiscoveryOptions.ShowResponseTypes) { document.response_types_supported = Constants.SupportedResponseTypes.ToArray(); } // response modes if (_options.DiscoveryOptions.ShowResponseModes) { document.response_modes_supported = Constants.SupportedResponseModes.ToArray(); } // token endpoint authentication methods if (_options.DiscoveryOptions.ShowTokenEndpointAuthenticationMethods) { document.token_endpoint_auth_methods_supported = _parsers.GetAvailableAuthenticationMethods().ToArray(); } // endpoints if (_options.DiscoveryOptions.ShowEndpoints) { if (_options.Endpoints.EnableAuthorizeEndpoint) { document.authorization_endpoint = baseUrl + Constants.ProtocolRoutePaths.Authorize; } if (_options.Endpoints.EnableTokenEndpoint) { document.token_endpoint = baseUrl + Constants.ProtocolRoutePaths.Token; } if (_options.Endpoints.EnableUserInfoEndpoint) { document.userinfo_endpoint = baseUrl + Constants.ProtocolRoutePaths.UserInfo; } if (_options.Endpoints.EnableEndSessionEndpoint) { document.frontchannel_logout_session_supported = true; document.frontchannel_logout_supported = true; document.end_session_endpoint = baseUrl + Constants.ProtocolRoutePaths.EndSession; } if (_options.Endpoints.EnableCheckSessionEndpoint) { document.check_session_iframe = baseUrl + Constants.ProtocolRoutePaths.CheckSession; } if (_options.Endpoints.EnableTokenRevocationEndpoint) { document.revocation_endpoint = baseUrl + Constants.ProtocolRoutePaths.Revocation; } if (_options.Endpoints.EnableIntrospectionEndpoint) { document.introspection_endpoint = baseUrl + Constants.ProtocolRoutePaths.Introspection; } } if (_options.DiscoveryOptions.ShowKeySet) { if ((await _keys.GetValidationKeysAsync()).Any()) { document.jwks_uri = baseUrl + Constants.ProtocolRoutePaths.DiscoveryWebKeys; } } return(new DiscoveryDocumentResult(document, _options.DiscoveryOptions.CustomEntries)); }