Featured resource
2026 Tech Forecast
2026 Tech Forecast

1,500+ tech insiders, business leaders, and Pluralsight Authors share their predictions on what’s shifting fastest and how to stay ahead.

Download the forecast
  • Lab
    • Libraries: If you want this lab, consider one of these libraries.
    • Core Tech
Labs

Guided: Adding Authentication and Authorization to an ASP.NET Core 10 App

In this hands-on CodeLab, you will introduce cookie-based authentication and authorization into an existing ASP.NET Core 10 MVC application. You will register authentication services, setup middleware, and implement a simple login flow among other features. By the end of this lab, you will have demonstrated a practical understanding of how ASP.NET Core’s authentication and authorization pipeline fits together.

Lab platform
Lab Info
Level
Intermediate
Last updated
Apr 17, 2026
Duration
44m

Contact sales

By clicking submit, you agree to our Privacy Policy and Terms of Use, and consent to receive marketing emails from Pluralsight.
Table of Contents
  1. Challenge

    Introduction

    Welcome to the Guided: Adding Authentication and Authorization to an ASP.NET Core 10 App CodeLab. In this CodeLab, you will add cookie-based authentication and authorization to PsTaskboard, an existing ASP.NET Core 10 MVC application. PsTaskboard is a lightweight project-tracking board with a Home page and a Projects list seeded with in-memory data—controllers, views, view models, and a repository are already wired up and working.

    By the end of this lab you will have demonstrated how ASP.NET Core's authentication and authorization pipeline fits together: how services are registered, how middleware reads identity and enforces policy, how [Authorize] and [AllowAnonymous] control access, and how SignInAsync / SignOutAsync manage user sessions through cookies.

    Note: This lab does not involve passwords or user stores. The focus is on the pipeline mechanics of cookie authentication—how cookies are issued, read, and evaluated—not on credential validation. You will log in with just a username. This is intentional: it isolates the concepts you are learning from the complexity of password hashing, storing credentials, or user management, which are separate topics.

    You are given starter-code, and it contains TODO comments which align with the instructions, indicating where you'll add or modify code.

    There is a solutions directory containing the completed code for each step. You can refer to these if you get stuck or want to see the finished implementation. You do not need to have the exact same code as the solutions to pass the tests—there may be multiple valid ways to implement the TODOs, and the tests are designed to allow for that flexibility. The solutions are provided as a reference, not a template.

  2. Challenge

    Step 1: Configure the Authentication and Authorization Pipeline

    Objective: Register cookie authentication services and activate the authentication and authorization middleware in the correct order.


    Background

    ASP.NET Core's security model has two distinct layers that work together:

    • Authentication defines "Who is this user?" It reads incoming requests for credentials (in this case, a cookie), deserializes them into a ClaimsPrincipal, and populates HttpContext.User. This happens in two parts: first, a cookie authentication handler is registered in the dependency injection container (AddAuthentication + AddCookie); then, the UseAuthentication() middleware is added to the request pipeline to invoke that handler on every request.

    • Authorization addresses "Is this user allowed to do this?" The UseAuthorization() middleware reads endpoint metadata — attributes like [Authorize] and [AllowAnonymous] — and decides whether to allow, challenge, or forbid the request. Without this middleware, those attributes are inert metadata that the framework never evaluates.

    The order of these middleware calls matters. ASP.NET Core processes middleware in the order they are registered. UseAuthentication() must run before UseAuthorization() so that the user's identity is established before access decisions are made. Both must come after UseRouting() (which determines which endpoint will handle the request) and before endpoint mapping (which executes the endpoint).


    Instructions

    Open Program.cs. You will find three TODO comments marking where to add code.

  3. Challenge

    Step 2: Protect Controllers with Authorization Attributes

    Objective: Declare which controllers require authentication and which remain public.


    Background

    With the middleware pipeline in place from Step 1, you can now use attributes to control access at the controller or action level:

    • The [Authorize] marks a controller or action as requiring an authenticated user. When an unauthenticated request reaches an [Authorize] endpoint, the authorization middleware issues a challenge. The cookie handler converts this into a 302 redirect to the LoginPath you configured in TODO 1.

    • [AllowAnonymous] explicitly marks a controller or action as accessible without authentication. This is a defensive annotation: even if a global authorization policy is added later, [AllowAnonymous] ensures the endpoint stays public.

  4. Challenge

    Step 3: Implement Login and Logout

    Objective: Build the controller actions that create and destroy authenticated user sessions using cookie authentication.


    Background

    Cookie authentication works by serializing a ClaimsPrincipal into an encrypted cookie. On each subsequent request, the UseAuthentication() middleware reads the cookie, decrypts it, and reconstructs the ClaimsPrincipal as HttpContext.User. The sign-in and sign-out flow is managed through two methods:

    • HttpContext.SignInAsync(scheme, principal)—Serializes the given ClaimsPrincipal into a cookie and includes it in the response's Set-Cookie header. The browser stores this cookie and sends it with all subsequent requests to the same domain.

    • HttpContext.SignOutAsync(scheme)—Tells the cookie handler to issue a Set-Cookie header that expires the authentication cookie. The browser deletes the cookie, and subsequent requests are treated as unauthenticated.

    A ClaimsPrincipal is built from one or more ClaimsIdentity objects, each containing a list of Claim key-value pairs. For this exercise you need only one claim: ClaimTypes.Name, which stores the username. This value becomes accessible as User.Identity.Name in controllers and Razor views.

  5. Challenge

    Step 4: Add Authentication-Aware Navigation

    Objective: Update the shared layout to show the user's login state in the navigation bar.


    Background

    In Razor views (including layout files), the User property is available directly — it is the same ClaimsPrincipal that UseAuthentication() populates on each request. You can check User.Identity!.IsAuthenticated to determine whether the current request has a valid authentication cookie, and User.Identity.Name to read the ClaimTypes.Name claim you set during sign-in.

    The ! (null-forgiving operator) on User.Identity! is used because Identity is typed as nullable (IIdentity?), but in practice it is always populated by the authentication middleware — either as an authenticated identity or as an empty unauthenticated one.

    Running the Application

    To run PsTaskboard and test your changes in the browser, use the Terminal from the project root:

    dotnet run --project PsTaskboard
    

    (You may need to use the + button to open a new Terminal.)

    The application starts at localhost:5056. Open this URL in the Web Browser tab to see the home page. Navigate to /Project/List to test access control, and to /Account/Login to test the login flow (once you have completed the relevant TODOs).


    Conclusion

    If you have reached this section, then good job on completing the lab. You have implemented a complete cookie-based authentication and authorization flow in an ASP.NET Core 10 MVC application. The work covered four layers of the security pipeline:

    1. Service registration and middleware: the invisible plumbing that reads cookies and evaluates access rules on every request.
    2. Authorization attributes: declarative access control that protects specific controllers and explicitly keeps others public.
    3. Sign-in and sign-out actions: the code that creates and destroys authenticated sessions by issuing and expiring cookies.
    4. Authentication-aware UI: Razor conditional rendering that reflects the user's login state in the navigation.
About the author

George is a Pluralsight Author working on content for Hands-On Experiences. He is experienced in the Python, JavaScript, Java, and most recently Rust domains.

Real skill practice before real-world application

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Learn by doing

Engage hands-on with the tools and technologies you’re learning. You pick the skill, we provide the credentials and environment.

Follow your guide

All labs have detailed instructions and objectives, guiding you through the learning process and ensuring you understand every step.

Turn time into mastery

On average, you retain 75% more of your learning if you take time to practice. Hands-on labs set you up for success to make those skills stick.

Get started with Pluralsight