Disallow and redirect user to a different page after social login in ASP.NET Core

Viewed 266

I'm implementing authentication in ASP.NET Core with social providers using the authentication middleware (no Identity). Things are working with the following configuration:

services
    .AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.RequireAuthenticatedSignIn = false;
    })
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
    {
        options.LoginPath = "/login";
        options.LogoutPath = "/account/logout";
    })
    .AddGoogle(options =>
    {
        options.ClientId = "...";
        options.ClientSecret = "...";
        options.Events = new OAuthEvents
        {
            OnTicketReceived = ctx =>
            {
                ...
            }
        };
    });

When redirecting the user to the Google challenge and they sign in, my site successfully authenticates with cookie auth.

Now, I want greater control of what should happen when the user sign in. I want to verify a few requirements in OnTicketReceived and disallow the sign in with cookie auth in some cases.

Consider code like this forOnTicketReceived:

OnTicketReceived = ctx =>
{
    if (someRequirementNotMet)
    {
         // User should not be logged in and redirected to /login
         // CODE MISSING HERE!
    }

    if (someCondition)
    {
         // User should be logged in and redirected to /somepage
         ctx.ReturnUri = "/somepage";
         return Task.CompletedTask;
    }

    // User should be logged in and redirected to /someotherpage
    ctx.ReturnUri = "/someotherpage";
    return Task.CompletedTask;
}

How would I achieve this? I've tried this:

ctx.ReturnUri = "/login";
return Task.CompletedTask;

inside the first if. But the user is logged in when redirected to /login. I've also tried to call ctx.HandleResponse() but this simply generates a blank result.

1 Answers

I figured out how this can be solved:

OnTicketReceived = ctx =>
{
    if (someRequirementNotMet)
    {
         // User should not be logged in and redirected to /login
         ctx.HandleResponse();
         ctx.Response.Redirect("/login");
         return Task.CompletedTask;
    }

    if (someCondition)
    {
         // User should be logged in and redirected to /somepage
         ctx.ReturnUri = "/somepage";
         return Task.CompletedTask;
    }

    // User should be logged in and redirected to /someotherpage
    ctx.ReturnUri = "/someotherpage";
    return Task.CompletedTask;
}
Related