Skip to content

Instantly share code, notes, and snippets.

@ilmax
Created July 31, 2020 13:19
Show Gist options
  • Save ilmax/dacc3e50206bf9801ec236e64abbc963 to your computer and use it in GitHub Desktop.
Save ilmax/dacc3e50206bf9801ec236e64abbc963 to your computer and use it in GitHub Desktop.
// Courtesy of https://github.com/IdentityServer/IdentityServer4/blob/18897890ce2cb020a71b836db030f3ed1ae57882/src/IdentityServer4/src/Endpoints/DiscoveryEndpoint.cs
// This slightly adjusts the original implementation to play nicely behind an application gateway so it checks if we have an X-original-host header and uses that as our baseUrl
internal class DiscoveryEndpointHandler : IEndpointHandler
{
private readonly ILogger _logger;
private readonly IdentityServerOptions _options;
private readonly IDiscoveryResponseGenerator _responseGenerator;
public DiscoveryEndpointHandler(
IdentityServerOptions options,
IDiscoveryResponseGenerator responseGenerator,
ILogger<DiscoveryEndpointHandler> logger)
{
_logger = logger;
_options = options;
_responseGenerator = responseGenerator;
}
public async Task<IEndpointResult> ProcessAsync(HttpContext context)
{
_logger.LogTrace("Processing discovery request.");
// validate HTTP
if (!HttpMethods.IsGet(context.Request.Method))
{
_logger.LogWarning("Discovery endpoint only supports GET requests");
return new StatusCodeResult(HttpStatusCode.MethodNotAllowed);
}
_logger.LogDebug("Start discovery request");
if (!_options.Endpoints.EnableDiscoveryEndpoint)
{
_logger.LogInformation("Discovery endpoint disabled. 404.");
return new StatusCodeResult(HttpStatusCode.NotFound);
}
var baseUrl = context.GetIdentityServerBaseUrl();
if (context.Request.Headers.TryGetValue("X-original-host", out var xOriginalHostValue))
{
// NOTE The value of X-original-host should only contain the host portion
var xOriginalHost = xOriginalHostValue.ToString();
var baseUrlBuilder = new UriBuilder(new Uri(baseUrl));
if (xOriginalHost.Length > 0 && xOriginalHost != baseUrlBuilder.Host)
{
baseUrlBuilder.Host = xOriginalHost;
baseUrl = baseUrlBuilder.Uri.AbsoluteUri;
}
}
var issuerUri = context.GetIdentityServerIssuerUri();
// generate response
_logger.LogTrace("Calling into discovery response generator: {type}", _responseGenerator.GetType().FullName);
var response = await _responseGenerator.CreateDiscoveryDocumentAsync(EnsureTrailingSlash(baseUrl), issuerUri);
return new DiscoveryDocumentResult(response, _options.Discovery.ResponseCacheInterval);
static string EnsureTrailingSlash(string url)
{
if (url != null && !url.EndsWith("/"))
{
return url + "/";
}
return url;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment