Home ASP.NET Core 2.1 Authentication with social logins
Post
Cancel

ASP.NET Core 2.1 Authentication with social logins

This post is part of a series on ASP.NET Core 2.0 Authentication and I am going to talk about sign-in via social or third-party providers like Facebook, Twitter or GitHub.

Application

In this post I will setup a new ASP.NET 2.1 MVC application, without any security mechanism scaffolded, I will actually setup logins based on various social providers like Facebook, Twitter and Github.
This time I will only talk about securing the application with the minimum identity claims provided by the social providers. In coming posts I will focus on enriching the experience, requiring even more information, but let's keep this one really simple.

Ergo, application will be kept very simple, with a secure page that outlines authenticated user's claims.
Login is handled by a page which lists the available social providers. User has also the ability to sign-out from the application.

Source Code

Code outlined in this article can be found on Github.

Social Providers

Many scenarios require applications that need to work with a social provider, like Facebook, Twitter, Github, LinkedIn, Instagram, etc.
The application may need to access specific user Id's, or photos, or posts, etc.
Maybe using local logins is not possible for your application. This is where social logins shine. Using a social login is much more easier process than specifying you own store, handle users, role, claims, etc., handle sign-in, sign-out, sign-up.
What do we need though to set this up?

In order to get up-and-running with a social provider we need to register the application with that provider.

Then we need a way to handle OAuth/OIDC (Open Id Connect) redirects with the provider. Remember that the application does not take/store any credentials from the user, it is merely redirecting to the social provider, which signs-in the user and redirects back to the application with an authorization code (depends on the flow the provider supports, but most of the times this is the flow).

Next, we need to handle cookies, meaning that we must store the OAuth code on a cookie. This code is exchanged with the provider for a cookie. Finally, we must find a way to sign-out from the application.

I hope, by now, you understand how much easier it is to set this up rather a local login. As mentioned earlier, local logins would require you to set up

  • a data store, for example SQL Server or MySQL, and a schema to define users, roles, user claims and other stuff. Check the previous posts on local logins to find out how much work I had to do in order to create a store.
  • a way to validate user credentials and encrypt them.
  • login, logout and sign-up screens.

But when setting social logins, you don't need to go through all this fuss. Just setup the provider and some keys and let the application handle the rest.

Setup MVC application

First I am going to setup the MVC application quickly. Select your workspace, open command prompt and use the dotnet CLI to create the app.
Please note, that I am going to create an ASP.NET Core 2.1 MVC application, so if you want to follow along, make sure to download latest .NET Core 2.1 SDK. I am working on Windows 10 x64, so I will need the x64 installer.
If you wish to work on ASP.NET Core 2.1 that is no problem, just follow along, you will only need to use the 2.0 NuGet packages instead of 2.1-preview.


> dotnet new mvc -au None -n Social.Logins.Web
> dotnet new sln -n Authentication
> dotnet sln add Social.Logins.Web\Social.Logins.Web.csproj

Social.Logins.Web is the MVC application. If you want to know the app URL, navigate into project's folder, under Properties you will find the launchSettings.json. Open it and locate the applicationUrl under iisExpress. Its value ishttp://localhost:45138. You will also need the HTTPS URL, which is also listed there,https://localhost:44393/.

Let's quickly add the required Microsoft.AspNetCore.Authentication NuGet packages in Social.Logins.Web project.

> dotnet add package Microsoft.AspNetCore.Authentication.Facebook --version 2.1.0-preview1-final
>dotnet add package Microsoft.AspNetCore.Authentication.Twitter --version 2.1.0-preview1-final
>dotnet add package AspNet.Security.OAuth.GitHub --version 2.0.0-rc2-final

Before jumping into code, let me quickly show you how to register you application in Facebook, Twitter and Github.
Remember, the application's running in localhost in http://localhost:45138 andhttps://localhost:44393.

Facebook

Go tohttps://developers.facebook.com/ and on top right menu, select My Apps and Add New App.
Provide a name for your app and an email. Hit Create App ID.

Select Facebook Login in products screen

And Web in the quickstart screen

Insert the application URL found in launchsettings.jsonand click save.

Go to the Facebook Login product Settings and make sure to add the following redirect URIs in Client OAuth Settings. By default ASP.NET Core is using the /signin-facebook redirect URI. Be sure to add for HTTPS as well, cause the ASP.NET Core 2.1 application is running in HTTPS.

In Settings > Basic make sure to copy the App ID and the App Secret. You will need them later in Facebook authentication setup.

Twitter

Go tohttps://apps.twitter.com/ and create a new app. I will use the default ASP.NET Core callback URI which is /signin-twitter.

Copy the consumer key and consumer secret for later usage.

Github

Go tohttps://github.com/settings/developers and create a new OAuth app.

Provide the callback URL with the default /signin-github URI.
Fill rest of required settings if you wish.

