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:
- Part 1: Creating an OpenID connect system with Angular 8 and IdentityServer4
- Part 2: Creating identity server setup with client credential authentication
- Part 3: Creating interactive authentication with an authorization code client
- Part 4: OpenID Connect Hybrid Flow for calling resource API
- Part 5: OpenID Connect with ASP.NET Identity (this)
- Part 6: OpenID Connect with Entity Framework for IdentityServer configuration
- Part 7: OpenID Connect with Angular client
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/:
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.
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.
6 thoughts on “OpenID Connect with IdentityServer and ASP.NET Core Identity (OIDC Part 5)”
Pingback: Creating an OpenID connect system with Angular 5 and IdentityServer4 (OIDC part 1) – Christian Lüdemann IT
Hi,
Where does the Pages folder come from that contains the Account/register.cshtml
Thanks,
add scaffold of identity by right clicking on project & click on add then identity add
Pingback: OpenID Connect Interactive authentication with Authorization Code Flow (OIDC Part 3) – Christian Lüdemann
Pingback: OpenID Connect with Angular 8 (OIDC Part 7) – Christian Lüdemann
I have been trying to follow along with this using ASP .NET Core 3, but run into an issue on the redirect after login trying to get the API resources. It just returns “This localhost page can’t be found” with the web address starting as “http://localhost:55390/consent?returnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3Dmvc%26redirect_uri%3Dhttp%253A%252F%252Flocalhost%253A53969%252Fsignin-oidc%26response_type%3Dcode…” and so on.
I have run the downloaded sample and it works without issue, and I have even tried to compare the two, but that is difficult to do when the .NET Core versions are different (meaning a lot of other code changes required).
Do you have any insight into what might be causing this?