Single Sign-On (SSO) — ASP.NET Core Application Using IdentityServer4 as SSO Identity Provider with multiple client apps

DotNet Full Stack Dev
5 min readMar 29, 2024

--

Single Sign-On (SSO) is an authentication process that enables users to access multiple applications or services with a single set of credentials. Instead of requiring users to log in separately to each application, SSO allows them to authenticate once and access all authorized resources seamlessly.

Embark on a journey of continuous learning and exploration with DotNet-FullStack-Dev. Uncover more by visiting our https://dotnet-fullstack-dev.blogspot.com reach out for further information.

How SSO Works:

  1. Authentication: When a user attempts to access an application that supports SSO, they are redirected to a centralized identity provider (IdP) for authentication.
  2. User Authentication: The user provides their credentials (username and password) to the IdP.
  3. Token Generation: Upon successful authentication, the IdP generates a security token (e.g., JSON Web Token, SAML token) containing user information and authentication assertions.
  4. Token Verification: The application receives the token and verifies its authenticity and integrity using cryptographic signatures or other validation mechanisms.
  5. Access Authorization: Based on the token’s content and the user’s identity, the application grants access to the requested resources.
  6. Session Management: The user’s authentication session is established and maintained by the IdP, allowing them to access other SSO-enabled applications without re-entering credentials.

Benefits of SSO:

  • Convenience: Users only need to remember one set of credentials, reducing password fatigue and simplifying the login process.
  • Enhanced Security: SSO centralizes authentication, enabling organizations to enforce stronger authentication policies and access controls.
  • Improved Productivity: SSO streamlines access to multiple applications, reducing the time spent on login procedures and improving user productivity.

Demo Application: Multiple Applications with SSO

In this demo application, we’ll create two ASP.NET Core applications: an Identity Provider (IdP) using IdentityServer4 and a client application that relies on SSO for authentication.

1. Identity Provider (IdP):

  • Implement an ASP.NET Core application using IdentityServer4 to act as the SSO IdP.
  • Configure client applications and user identities within IdentityServer4.
  • Generate security tokens (JWT or SAML) upon user authentication.

2. Client Application:

  • Create a separate ASP.NET Core application that serves as a client application.
  • Configure the client application to trust the IdP for authentication.
  • Implement middleware or authentication handlers to validate tokens received from the IdP.
  • Secure application endpoints based on user roles or claims provided in the token.

Sample Code Snippet (Client Application):

public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = "cookie";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("cookie")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://identityprovider.com";
options.ClientId = "client_id";
options.ClientSecret = "client_secret";
options.ResponseType = "code";
options.SaveTokens = true;
options.Scope.Add("openid");
options.Scope.Add("profile");
});

services.AddControllersWithViews();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}

This code snippet configures an ASP.NET Core client application to authenticate users using OpenID Connect and trust the specified Identity Provider (IdP) for authentication. Upon successful authentication, the client application receives security tokens from the IdP, allowing users to access protected resources within the application.

IdentityServer4

IdentityServer4 is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core. It allows developers to set up their own identity provider (IdP) for Single Sign-On (SSO) authentication. In this guide, we’ll walk through creating an ASP.NET Core application using IdentityServer4 to act as the SSO IdP.

Step 1: Create a New ASP.NET Core Project: Start by creating a new ASP.NET Core project in Visual Studio or your preferred IDE.

Step 2: Install IdentityServer4 NuGet Package: Install the IdentityServer4 NuGet package in your project. You can do this via NuGet Package Manager or by adding the package reference manually to your project file:

dotnet add package IdentityServer4

Step 3: Configure IdentityServer4 in Startup.cs: Open the Startup.cs file and configure IdentityServer4 services and middleware. Below is a simplified example:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using IdentityServer4;
using IdentityServer4.Models;

public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddInMemoryClients(new[]
{
new Client
{
ClientId = "client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedScopes = { "api1" }
}
})
.AddInMemoryApiScopes(new[]
{
new ApiScope("api1", "My API")
})
.AddDeveloperSigningCredential();

services.AddControllersWithViews();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseStaticFiles();
app.UseRouting();

app.UseIdentityServer();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
}

This code sets up IdentityServer4 with an in-memory client and API scope configuration. In a real-world scenario, you would typically store client and scope configurations in a database.

Step 4: Create Clients and Scopes: IdentityServer4 relies on clients and scopes to define who can access which resources. Clients represent applications that can request tokens, and scopes define the permissions associated with those tokens.

Step 5: Run the Application: Compile and run the application. You can now access the IdentityServer4 endpoints to authenticate users and issue tokens.

By configuring IdentityServer4 in your ASP.NET Core application, you can create a powerful identity provider for Single Sign-On authentication. IdentityServer4 simplifies the process of implementing authentication and authorization in your applications, making it easier to secure your resources and provide a seamless user experience.

IdentityServer4 can act as a Single Sign-On (SSO) identity provider for multiple client applications. Each client application needs to be registered with IdentityServer4 and configured to trust the identity provider for authentication. Below, I’ll provide an example of configuring two client applications to authenticate with IdentityServer4 as the SSO IdP.

Step 1: Configure IdentityServer4 as SSO IdP (Same as Previous Example): Set up IdentityServer4 in your ASP.NET Core application as the SSO identity provider, following the steps outlined in the previous example.

Step 2: Create Two Client Applications:

Client Application 1 — Startup.cs:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://localhost:5001"; // IdentityServer4 URL
options.ClientId = "client1"; // Client ID registered in IdentityServer4
options.ClientSecret = "secret1"; // Client secret registered in IdentityServer4
options.ResponseType = "code";
options.Scope.Add("api1"); // Scopes requested by the client application
});

services.AddControllersWithViews();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
}

Client Application 2 — Startup.cs:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://localhost:5001"; // IdentityServer4 URL
options.ClientId = "client2"; // Client ID registered in IdentityServer4
options.ClientSecret = "secret2"; // Client secret registered in IdentityServer4
options.ResponseType = "code";
options.Scope.Add("api2"); // Scopes requested by the client application
});

services.AddControllersWithViews();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseStaticFiles();
app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
});
}
}

Explanation:

  • Each client application configures authentication using the AddOpenIdConnect method, specifying the authority (IdentityServer4 URL), client ID, client secret, and scopes.
  • The ClientId and ClientSecret values must match the client configurations registered in IdentityServer4.
  • Each client application is identified by a unique ClientId.
  • After successful authentication with IdentityServer4, the client applications can access the requested scopes (api1 for Client Application 1 and api2 for Client Application 2).

Conclusion

By configuring multiple client applications to authenticate with IdentityServer4 as the SSO identity provider, you can provide a seamless authentication experience for users across multiple applications. IdentityServer4 handles authentication and issues tokens to the client applications, allowing them to access protected resources based on the defined scopes. This approach centralizes authentication and improves security and user experience across the ecosystem of applications.

--

--

DotNet Full Stack Dev
DotNet Full Stack Dev

Written by DotNet Full Stack Dev

Join me to master .NET Full Stack Development & boost your skills by 1% daily with insights, examples, and techniques! https://dotnet-fullstack-dev.blogspot.com

Responses (1)