How to Implement Authentication in ASP.NET Core (Google, Facebook, Twitter)

Implementing Authentication in ASP.NET Core: A Complete Guide with Social Login and MFA

When you think about securing your web applications, the first line of action is authentication. And with ASP.NET Core as a powerful yet flexible framework, putting up robust authentication mechanisms is made very easy. This post I will guide you through setting up authentication for your ASP.NET Core application. Here, we’ll cover social login integration with providers like Google, Facebook, and Twitter, along with detailed OAuth configuration steps and Multi-Factor Authentication (MFA).

Step 1: Setting Up Your ASP.NET Core Project

First, ensure you have the latest version of .NET Core SDK installed. Create a new ASP.NET Core project using the command line by running the following command:

dotnet new webapp -n AuthDemo
cd AuthDemo

Step 2: Adding Authentication Packages

Add the required NuGet packages for authentication. Here we use Identity, which has in-built features for user registration, login, and management.

dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.AspNetCore.Authentication.Google
dotnet add package Microsoft.AspNetCore.Authentication.Facebook
dotnet add package Microsoft.AspNetCore.Authentication.Twitter

Step 3: Configuring Services

Open Startup.cs and configure the services required for authentication in the ConfigureServices method. Here’s example get you started:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddAuthentication()
        .AddGoogle(options =>
        {
            options.ClientId = Configuration["Authentication:Google:ClientId"];
            options.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
        })
        .AddFacebook(options =>
        {
            options.AppId = Configuration["Authentication:Facebook:AppId"];
            options.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
        })
        .AddTwitter(options =>
        {
            options.ConsumerKey = Configuration["Authentication:Twitter:ConsumerKey"];
            options.ConsumerSecret = Configuration["Authentication:Twitter:ConsumerSecret"];
            options.RetrieveUserDetails = true;
        });

    services.AddRazorPages();
}

Don’t forget to add the connection string and authentication settings in appsettings.json:

"ConnectionStrings": {
  "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-AuthDemo;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"Authentication": {
  "Google": {
    "ClientId": "YOUR_GOOGLE_CLIENT_ID",
    "ClientSecret": "YOUR_GOOGLE_CLIENT_SECRET"
  },
  "Facebook": {
    "AppId": "YOUR_FACEBOOK_APP_ID",
    "AppSecret": "YOUR_FACEBOOK_APP_SECRET"
  },
  "Twitter": {
    "ConsumerKey": "YOUR_TWITTER_CONSUMER_KEY",
    "ConsumerSecret": "YOUR_TWITTER_CONSUMER_SECRET"
  }
}

Step 4: OAuth Configuration Steps

