OpenID Connect with IdentityServer and ASP.NET Core Identity (OIDC Part 5)

Share on facebook
Share on google
Share on twitter
Share on linkedin

Great that you made it this far! Now we are getting closer to what would be a “normal” scenario. Until now we have played around with authenticating with client credentials, authorization code flow, and hybrid flow – all with hardcoded test users. Of course, this would not work in a production setup, so we will in this post enable users to register and authenticate (log in) using ASP.NET Core Identity.

ASP.NET Core Identity is a Package for ASP.NET applications that bootstraps the app with support for managing users and easily save them in a database with Entity Framework and Identity middleware.

In this post the client app will still use the hybrid flow client from last part, so we are only doing changes in the authorization server for this part. This part is implemented with inspiration from the official IdentityServer4 documentation here.

The OpenID connect with IdentityServer4 and Angular series

This series is learning you OpenID connect with Angular with these parts:

Authorization Server

The easiest way to implement the authorization server for this part is to create a new project in Visual Studio 2017 with ASP.NET Core Identity already setup. To do this we first open Visual Studio 2017 and click New->project. We should now select an ASP.NET Core Web Application like this:

Then we select “Web Application (Model-View-Controller):

We want to have it bootstrapped with Core Identity so we click “choose Authentication” and choose “Individual User Accounts”:

Now we click next and this should set up a new MVC application with ASP.NET Identity. Remember to configure this to run on port 5000 like the old AuthorizationServer.

Add Identity packages

The first we need to do is installing Identity by going on NuGet and find the package called:
IdentityServer4.AspNetIdentity

This contains the IdentityServer4 package, so we can run the IdentityServer middleware.

The IdentityServer client

We are gonna use the same IdentityServer client with hybrid flow as we did in the last part, so feel free to copy the AuthorizationServer/Config.cs file to the new project.

Setting up IdentityServer middleware

Identity middleware is setup with:

services.AddIdentity<ApplicationUser, IdentityRole>()
   .AddEntityFrameworkStores<ApplicationDbContext>()
   .AddDefaultTokenProviders();

This sets up all the routes and controllers that enables user registration, login, logout etc.

Now that Identity server middleware is setup we only need to hook Identity into the IdentityServer middleware with AddAspNetIdentity. The IdentityServer middleware chain should now look like this:

services.AddIdentityServer()
              .AddDeveloperSigningCredential()
              .AddInMemoryIdentityResources(Config.GetIdentityResources())
              .AddInMemoryApiResources(Config.GetApiResources())
              .AddInMemoryClients(Config.GetClients())
              .AddAspNetIdentity<ApplicationUser>();

The hardcoded test users have now been substituted by user data from the database.

We are also gonna copy the Quickstart folder from the last part to the new project here as this gives us our registration, login and consent pages + controllers.

Setting up the database for Identity

For setting up persistence of users we are gonna add a new DbContext with Identity’s ApplicationDbContext and make it use SQL server:

services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

The AddDbContext creates a new DB, configured with tables for user management, giving us a really good foundation for managing our users.

The whole startup file should look like this.

To actually create the Identity tables we need to update the database with:
dotnet ef database update

This adds a new migration in the migration in the data folder of the AuthorizationServer project at AuthorizationServer/Data/Identity Migrations

We can now see that the database is set up with Identity tables:

Run it

Business as usual here. We select the three project and make them all run together like before. We should now be able to go to http://localhost:5000/register and register users that can be authenticated by logging in with their credentials.

OIDC register

When we go to localhost:5002/identity we should now be redirected to the login page as before. If we click on register we can create a new user and hereafter login and give consent to that user’s resources.

And as before we should now be redirected to the Identity View showing our identity information:

Conclusion

In this part we made the app more realistic by enabling dynamic registration of users instead of using hardcoded test users, using ASP.NET core Identity. This only required a few changes in the authorization server, so this shows how powerful the ASP.NET Core Identity package is. Next part we are gonna move the hardcoded configuration data into the Database and use this for dynamic configuration of the identity server.

Do you want to become an Angular architect? Check out Angular Architect Accelerator.

Related Posts and Comments

How to Handle Errors in a Reactive Angular App

In this post, we will cover how to handle errors in a reactive Angular app. To provide a good user experience you should always let your users know what state your application is in. That includes showing a loading spinner when it’s loading and showing error messages if there are any errors. It is a

Read More »

How to Set Up Git Hooks in an Nx Repo

Git hooks can be used to automate tasks in your development workflow. The earlier a bug is discovered, the cheaper it is to fix (and the less impact it has). Therefore it can be helpful to run tasks such as linting, formatting, and tests when you are e.g. committing and pushing your code, so any

Read More »

The Stages of an Angular Architecture with Nx

Long gone are the times when the frontend was just a dumb static website. Frontend apps have gotten increasingly complex since the rise of single-page application frameworks like Angular. It comes with the price of increased complexity and the ever-changing frontend landscape requires you to have an architecture that allows you to scale and adapt

Read More »

The Best Way to Use Signals in Angular Apps

Since Angular 16, Angular now has experimental support for signals and there is a lot of confusion in the community about whether this is going to replace RxJS or how it should be used in an app in combination with RxJS. This blog post sheds some light on what I think is the best way

Read More »

High ROI Testing with Cypress Component Testing

Testing is one of the most struggled topics in Angular development and many developers are either giving up testing altogether or applying inefficient testing practices consuming all their precious time while giving few results in return. This blog post will change all this as we will cover how I overcame these struggles the hard way

Read More »