4

I am facing issues while implementing external login in asp.net core 2.2 (mvc) without using identity. After signing in to google it redirect back to callback url that is throwing exception as attached in the image below.

Exception: The oauth state was missing or invalid.

Unknown location

Exception: An error was encountered while handling the remote login.

Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()

For more detailed steps that I did, please check here

enter image description here

Below is Startup.cs settings

 public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services
            .AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
            })
            .AddCookie(options =>
            {
                options.Cookie.IsEssential = true;
            })
            .AddGoogle(options =>
            {
                options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.ClientId = Configuration["Authentication:Google:ClientId"];
                options.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
                options.CallbackPath = "/externallogincallback";

            });

              services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

Below is my HomeController.cs settings

 //Action to issue a challange to google login
    public IActionResult Google(string provider)
    {
        provider = "Google";
        //Issue a challenge to external login middleware to trigger sign in process
        //return new ChallengeResult(provider);

        var authenticationProperties = new AuthenticationProperties
        {
            RedirectUri = Url.Action("externallogincallback")
        };          

        return Challenge(authenticationProperties, "Google");
    }

    //Callback action to retrive signin user details
    [HttpGet("externallogincallback", Name = "externallogincallback")]
    [AllowAnonymous]
    public Task<IActionResult> externallogincallback(string returnUrl = null, string remoteError = null)
    {
        //Here we can retrieve the claims
        var result =  HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);

        return null;
    }

In Google console setting Authorized redirect URIs

For use with requests from a web server. This is the path in your application that users are redirected to after they have authenticated with Google. The path will be appended with the authorization code for access. Must have a protocol. Cannot contain URL fragments or relative paths. Cannot be a public IP address.

https://localhost:44379/externallogincallback 
ramya
  • 2,350
  • 6
  • 31
  • 57

5 Answers5

2

It is a bit confusing... The options.CallbackPath is not the path to your Controller/Action. It just must be the same as registered in your 3rd party provider (Google, or so...). By default it is signin-google, and this callback handler is taken by IdentityServer. The callback externallogincallback is actually set in the ChallengeResult. So, if you set the options.CallbackPath and Challenge(RediretUrl) as the same, which means it has two hanlders with same name/route, ASP.NET will run in error.

Vincent Shen
  • 83
  • 1
  • 1
  • 8
0

Remove callbackpath from setting

options.CallbackPath = "/externallogincallback";
leonheess
  • 16,068
  • 14
  • 77
  • 112
Ranmal
  • 9
  • 2
0

You have probably used routing in the startup and you need to define the following routing for this url

            routes.MapRoute(
                 name: "GoogleResponse",
                 template: "externallogincallback ",
                defaults: new { controller = "Home", action = "externallogincallback" });
Ehsan Babaei
  • 105
  • 4
0

As was mentioned removing options.CallbackPath is the right answer. It is because options.CallbackPath serves not as your API endpoint that will continue to execute after login rather than it serves as endpoint for some internal auth logic. More details in my answer here https://stackoverflow.com/a/61950614/9547346

osynavets
  • 1,199
  • 1
  • 12
  • 22
0

I had same problem before, it was port mismatch with redirect url. Check your lauchSetting.json's default port number.

sangeun jo
  • 37
  • 9