Copy the client Id and client secret to use them in application setup.

Implementation

Now that I have registered the application with those providers, it is time to configure them in code.
So, in Startup.cs, I will need to register these providers in authentication services. In ConfigureServices add the following configuration for authentication

Notice there is an extension method for each provider thanks to installing the appropriate NuGet packages earlier. The configuration in those is minimum as you see, you only need to setup your keys, so the provider knows about this application. But all these take care of user authentication.
For signing-in the user, I have added a call to the cookie authentication handler, .AddCookie. Note that I have setup the LoginPath to match a custom sign-in action. This is where the unauthorized user will be redirected in a challenge. I've done this because I have more than one social providers registered with my application. If I had one, I wouldn't need that, cause I would just challenge the user against that sole provider.
Also note that I have setup the DefaultAuthenticateScheme, DefaultChallengeScheme and DefaultSignInScheme to cookie authentication.
DefaultChallengeScheme is setup to cookie authentication for the reasons I described above. I have more than one providers and I want a consolidated sign-in screen to present them to the user, so he/she decides with whom provider to sign-in.
DefaultSignInScheme is setup to cookie authentication because I would like the application to use the cookie authentication scheme by default when signing in the user after authentication has taken place.
DefaultAuthenticateScheme is setup to cookie authentication as the default when authenticating users on incoming requests.

Don't forget to register authentication in the pipeline, in Configure method.

Now that configuration is in place, let's write some code to demonstrate the social logins.

First, I will start by creating an AuthController, which has actions to sign-in and sign-out the user.
I have created a SignIn action, which lists all available providers. Next, I have a SignIn action again, but this time it is performing real sign-in operations. It takes a provider name as a route and an optional return URL. It returns a Challenge back to the user, based on the authentication scheme, which is the provider. It also configures the redirect URI to be the return URL passed, else it redirects back to home. We need to set that because if we don't the application will fall in a infinite loop of redirections with the provider.
SignOut action calls the SignOutAsync method on the cookie and returns back to home page.

Let's see the SignIn.cshtml view. It lists all registered social providers for the user. In order to fetch them, I have injected an instance ofIAuthenticationSchemeProvider, named it SchemeProvider and called the GetRequestHandlerSchemesAsync, which returns all the external providers. I pass all the required information in the anchor tag, along with the return URL that is created by the 401 challenge.

Next up, I will create a new controller, just to show authenticated user claims. I named the controller ProfileController, with a single Index action, which creates a view model based on user's claims and name, to show on screen.

And this is the view, it displays user's name and his claims.

Finally, I will show you the layout menu, which has links to sign-in and sign-out actions. SignIn menu item is showing when the user is not authenticated, otherwise there is a link that opens a modal for the user to logout. Reason I did not made SignOut a GET is because Chrome prefetches GET requests to speed up browsing. This would result signing the user out without reason, just because Chrome would prefetch the GET request (meaning Chrome would do a sign out and you won't even notice!).

This is the modal that has the SignOut action wrapped in a form, so Chrome will not prefetch that one.

Let's see this in action

Facebook

I open the Sign In screen and choose the Facebook Login. This redirects me to Facebook, whereas I have to authorize this app to use my profile.

Twitter

I open the Sign In screen and choose the Twitter Login. This redirects me to Twitter, whereas I have to authorize this app to use my profile.

GitHub

I open the Sign In screen and choose the GitHub Login. This redirects me to GitHub, whereas I have to authorize this app to use my profile.

Sign-out

To sign-out, I click on the link on the top right corner, which itself opens a new modal dialog. I click on the Sign Out button, which indeed, signs the user out.

 

Summary

In this post, I've registered with three social providers, Facebook, Twitter and Github, demonstrating how to secure your application.
I had to register these providers in Startup, with keys provided from their portals.
In next post I will show how to setup a profile store, so you can import additional information for the authenticated user.


This post is part of the ASP.NET Core 2.0 Authentication series.

  1. ASP.NET Core 2.0 Cookie Authentication - Local logins
  2. ASP.NET Core 2.0 Authentication with local logins - Implementing claims transformation
  3. ASP.NET Core 2.0 Authentication with local logins - Responding to backend changes
  4. ASP.NET Core 2.0 Authentication with local logins - Implementing custom authorization policies
  5. ASP.NET Core 2.1 Authentication with social logins
  6. ASP.NET Core 2.0 Authentication with social logins - Implementing a profile store
  7. ASP.NET Core 2.0 Authentication with Azure Active Directory
  8. ASP.NET Core 2.0 Authentication with Azure Active Directory B2C
  9. ASP.NET Core 2.0 Authentication, IdentityServer4 and Angular
This post is licensed under CC BY 4.0 by the author.

Setup .NET Core 2.1 project and test with XUnit on Linux VM

ASP.NET Core 2.0 Authentication with social logins - Implementing a profile store

Comments powered by Disqus.