SSO Provider Basics

Learn how to set up a basic SSO provider application with the OIDC functionality implemented.

To explain how SSO works, we will build an IdP application with the most bare-bone functionality. Our application is represented by the following playground. We will go through the code step-by-step to see how the OIDC functionality is enabled.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}
OpenID Connect client credentials flow demonstration

Adding NuGet dependencies

If we open the OpenIddictAuthProvider.csproj file, we will find an ItemGroup block with the following NuGet references on line 8:

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.9" />
<PackageReference Include="OpenIddict.AspNetCore" Version="4.6.0" />
<PackageReference Include="OpenIddict.EntityFrameworkCore" Version="4.6.0" />
<PackageReference Include="OpenIddict.Server" Version="4.6.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
OIDC NuGet dependencies

Here's what each of these NuGet packages performs:

  • Microsoft.EntityFrameworkCore.InMemory: This provides an object-relational mapper (ORM) that allows us to have an in-memory database. The database is needed for storing authentication and authorization data, such as client applications, users, roles, etc. In a real production system, we would use a real database, such as the SQL Server. But for testing purposes, an in-memory database is sufficient.

  • OpenIddict.AspNetCore: This NuGet package provides bare-bone OIDC functionality.

  • OpenIddict.EntityFrameworkCore: This NuGet package provides components that are necessary for integrating with the ORM we added earlier.

  • OpenIddict.Server: This package allows us to build an OIDC server that will act as an IdP application.

  • Swashbuckle.AspNetCore: This package allows us to visualize and invoke API endpoints via an in-browser UI.

Once we have added all the necessary libraries, we will then configure all the necessary dependencies and endpoints during the application startup.

Configuring application middleware

All the startup code can be found in the Program.cs file. Let's have a look specifically at the SSO configuration setup. The first thing we perform is add the most foundational OIDC dependencies by making the following invocation on line 6:

builder.Services.AddOpenIddict()

Then, we chain-invoke the following block on lines 7–11, which adds the necessary database dependencies:

.AddCore(coreBuilder =>
{
coreBuilder.UseEntityFrameworkCore()
.UseDbContext<DbContext>();
})
Adding the OIDC database dependencies

Next, on lines 12–23, we chain the following invocation to the flow, which provides a more fine-tuned configuration of the server:

.AddServer(serverBuilder =>
{
serverBuilder.AllowClientCredentialsFlow();
serverBuilder.SetTokenEndpointUris("api/authorization/token");
serverBuilder.AddDevelopmentEncryptionCertificate()
.AddDevelopmentSigningCertificate();
serverBuilder.DisableAccessTokenEncryption();
serverBuilder.UseAspNetCore()
.EnableTokenEndpointPassthrough()
.DisableTransportSecurityRequirement();
serverBuilder.AllowRefreshTokenFlow();
});
Adding OIDC server configuration

We will have a more detailed look at this configuration in the next lesson. On lines 25–29, we add additional database dependencies and tell the system to use an in-memory database as follows:

builder.Services.AddDbContext<DbContext>(options =>
{
options.UseInMemoryDatabase(nameof(DbContext));
options.UseOpenIddict();
});
Configuring a specific dtabase type for the OIDC components

Now, we have an application that can store information on users, their roles, and any other data that allows us to grant and revoke appropriate permissions. We can apply additional functionality to the application to make it compatible with the standard authentication and authorization protocols, such as OpenID Connect and OAuth.