Implementing Token-Based Authentication in ASP.NET Core with Entrypage.io
This guide provides a step-by-step explanation of how to implement token-based authentication and authorization in an ASP.NET Core application using Entrypage.io as your identity provider.
Prerequisites:
- Entrypage-account
- .NET SDK
The implementation of OAuth in a web application depends on the type of app you are building. This guide covers the two most common approaches: an ASP.NET Core MVC Application and an ASP.NET Core API.
Implementing OAuth in an ASP.NET Core MVC Application
In an ASP.NET Core MVC application, the user authenticates with your site, which then initiates a local session. The authorization server’s primary role is simply to authenticate the user and confirm their identity.
This process follows a standard flow:
- A user visits the website and clicks “log in.”
- The user is redirected to the authorization server to authenticate, then redirected back to the website.
- The website validates the authentication and creates a secure session for the user.
- To authenticate the user, we will use the (Authorization Code with PKCE grant)[/wiki/oauth/what-is-authorization-code-with-proof-key-for-fode-exchange-pkce/] flow, a highly secure and recommended method.
This section covers:
- Setting up an Entrypage.io Authorization Server.
- Creating an ASP.NET Core MVC App and installing the necessary dependencies.
- Configuring the MVC App to authenticate with the authorization server.
1. Configuring the Authorization Server
To set up your authorization server with Entrypage.io, follow these steps:
- Go to portal.entrypage.io and sign in to your account.
- Navigate to the
Clients
tab and create a new client. - Configure the client with
PKCE
enabled. - Configure the client with a Client Secret.
- Set the
client_id
toaspnetcore-mvc-app
.- Configure the redirect_uri: ASP.NET Core redirects authorization requests back to /signin-oidc, so your client must contain the following redirect_uri: https://localhost:5678/signin-oidc.
- Note: Be sure to only use localhost addresses in sandbox domains. Never use a localhost redirect URI in a production environment.
Once this is complete, you are ready to configure your application.
2. Create the ASP.NET Core Application
Use your console or your favorite IDE to create a new MVC application and install the required NuGet packages:
dotnet new webapp
dotnet add package Microsoft.AspNetCore.Authentication.OAuth
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
This command will create a blank ASP.NET Core Razor application and add the libraries you need to perform the handshake with an OpenID Authorization Server and interpret the results.
3. Configure the Application to Authenticate
To activate the authentication and authorization packages, the application needs to be configured to use them. This is done through activating them in the program.cs file:
To enable the authentication and authorization packages, you must configure your application in the Program.cs file.
var builder = WebApplication.CreateBuilder(args);
builder
.Services
.AddAuthentication(o =>
{
o.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = "entrypage";
o.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(o =>
{
o.Cookie.SameSite = SameSiteMode.Strict;
o.Cookie.HttpOnly = true;
}).AddOpenIdConnect("entrypage", options =>
{
options.Authority = "https://exemple-test.sandbox.entrypage.io";
options.ClientId = "aspnetcore-mvc-app";
options.ClientSecret = "paste-your-client-secret-here";
options.SaveTokens = true;
options.UsePkce = true;
options.ResponseType = "code";
});
This code snippet does the following:
- It tells the ASP.NET Core pipeline which Identity Provider to use for authenticating users.
- It configures a cookie to persist the authentication, which creates a secure “session.” This allows the user to browse your application without having to re-authenticate with every click.
- It establishes the connection to your authorization server by providing the authority, client ID, and client secret.
4. Initiating Authentication
Once you’ve completed the previous step, you’re ready to move to the next step of the authentication process: triggering the challenge. This is how you initiate the OAuth handshake, redirecting the user to the identity provider (in this case, Entrypage.io) to log in.
The easiest way to do this with minimal code is by creating a simple endpoint that manually triggers the challenge.
The core of this process is the ChallengeAsync
method on the HttpContext. Think of a “challenge” as a polite request from your application to the user, saying, “Hey, you need to prove who you are.” This method tells ASP.NET Core’s authentication middleware to initiate the login flow for a specific scheme, which you’ve already configured to point to Entrypage.io:
app.MapGet("/login", async (context) =>
{
var authenticationOptions = new AuthenticationProperties
{
RedirectUri = "/",
};
await context.ChallengeAsync("entrypage", authenticationOptions);
});
- app.MapGet("/login", …): This creates a simple GET endpoint at the /login URL. Your front end can point to this endpoint, for example, via a “Sign in” button.
- AuthenticationProperties: This is a class that allows you to pass extra data along during the authentication process. In this case, we use it to specify the RedirectUri. This tells ASP.NET Core where to send the user after they have successfully logged in. Setting it to “/” will redirect the user to your application’s root page.
- context.ChallengeAsync(“entrypage”, …): This is the action that triggers everything. It instructs the middleware to perform the challenge for the scheme named “entrypage”, using the authenticationOptions you just defined.
Enforcing authorization
Configuring ASP.NET Core this way, allows the usage of the following ASP.NET Concepts and technology:
The Authorize attribute
By decorating controllermethods with the Authorize
attribute, ASP.NET Core knows these endpoints require authorization and it will deny access if the use has not authenticated.
Example:
public class MyController : Controller
{
[HttpGet]
[Authorize] // Add this line to require authorization
public IActionResult Get()
{
return Ok();
}
}
Or with minimal API:
app.MapGet("/my/secret/resource", (context) =>
{
var result = Results.Ok();
return Task.FromResult(result);
})
.RequireAuthorization(); // Add this line to require authorization
Summary
Once you have successfully configured the authentication and authorization middleware, you’ve laid the secure foundation for your application. The final Program.cs
file encapsulates all the necessary logic to handle user logins, manage sessions, and protect your resources.
With the core authentication flow in place, you are now equipped to build a fully functional application. The next steps involve integrating this setup into your user interface and expanding your protected endpoints. You can create a login button that points to the /login endpoint and a logout button that uses context.SignOutAsync(). For example, in a Razor Page, a login link would look like this:
<a asp-page="/login">Log In</a>
You can also use the [Authorize]
attribute to protect more complex parts of your application, ensuring that only authenticated users can access specific pages or API endpoints. This modular approach allows you to secure your application piece by piece, building on the strong foundation you’ve established.
For further exploration and a complete, runnable example, you can find the entire source code for this project on GitHub.
Find the complete code at GitHub