Change AspNetCore2 Oauth redirect handler

664 Views Asked by At

TL;DR

How do I change the behaviour of the redirect_url endpoint? I want to process SAML which obviously isn't a JWT.

All the gory details

You've probably seen code like this

Microsoft.AspNetCore.Authentication.AuthenticationBuilder authBuilder;
authBuilder = services.AddAuthentication();
...
authBuilder.AddGitHub(gitHubOptions =>
{
  gitHubOptions.AppId = clientId;
  gitHubOptions.AppSecret = clientSecret;
});

Rummaging through the source code for the GitHub provider we find that AddGitHub is an extension method that looks like this

public static AuthenticationBuilder AddGitHub(
    [NotNull] this AuthenticationBuilder builder,
    [NotNull] Action<GitHubAuthenticationOptions> configuration)
{
    return builder.AddGitHub(GitHubAuthenticationDefaults.AuthenticationScheme, configuration);
}

GitHubAuthenticationDefaults.AuthenticationScheme is just a string constant with the value "GitHub". If you want to re-use the same provider with more than one authentication endpoint then you have to use a different scheme name.

There's a succession of calls to signature overloads adding parameters and ending here.

public static AuthenticationBuilder AddGitHub(
    [NotNull] this AuthenticationBuilder builder,
    [NotNull] string scheme, [CanBeNull] string caption,
    [NotNull] Action<GitHubAuthenticationOptions> configuration)
{
    return builder.AddOAuth<GitHubAuthenticationOptions, GitHubAuthenticationHandler>(scheme, caption, configuration);
}

DisplayName also defaults to "GitHub" and isn't significant. Config we supplied above. So really we're calling AuthenticationBuilder.AddOAuth with two strings and our config object.

This call magically creates a redirection endpoint called signin-github which processes the token returned by the GitHub auth service.

The obvious next step is to clone the aspnet/Security repo, link a sample project to it and step through the magic, but naturally it targets Core 2.1 which everyone1 has.

More rummaging turns up this.

public static AuthenticationBuilder AddOAuth<TOptions, THandler>(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<TOptions> configureOptions)
    where TOptions : OAuthOptions, new()
    where THandler : OAuthHandler<TOptions>
{
    builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<TOptions>, OAuthPostConfigureOptions<TOptions, THandler>>());
  return builder.AddRemoteScheme<TOptions, THandler>(authenticationScheme, displayName, configureOptions);
}

It's an awful lot of code to wade through. Can anyone tell me where and how the redirection handler endpoint is generated, and how one goes about providing replacement behaviour for it?

Line 89 of OAuthHandler.cs looks promising

var tokens = await ExchangeCodeAsync(code, BuildRedirectUri(Options.CallbackPath));

because this appears to be the logic that swaps the CODE for the tokens and it is overridable, but it's very difficult to be sure when I can't run it.


  1. By "everyone" I mean everyone on the aspnetcore dev team, obviously.
0

There are 0 best solutions below