Google OAuth Configuration:

  1. Go to the Google Developers Console.
  2. Create a new project or select an existing one.
  3. Navigate to the “Credentials” tab.
  4. Click on “Create Credentials” and select “OAuth 2.0 Client IDs”.
  5. Set the application type to “Web application”.
  6. Add the authorized redirect URIs (e.g., https://localhost:5001/signin-google).
  7. Save the Client ID and Client Secret in your appsettings.json.

Facebook OAuth Configuration:

  1. Go to the Facebook Developers page.
  2. Create a new app.
  3. Add “Facebook Login” to your app.
  4. Navigate to the “Settings” under “Facebook Login”.
  5. Add the valid OAuth redirect URIs (e.g., https://localhost:5001/signin-facebook).
  6. Save the App ID and App Secret in your appsettings.json.

Twitter OAuth Configuration:

  1. Go to the Twitter Developer Portal.
  2. Create a new project and an app within the project.
  3. Navigate to the “Keys and tokens” tab.
  4. Generate the Consumer Key (API Key) and Consumer Secret (API Secret Key).
  5. Set the callback URL (e.g., https://localhost:5001/signin-twitter).
  6. Save the Consumer Key and Consumer Secret in your appsettings.json.

Step 5: Adding Middleware

In the Configure method of Startup.cs, add the authentication and authorization middleware. Here’s example:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Step 6: Creating Identity Pages

To scaffold the Identity pages, run the following command:

dotnet aspnet-codegenerator identity -dc ApplicationDbContext

This command generates the necessary pages for user registration, login, and management.

Step 7: Applying Migrations

Finally, apply the migrations to create the necessary database schema by running the following commands:

dotnet ef migrations add InitialSetup
dotnet ef database update

Step 8: Updating the Login Page

Update the login page to include options for social login. In Areas/Identity/Pages/Account/Login.cshtml, add buttons or links for Google, Facebook, and Twitter login. Here’s an example of what you might add:

@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Identity

@page
@model LoginModel

<h2>Log in</h2>

<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
    <!-- Existing login fields here -->
    <button type="submit" class="btn btn-primary">Log in</button>
    <div>
        <hr />
        <p>Or log in with:</p>
        <a asp-area="Identity" asp-page="/Account/ExternalLogin" asp-route-provider="Google" asp-route-returnUrl="@Model.ReturnUrl" class="btn btn-default">
            Google
        </a>
        <a asp-area="Identity" asp-page="/Account/ExternalLogin" asp-route-provider="Facebook" asp-route-returnUrl="@Model.ReturnUrl" class="btn btn-default">
            Facebook
        </a>
        <a asp-area="Identity" asp-page="/Account/ExternalLogin" asp-route-provider="Twitter" asp-route-returnUrl="@Model.ReturnUrl" class="btn btn-default">
            Twitter
        </a>
    </div>
</form>

Step 9: Configuring Multi-Factor Authentication (MFA)

To enable multi-factor authentication, update the ConfigureServices method in Startup.cs for MFA options:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<IdentityUser>(options =>
    {
        options.SignIn.RequireConfirmedAccount = true;
        options.Tokens.AuthenticatorTokenProvider = TokenOptions.DefaultAuthenticatorProvider;
        options.SignIn.RequireConfirmedEmail = true;
        options.Lockout.AllowedForNewUsers = true;
        options.Lockout.MaxFailedAccessAttempts = 5;
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
    })
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

    services.Configure<DataProtectionTokenProviderOptions>(options =>
        options.TokenLifespan = TimeSpan.FromHours(3));

    services.AddAuthentication()
        .AddGoogle(options =>
        {
            options.ClientId = Configuration["Authentication:Google:ClientId"];
            options.ClientSecret = Configuration["Authentication:Google:ClientSecret"];
        })
        .AddFacebook(options =>
        {
            options.AppId = Configuration["Authentication:Facebook:AppId"];
            options.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
        })
        .AddTwitter(options =>
        {
            options.ConsumerKey = Configuration["Authentication:Twitter:ConsumerKey"];
            options.ConsumerSecret = Configuration["Authentication:Twitter:ConsumerSecret"];
            options.RetrieveUserDetails = true;
        });

    services.AddRazorPages();
}

Update the Login.cshtml page to be MFA-aware:

@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Identity

@page
@model LoginModel

<h2>Log in</h2>

<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
    <!-- Existing login fields here -->
    <button type="submit" class="btn btn-primary">Log in</button>
    <div>
        <hr />
        <p>Or log in with:</p>
        <a asp-area="Identity" asp-page="/Account/ExternalLogin" asp-route-provider="Google" asp-route-returnUrl="@Model.ReturnUrl" class="btn btn-default">
            Google
        </a>
        <a asp-area="Identity" asp-page="/Account/ExternalLogin" asp-route-provider="

Facebook" asp-route-returnUrl="@Model.ReturnUrl" class="btn btn-default">
            Facebook
        </a>
        <a asp-area="Identity" asp-page="/Account/ExternalLogin" asp-route-provider="Twitter" asp-route-returnUrl="@Model.ReturnUrl" class="btn btn-default">
            Twitter
        </a>
    </div>
</form>

<hr />
<p>Enable Multi-Factor Authentication:</p>
<form asp-page-handler="EnableMFA" method="post">
    <button type="submit" class="btn btn-default">Enable MFA</button>
</form>

Add the backend logic to handle enabling MFA in the LoginModel.cs:

public class LoginModel : PageModel
{
    private readonly SignInManager<IdentityUser> _signInManager;
    private readonly UserManager<IdentityUser> _userManager;

    public LoginModel(SignInManager<IdentityUser> signInManager, UserManager<IdentityUser> userManager)
    {
        _signInManager = signInManager;
        _userManager = userManager;
    }

    public async Task<IActionResult> OnPostEnableMFAAsync()
    {
        var user = await _userManager.GetUserAsync(User);
        if (user == null)
        {
            return NotFound("Unable to load user.");
        }

        var isMfaEnabled = await _userManager.GetTwoFactorEnabledAsync(user);
        if (!isMfaEnabled)
        {
            var token = await _userManager.GenerateTwoFactorTokenAsync(user, "Authenticator");
            // Send the token to the user (e.g., via email or SMS)
            // Here, you would implement your logic to send the token
        }

        return RedirectToPage();
    }
}

Did you find this post useful? Have any questions or feedback? Please leave your comments below. Your feedback helps us improve and create more valuable content for you! If you follow these steps, then a firm ground shall be laid to secure your ASP.NET Core applications. Further, stay tuned for our detailed walkthroughs about effective ways of extending and customizing your authentication system!

Please enable JavaScript in your browser to complete this form.
Did you find this post useful?

Leave a Reply

Your email address will not be published. Required fields are marked *