asp.net-corehttp-redirecturigoogle-authenticationbase-path

Extra slash in redirect_uri


I have added a google authentication to my application in Startup.cs.

services.AddAuthentication()
    .AddGoogle(googleOptions =>
    {
        googleOptions.ClientId = "xxx";
        googleOptions.ClientSecret = "xxx";
    });

Also i have an page which redirects to external provider.

public IActionResult OnPost(string provider, string returnUrl = null)
{
    string redirectUrl = Url.Page("./ExternalLogin", pageHandler: "Callback", values: new { returnUrl });
    Microsoft.AspNetCore.Authentication.AuthenticationProperties properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
    return new ChallengeResult(provider, properties);
}

In my application i need to specify Base Path.

<base href="/anystring/" />
app.Use((context, next) =>
{
    context.Request.PathBase = "/anystring/";
    return next.Invoke();
});

The problem is that redirect_uri is incorrect on redirect to external provider - there is an extra slash in combined path: http://localhost:4200/anystring//signin-google.

Expected redirect_uri is: http://localhost:4200/anystring/signin-google

The same problem occurs when i try to use any other external login provider.

But when '/' is used as base path - everything works fine and there is no extra slash in the redirect_uri.

I tried to trim trailing slash from the return url:

public IActionResult OnPost(string provider, string returnUrl = null)
{
    returnUrl = returnUrl?.TrimEnd('/'); // trim trailing slash
    string redirectUrl = Url.Page("./ExternalLogin", pageHandler: "Callback", values: new { returnUrl });
    Microsoft.AspNetCore.Authentication.AuthenticationProperties properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
    return new ChallengeResult(provider, properties);
}

But this solution does not help and it does not look like a good solution.


Solution

  • Path base should be trimmed to fix this issue.

    app.Use((context, next) =>
    {
        context.Request.PathBase = "/anystring/".TrimEnd('/');
        return next.Invoke();
    });