Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net Core Identity 2 Provider login Cancel leads to unhandled exception

I've added LinkedIn as a provider. I have implemented the login and register with LinkedIn without any issue. In the use case where the user CANCELS from within the provider Pages (either linkedIn login or cancels the authorization of the app) the identity middleware seems to throw an unhandled exception:

An unhandled exception occurred while processing the request.
Exception: user_cancelled_login;Description=The user cancelled LinkedIn login
Unknown location

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

Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()

System.Exception: user_cancelled_login;Description=The user cancelled LinkedIn login

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

The provider setup in startup defines the callback:

services.AddAuthentication().AddOAuth("LinkedIn", "LinkedIn", c =>
        {
            c.ClientId = Configuration["Authentication:LinkedIn:ClientId"];
            c.ClientSecret = Configuration["Authentication:LinkedIn:ClientSecret"];
            c.Scope.Add("r_basicprofile");
            c.Scope.Add("r_emailaddress");
            c.CallbackPath = "/signin-linkedin";
....

And As I have said the middleware seems to handled ALL other cases except where the user cancels within the LinkedIn pages. The return URL from LinkedIn looks correct:

https://localhost:44372/signin-linkedin?error=user_cancelled_login&error_description=The+user+cancelled+LinkedIn+login&state=CfDJ8MA7iQUuXmhBuZKmyWK9xeAgBBkQvnhf1akLhCIn9bsajCPUf7Wg22oeZBH9jZOIY3YrchMSWZ4dH7NQ1UngLKEuqgU-IHfBglbgJDtS-wc4Z-6DnW66uR0G1ubvNVqatFJHYv17pgqZT98suVkvKgihcJdbNEw7b1ThkuFbn9-5EcYhQ5ln6ImoTgthT8io1DOcCfc_-nBVfOa93a6CpUJTsZc9w93i70jn5dKKXSLntZe0VyRSA0r0PKc5spu5En-0R1rxiLjsjo4dy89PV3A

But never gets to my ExternalCallback controller method where the other cases like successful login/authorization are handled??

I'm wondering if this is working for anyone else with 3rd part providers?

like image 471
billy jean Avatar asked Jun 19 '18 23:06

billy jean


2 Answers

There's a Github issue that explains what's happening here in more detail, with a bit of information as to why it's happening and even an indication that this won't be "fixed":

Handling the RemoteFailure event is the right thing to do. We should update our docs/samples to show how to handle that event and at least show a more appropriate message to the user. The error page sample could include a link to enabled the user to try logging in again.

Unfortunately it's difficult to implement this event in a very generic way that's also super useful because each remote auth provider has its own behavior for different types of failures.

The workaround for this (as quoted above) is to handle the RemoteFailure event:

services.AddAuthentication().AddOAuth("LinkedIn", "LinkedIn", c => {
    // ...
    c.Events.OnRemoteFailure = ctx =>
    {
        // React to the error here. See the notes below.
        return Task.CompletedTask;
    }
    // ...
});

ctx is an instance of RemoteFailureContext, which includes an Exception property describing what went wrong. ctx also contains a HttpContext property, allowing you to perform redirects, etc, in response to such exceptions.

like image 72
Kirk Larkin Avatar answered Sep 29 '22 11:09

Kirk Larkin


I've found the following to work well for me, based on this and similar to Kirk Larkin's answer. The part that took a little figuring out was where to redirect to, without causing problems for subsequent login attempts.

services.AddAuthentication().AddOAuth("LinkedIn", "LinkedIn", c =>
{
    ...
    c.Events = new OAuthEvents()
    {
        OnRemoteFailure = (context) =>
        {
            context.Response.Redirect(context.Properties.GetString("returnUrl"));
            context.HandleResponse();
            return Task.CompletedTask;
        }
    };
};
like image 34
Chris Peacock Avatar answered Sep 29 '22 13:09

Chris Peacock