- Lab
-
Libraries: If you want this lab, consider one of these libraries.
- Core Tech
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 Info
Table of Contents
-
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 howSignInAsync/SignOutAsyncmanage 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
TODOcomments which align with the instructions, indicating where you'll add or modify code.There is a
solutionsdirectory 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 theTODOs, and the tests are designed to allow for that flexibility. The solutions are provided as a reference, not a template. -
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 populatesHttpContext.User. This happens in two parts: first, a cookie authentication handler is registered in the dependency injection container (AddAuthentication+AddCookie); then, theUseAuthentication()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 beforeUseAuthorization()so that the user's identity is established before access decisions are made. Both must come afterUseRouting()(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. -
-
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 theLoginPathyou 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.
-
-
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
ClaimsPrincipalinto an encrypted cookie. On each subsequent request, theUseAuthentication()middleware reads the cookie, decrypts it, and reconstructs theClaimsPrincipalasHttpContext.User. The sign-in and sign-out flow is managed through two methods:-
HttpContext.SignInAsync(scheme, principal)—Serializes the givenClaimsPrincipalinto a cookie and includes it in the response'sSet-Cookieheader. 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 aSet-Cookieheader that expires the authentication cookie. The browser deletes the cookie, and subsequent requests are treated as unauthenticated.
A
ClaimsPrincipalis built from one or moreClaimsIdentityobjects, each containing a list ofClaimkey-value pairs. For this exercise you need only one claim:ClaimTypes.Name, which stores the username. This value becomes accessible asUser.Identity.Namein controllers and Razor views. -
-
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
Userproperty is available directly — it is the sameClaimsPrincipalthatUseAuthentication()populates on each request. You can checkUser.Identity!.IsAuthenticatedto determine whether the current request has a valid authentication cookie, andUser.Identity.Nameto read theClaimTypes.Nameclaim you set during sign-in.The
!(null-forgiving operator) onUser.Identity!is used becauseIdentityis 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
PsTaskboardand 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/Listto test access control, and to/Account/Loginto 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:
- Service registration and middleware: the invisible plumbing that reads cookies and evaluates access rules on every request.
- Authorization attributes: declarative access control that protects specific controllers and explicitly keeps others public.
- Sign-in and sign-out actions: the code that creates and destroys authenticated sessions by issuing and expiring cookies.
- Authentication-aware UI: Razor conditional rendering that reflects the user's login state in the navigation.
About the author
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.