Company.SSO.Client
1.1.2
dotnet add package Company.SSO.Client --version 1.1.2
NuGet\Install-Package Company.SSO.Client -Version 1.1.2
<PackageReference Include="Company.SSO.Client" Version="1.1.2" />
<PackageVersion Include="Company.SSO.Client" Version="1.1.2" />
<PackageReference Include="Company.SSO.Client" />
paket add Company.SSO.Client --version 1.1.2
#r "nuget: Company.SSO.Client, 1.1.2"
#:package Company.SSO.Client@1.1.2
#addin nuget:?package=Company.SSO.Client&version=1.1.2
#tool nuget:?package=Company.SSO.Client&version=1.1.2
Enterprise Single Sign-On (SSO) Identity & Access Management System
This repository contains a complete, production-ready Enterprise Single Sign-On (SSO) and Identity & Access Management (IAM) System built using .NET 8. It implements an OIDC/OAuth2-inspired Authorization Code flow, complete with role mapping, dynamic permission checks, single log-out (SLO), and an administration dashboard.
Solution Architecture
The solution consists of four projects organized as follows:
Company.SSO.Server: The central Identity Provider (IdP) that maintains user accounts, active roles, application registrations, and issues JWT tokens.Company.SSO.Client: The reusable authentication middleware library (shipped as a NuGet package) that handles auth redirects, callback code exchanges, and custom permission filters.Company.App1: A test ERP Web Application running on port 5001 to verify authentication, claims inspection, and permission-based routing.Company.App2: A test CRM Web Application running on port 5002 to verify multi-app session propagation and Single Logout.
Getting Started
Prerequisites
- .NET 8 SDK
- Any modern web browser
How to Run the System
To test the complete single sign-on experience, run the central server and the client applications in separate terminal windows:
- Start the SSO Server (Port 5000):
dotnet run --project src/Company.SSO.Server - Start the ERP App 1 (Port 5001):
dotnet run --project src/Company.App1 - Start the CRM App 2 (Port 5002):
dotnet run --project src/Company.App2
Upon running the server for the first time, a SQLite database file named shared.db will automatically be generated in the solution root directory, pre-seeded with default client applications, permissions, and roles.
Seeded User Credentials
You can test the system using the following seeded accounts:
| Password | Role | Permissions | |
|---|---|---|---|
admin@sso.company |
Admin@123 |
SuperAdmin | USER.CREATE, USER.UPDATE, USER.DELETE, REPORT.VIEW, INVOICE.APPROVE |
appadmin@sso.company |
Admin@123 |
ApplicationAdmin | USER.CREATE, USER.UPDATE, REPORT.VIEW |
user@sso.company |
User@123 |
NormalUser | REPORT.VIEW |
Client Integration Guide
To implement SSO in any other ASP.NET Core MVC application, follow these integration steps:
1. Install the Package
Add the library reference (or install it via NuGet once published):
dotnet add package Company.SSO.Client
2. Configure appsettings.json
Add the SSO configurations block pointing to the central server.
Make sure the scheme (http:// vs https://) in RedirectUri matches your application's actual active protocol and port (typically .NET templates use https://localhost:7022 and http://localhost:5022). Using the wrong scheme (e.g. http on port 7022) will cause query parameter loss during automatic redirects.
"SSO": {
"SsoServerUrl": "http://localhost:5000",
"ClientId": "your_registered_client_id",
"ClientSecret": "your_registered_client_secret",
"RedirectUri": "https://localhost:7022/signin-sso"
}
3. Setup Program.cs
Register the services and add the middleware to the pipeline (placed before authentication/authorization):
using Company.SSO.Client;
// 1. Add SSO client services
builder.Services.AddSSO(options => {
builder.Configuration.GetSection("SSO").Bind(options);
});
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
// 2. Intercept OIDC callback and SLO endpoints (MUST be before UseAuthentication/UseAuthorization)
app.UseSSO();
app.UseAuthentication();
app.UseAuthorization();
4. Secure Controllers and Action Methods
Use the standard [Authorize] attribute to enforce login, and [SsoPermission("CODE")] for granular role permissions:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Company.SSO.Client;
[Authorize]
public class SalesController : Controller
{
// Accessible by any logged-in user
public IActionResult Index() => View();
// Requires the user to have the "REPORT.VIEW" permission claim
[SsoPermission("REPORT.VIEW")]
public IActionResult ViewReports() => View();
}
5. Accessing User Profile Details on Clients
When a user logs in, the Company.SSO.Client middleware automatically maps all custom claims (including profile_image and custom names) from the SSO server token into local user claims. You can retrieve these values in any client application controller or view:
// Retrieve user email
var email = User.FindFirst(System.Security.Claims.ClaimTypes.Email)?.Value;
// Retrieve user name
var name = User.Identity?.Name;
// Retrieve profile picture URL
var avatarUrl = User.FindFirst("profile_image")?.Value ?? "/images/default-avatar.png";
Troubleshooting & Common Errors
1. Error: "Authorization code is missing."
This occurs if the SsoCallbackMiddleware intercepts /signin-sso but detects that the code query parameter is empty.
- Check the Scheme & Port: Double-check your
appsettings.json'sRedirectUri. If your app is running on HTTPS port7022, the RedirectUri must start withhttps://. If it starts withhttp://, the browser or server will redirect/upgrade the protocol, which can strip the query string parameters. - Middleware Order: Ensure that
app.UseSSO()is registered afterapp.UseRouting()but beforeapp.UseAuthentication()andapp.UseAuthorization()inProgram.cs.
2. Error: Failed to exchange authorization code: {"error":"invalid_client"}
This occurs if the back-channel token exchange API on the SSO Server rejects your client credentials.
- Register the Client: You must register your client application in the SSO database.
- Open the SSO Server Dashboard (
http://localhost:5000). - Log in as SuperAdmin (
admin@sso.company/Admin@123). - Use the Register New Application form at the bottom to register your client app's
ClientId,ClientSecret, andRedirectUrimatching your clientappsettings.jsonconfiguration.
- Open the SSO Server Dashboard (
- Casing Cautions: Client ID and Client Secret string comparisons are case-sensitive. Ensure they match exactly in the SSO Server dashboard and in your client application's
appsettings.json.
Key Features Built-In
- Single Sign-On (SSO): Logging in on one app establishes a global session on the SSO server. Accessing another app challenges the server and signs you in instantly without requiring credentials again.
- Single Log-Out (SLO): Logging out of any application initiates a front-channel logout flow that signs you out of all active apps via background iframes.
- User Profile Management: Centralized settings page where logged-in users can update their profile information (Name, Mobile), upload profile photos (supported with direct circular image updates and live uploader previews), and update security credentials (change password).
- Session Claim Updates: When users change their profile details (such as Name), the cookie identity principal is re-authenticated dynamically in real-time, instantly propagating names across navigation headers.
- User isolated Logout: SLO only terminates the session belonging to the logging-out identity, preventing users in different browser windows/contexts from clashing.
- User & Rights Editor: Centralized Admin dashboard where Super Admins can add applications, edit users, assign multiple roles, and view security/audit logs in real-time.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- System.IdentityModel.Tokens.Jwt (>= 8.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.