### Quick Start Astro Development Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/README.md Navigate to the astro directory, install dependencies, and start the development server for hot-reloading. ```bash cd astro npm install npm run dev ``` -------------------------------- ### End-to-End Role and Group Setup Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/fundamentals/roles-and-groups.md This C# example demonstrates creating a role, a group, assigning the role to the group, adding a user to the group, and then querying the user's effective roles. It utilizes IRoleAdmin, IGroupAdmin, and IMembershipAdmin services. Ensure these services are registered via AddUserManagement() in your configuration. ```csharp using Duende.UserManagement.Membership; public class RoleSetupService( IRoleAdmin roleAdmin, IGroupAdmin groupAdmin, IMembershipAdmin membershipAdmin) { public async Task SetupEditorRoleAsync(UserSubjectId subjectId, CancellationToken ct) { // 1. Create a role. var roleResult = await roleAdmin.CreateAsync( new Role { Name = RoleName.Create("content-editor") }, ct); var roleId = roleResult.Value; // 2. Create a group. var groupResult = await groupAdmin.CreateAsync( new Group { Name = GroupName.Create("editors") }, ct); var groupId = groupResult.Value; // 3. Assign the role to the group (transitive path). await membershipAdmin.AssignRoleToGroupAsync(roleId, groupId, ct); // 4. Add the user to the group. Membership is auto-created when assigning roles/groups. await membershipAdmin.AssignGroupAsync(subjectId, groupId, ct); // 5. Query effective roles (direct + transitive, merged in application code). var directRoles = await membershipAdmin.GetDirectRolesAsync(subjectId, range: null, ct); var transitiveRoles = await membershipAdmin.GetTransitiveRolesAsync(subjectId, range: null, ct); var effectiveRoles = directRoles.Items .Concat(transitiveRoles.Items) .DistinctBy(r => r.Id) .ToList(); // effectiveRoles now contains "content-editor" via the group. } } ``` -------------------------------- ### Install Duende IdentityServer Templates Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/0-overview.md Installs the Duende IdentityServer templates for ASP.NET Core applications. This is the first step for using the quickstarts. ```bash dotnet new install Duende.Templates ``` -------------------------------- ### Add Quickstart UI to Project Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/2-interactive.md Use the .NET CLI to add the duende-is-ui template to your IdentityServer project. This provides a starting point for the login, logout, consent, and error UIs. ```console dotnet new duende-is-ui ``` -------------------------------- ### Full SamlServiceProvider Configuration Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/saml/service-providers.md Use this example to configure a SamlServiceProvider with signing, single logout, and claim mappings. Ensure AssertionConsumerServiceUrls use SamlBinding.HttpPost. ```csharp new SamlServiceProvider { EntityId = "https://sp.example.com", DisplayName = "Example SP", Enabled = true, // Assertion Consumer Service AssertionConsumerServiceUrls = [ new() { Location = "https://sp.example.com/acs", Binding = SamlBinding.HttpPost, Index = 0, IsDefault = true } ], // Single Logout Service SingleLogoutServiceUrls = [ new() { Location = "https://sp.example.com/saml/slo", Binding = SamlBinding.HttpRedirect, } ], // Signing SigningBehavior = SamlSigningBehavior.SignAssertion, RequireSignedAuthnRequests = true, // bool?: null falls back to global SamlOptions.WantAuthnRequestsSigned Certificates = [ new() { Certificate = myCertificate, Use = KeyUse.Signing } ], // NameID DefaultNameIdFormat = SamlConstants.NameIdentifierFormats.Unspecified, // Claims ClaimMappings = new Dictionary { ["department"] = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/department", }, } ``` -------------------------------- ### Example Output of Package List Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/upgrades/identityserver4-to-duende-identityserver-v8.mdx This is an example of the output you might see when checking for IdentityServer4 packages, indicating the package name and version. ```bash > IdentityServer4 3.1.4 3.1.4 > IdentityServer4.EntityFramework 3.1.4 3.1.4 ``` -------------------------------- ### Install Duende.BFF.EntityFramework Package Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/bff/fundamentals/session/server-side-sessions.mdx Install the necessary NuGet package to enable Entity Framework integration for server-side session storage. ```bash dotnet add package Duende.BFF.EntityFramework ``` -------------------------------- ### Install Entity Framework Core Integration Package Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/data/ef.md Install the Duende.IdentityServer.EntityFramework NuGet package to enable EF Core integration. ```bash dotnet add package Duende.IdentityServer.EntityFramework ``` -------------------------------- ### Install Duende Templates Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/index.mdx Install the Duende templates to quickly set up a new project. This involves installing the main template package and then creating a new project using the duende-is command. ```bash dotnet new install Duende.Templates dotnet new duende-is -o DuendeIdentityServer dotnet run --project DuendeIdentityServer ``` -------------------------------- ### Add IdentityServer and User Management NuGet Packages Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/getting-started.mdx Installs the core IdentityServer package, the User Management integration package, and a storage provider package (SQLite in this example). ```bash dotnet add package Duende.IdentityServer dotnet add package Duende.UserManagement.IdentityServer8 dotnet add package Duende.Storage.Sqlite ``` -------------------------------- ### Install and Copy oidc-client Library Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/javascript-clients/js-without-backend.md Use NPM to install the oidc-client library and then copy its distribution files into the wwwroot directory for serving. ```console npm i oidc-client copy node_modules/oidc-client/dist/* wwwroot ``` -------------------------------- ### Install OpenID Connect NuGet Package Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/fundamentals/openid-connect-events.md Install the necessary NuGet package for the OpenID Connect handler. This is a prerequisite for integrating OIDC authentication. ```bash dotnet package add Microsoft.AspNetCore.Authentication.OpenIdConnect ``` -------------------------------- ### AttestationTrustPolicyResult Examples Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/authentication/passkeys.mdx Shows how to return Accept() to allow registration or Reject(reason) to block it. ```csharp // Accept the authenticator return AttestationTrustPolicyResult.Accept(); ``` ```csharp // Reject with a reason return AttestationTrustPolicyResult.Reject("Authenticator not in allowlist."); ``` -------------------------------- ### Install NuGet Packages for BFF and OIDC Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/javascript-clients/js-with-backend.mdx Installs the required NuGet packages for Duende BFF and OIDC support into the JavaScriptClient project. ```bash dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect dotnet add package Duende.BFF dotnet add package Duende.BFF.Yarp ``` -------------------------------- ### Install SQL Server Storage Package Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/fundamentals/storage.md Add the Duende.Storage.SqlServer NuGet package to your project to enable SQL Server storage. ```bash dotnet add package Duende.Storage.SqlServer ``` -------------------------------- ### Install PostgreSQL Storage Package Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/fundamentals/storage.md Installs the necessary NuGet package for PostgreSQL storage integration. ```bash dotnet add package Duende.Storage.PostgreSQL ``` -------------------------------- ### YAML Frontmatter Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/README.md Example of frontmatter configuration in a documentation file, specifying title, sidebar label, and order. ```yaml title: "Using IdentityServer As A Federation Gateway" sidebar: label: "Federation" order: 1 ``` -------------------------------- ### Install EF Core CLI Tool Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/4-entity-framework.md Install the global Entity Framework Core CLI tool. This is required for running EF migration commands. ```bash dotnet tool install --global dotnet-ef ``` -------------------------------- ### Install User Token Management Package Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/accesstokenmanagement/index.mdx Install the NuGet package for automatic access token lifetime management using a refresh token for API calls on behalf of the logged-in user. ```bash dotnet add package Duende.AccessTokenManagement.OpenIdConnect ``` -------------------------------- ### Add ASP.NET Identity NuGet Package Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/aspnet-identity/index.md Install the Duende.IdentityServer.AspNetIdentity NuGet package using the .NET CLI. ```bash dotnet add package Duende.IdentityServer.AspNetIdentity ``` -------------------------------- ### End Session URL Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/reference/v7/endpoints/end-session.md This is an example of the GET request URL for the end session endpoint, including optional parameters for initiating single sign-out. ```text GET /connect/endsession?id_token_hint=...&post_logout_redirect_uri=http%3A%2F%2Flocalhost%3A7017%2Findex.html ``` -------------------------------- ### Create Solution and Add Projects Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/7-blazor.mdx Create a solution file and add the Blazor and BFF projects to it, useful for IDE integration. ```bash dotnet new sln -n BlazorQuickstart dotnet sln add BlazorWasm/BlazorWasm.csproj dotnet sln add BFF/BFF.csproj ``` -------------------------------- ### Uninstall and Install Duende IdentityServer Templates Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/0-overview.md Uninstalls a previous version of Duende templates and installs the latest version. This ensures you have the most up-to-date templates for the quickstarts. ```bash dotnet new uninstall Duende.Templates dotnet new install Duende.Templates ``` -------------------------------- ### Create Backend-for-Frontend (BFF) Project Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/7-blazor.mdx Use the .NET CLI to create a new web project to host the BFF. ```bash dotnet new web -n BFF ``` -------------------------------- ### Authorize Endpoint Request Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/reference/v7/endpoints/authorize.md Example of a GET request to the authorize endpoint with common parameters like client ID, scopes, response type, redirect URI, state, and nonce. ```text GET /connect/authorize? client_id=client1& scope=openid email api1& response_type=id_token token& redirect_uri=https://myapp/callback& state=abc& nonce=xyz ``` -------------------------------- ### Get Discovery Document with Duende IdentityModel Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/reference/v7/endpoints/discovery.md Example of using the Duende IdentityModel client library to programmatically retrieve the discovery document from a .NET client. ```csharp var client = new HttpClient(); var disco = await client.GetDiscoveryDocumentAsync("https://demo.duendesoftware.com"); ``` -------------------------------- ### Build Everything (Astro + .NET) Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/README.md Execute a full build of both the Astro site and the .NET components. ```bash dotnet build.cs ``` -------------------------------- ### Create New ASP.NET Core Project Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/bff/getting-started/multi-frontend.mdx Initializes a new ASP.NET Core web project and navigates into its directory. ```bash dotnet new web -n MyMultiBffApp cd MyMultiBffApp ``` -------------------------------- ### Display Post-Recovery Message Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/authentication/recovery-codes.mdx After a user authenticates with a recovery code, display a message guiding them to restore their normal 2FA setup. This snippet shows how to set a temporary message. ```csharp if (usedRecoveryCode) { TempData["PostRecoveryMessage"] = "You signed in with a recovery code. " + "Set up your authenticator app and generate new recovery codes " + "to keep your account secure."; } ``` -------------------------------- ### Creating a User Profile via Admin Interface Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/fundamentals/profiles.md Demonstrates how to provision a new user profile using the `IUserProfileAdmin` interface. Ensure necessary using directives are included. ```csharp using Duende.Storage.EntityAttributeValue; using Duende.UserManagement; using Duende.UserManagement.Profiles; public class AdminProvisioningService(IUserProfileAdmin profileAdmin) { public async Task ProvisionAsync( string subjectId, string email, int employeeId, CancellationToken ct) { var schema = await profileAdmin.GetSchemaAsync(ct); var attributes = new AttributeValueCollection(schema); attributes.Set(AttributeCode.Create("email"), email); attributes.Set(AttributeCode.Create("employee_id"), employeeId); return await profileAdmin.TryAddAsync( UserSubjectId.Create(subjectId), attributes.Validate(), ct); } } ``` -------------------------------- ### Prometheus Alert for No New Sessions Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/bff/fundamentals/deployment.mdx Example Prometheus alert to detect when no new sessions are being started, which could indicate a Data Protection key mismatch or pod restart issues. ```prometheus # Prometheus-style alert examples # Metric names are converted from dot notation to underscores by Prometheus. # No new sessions — potential Data Protection key mismatch alert: BffNoNewSessions expr: rate(session_started_total[5m]) == 0 for: 5m ``` -------------------------------- ### Run Documentation Container Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/README.md Run the built container image and map port 8080 to access the documentation site locally. ```bash docker run -p 8080:8080 docs ``` -------------------------------- ### Get and Use Access Token with Automatic Refresh Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/3a-token-management.md Utilize GetUserAccessTokenAsync to retrieve tokens and SetBearerToken for convenient HTTP header setup. This ensures the access token is automatically refreshed if needed. ```csharp // CallApi.cshtml.cs public async Task OnGet() { var tokenInfo = await HttpContext.GetUserAccessTokenAsync(); var client = new HttpClient(); client.SetBearerToken(tokenInfo.AccessToken!); var content = await client.GetStringAsync("https://localhost:6001/identity"); var parsed = JsonDocument.Parse(content); var formatted = JsonSerializer.Serialize(parsed, new JsonSerializerOptions { WriteIndented = true }); Json = formatted; } ``` -------------------------------- ### Create Solution and IdentityServer Project Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/1-client-credentials.md Creates a new solution directory, a source subdirectory, and an empty IdentityServer project using the 'duende-is-empty' template. ```console mkdir quickstart cd quickstart mkdir src dotnet new sln -n Quickstart ``` ```console cd src dotnet new duende-is-empty -n IdentityServer ``` ```console cd .. dotnet sln add ./src/IdentityServer ``` -------------------------------- ### Prometheus Alert for Abnormal Session Churn Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/bff/fundamentals/deployment.mdx Example Prometheus alert to monitor for abnormal session churn, where sessions are ending faster than they are starting. This could point to issues with the Identity Provider or session store. ```prometheus # Abnormal session churn alert: BffSessionChurn expr: rate(session_ended_total[5m]) / rate(session_started_total[5m]) > 2 for: 5m ``` -------------------------------- ### Base64 URL Encode and Decode with ASP.NET Core Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identitymodel/utils/base64.md Utilize WebEncoders.Base64UrlEncode and WebEncoders.Base64UrlDecode for Base64 URL operations. Ensure the Microsoft.AspNetCore.WebUtilities package is installed. This example demonstrates encoding a string to Base64 URL, then decoding it back to verify. ```bash dotnet add package Microsoft.AspNetCore.WebUtilities ``` ```csharp using System.Text; using Microsoft.AspNetCore.WebUtilities; var bytes = "hello"u8.ToArray(); var b64url = WebEncoders.Base64UrlEncode(bytes); bytes = WebEncoders.Base64UrlDecode(b64url); var text = Encoding.UTF8.GetString(bytes); Console.WriteLine(text); ``` -------------------------------- ### Basic PostgreSQL Storage Setup Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/fundamentals/storage.md Configures User Management to use PostgreSQL storage by registering the NpgsqlDataSource and the PostgreSQL store. It also initializes the database schema on startup. ```csharp using Duende.Storage.Schema; using Duende.Storage.PostgreSql; using Npgsql; var builder = WebApplication.CreateBuilder(args); // Register the NpgsqlDataSource and PostgreSQL store builder.Services .AddSingleton(new NpgsqlDataSourceBuilder( builder.Configuration.GetConnectionString("pgsql")!).Build()) .AddPostgreSqlStore(); var app = builder.Build(); // Initialize the database schema on startup. using (var scope = app.Services.CreateScope()) { await scope.ServiceProvider .GetRequiredService() .CreateIfNotExistsAsync(CancellationToken.None); } ``` -------------------------------- ### Build Astro to wwwroot Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/README.md Build the Astro site and output the static files to the wwwroot directory. ```bash dotnet build.cs astro-build ``` -------------------------------- ### Create Client Project Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/1-client-credentials.md Commands to create a new console project for the client and add it to the solution. ```bash cd src dotnet new console -n Client ``` ```bash cd .. dotnet sln add ./src/Client ``` -------------------------------- ### Install Entity Framework Integration Package Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/4-entity-framework.md Replace the default IdentityServer package with the Entity Framework integration package to enable database persistence. Run these commands from the `src/IdentityServer` directory. ```bash dotnet remove package Duende.IdentityServer dotnet add package Duende.IdentityServer.EntityFramework ``` -------------------------------- ### Start the Application Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/getting-started.mdx Run the ASP.NET Core application using the 'https' launch profile to enable secure connections required for IdentityServer's session cookies. ```bash dotnet run --launch-profile https ``` -------------------------------- ### Introspection Endpoint Request Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/reference/v7/endpoints/introspection.md Example of an HTTP POST request to the introspection endpoint, including Authorization header and token parameter. ```text POST /connect/introspect Authorization: Basic xxxyyy token= ``` -------------------------------- ### Add Client Configuration Store Storage Package Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/configuration/dcr.mdx Install the NuGet package for the Entity Framework Core-based client configuration store using the .NET CLI. ```bash dotnet add package Duende.IdentityServer.Configuration.Storage ``` -------------------------------- ### Down-scoped Access Token Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/fundamentals/resources/isolation/index.md An example of a down-scoped access token, containing only the audience and scope for the requested resource ('urn:invoice'). ```json { "aud": ["urn:invoice"], "scope": "read", "client_id": "client" } ``` -------------------------------- ### Register New User Profile Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/fundamentals/profiles.md Handles the onboarding of a new user after authentication by creating their profile with initial attributes. It retrieves the schema, sets attribute values, and then attempts to create the user profile. ```csharp using Duende.Storage.EntityAttributeValue; using Duende.UserManagement; using Duende.UserManagement.Profiles; // 2. Register a new user profile (self-service, called after authentication). public class OnboardingHandler(IUserProfileSelfService profileService) { public async Task OnboardAsync( string subjectId, string givenName, string familyName, string email, CancellationToken ct) { var schema = await profileService.GetSchemaAsync(ct); var attributes = new AttributeValueCollection(schema); attributes.Set(AttributeCode.Create("given_name"), givenName); attributes.Set(AttributeCode.Create("family_name"), familyName); attributes.Set(AttributeCode.Create("email"), email); attributes.Set(AttributeCode.Create("email_verified"), false); return await profileService.TryCreateAsync( UserSubjectId.Create(subjectId), attributes.Validate(), ct); } } ``` -------------------------------- ### Custom NameID Generation Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/saml/extensibility.md An example implementation of ISamlNameIdGenerator that uses a custom 'employee_id' claim as the NameID value. Handles cases where the claim is not found. ```csharp // MyNameIdGenerator.cs public class MyNameIdGenerator : ISamlNameIdGenerator { public Task GenerateAsync( NameIdGenerationContext context, CancellationToken ct) { // Example: use a custom "employee_id" claim as the NameID value var employeeId = context.Subject.FindFirst("employee_id")?.Value; if (employeeId is null) return Task.FromResult(NameIdGenerationResult.Failure( StatusCodes.Responder, StatusCodes.UnknownPrincipal, "Employee ID claim not found.")); var nameId = new NameId(employeeId, context.ResolvedFormat); return Task.FromResult(NameIdGenerationResult.Success(nameId)); } } ``` -------------------------------- ### Add Frontend During Startup Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/bff/fundamentals/multi-frontend/index.mdx Use `AddFrontends` with `BffFrontend` to configure frontends when your application starts. This method can be called multiple times or with multiple frontends at once. ```csharp services .AddBff() .AddFrontends(new BffFrontend(BffFrontendName.Parse("frontend1"))); ``` -------------------------------- ### Configure Client Options using Configure (V3) Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/accesstokenmanagement/advanced/client-credentials.mdx Configure client credentials options using the standard .NET options system for V3. The `TokenEndpoint` can be a string. ```csharp services.Configure("invoices", client => { client.TokenEndpoint = "https://sts.company.com/connect/token"; client.ClientId = "4a632e2e-0466-4e5a-a094-0455c6105f57"; client.ClientSecret = "e8ae294a-d5f3-4907-88fa-c83b3546b70c"; client.Scope = "list"; client.Resource = "urn:invoices"; }); ``` -------------------------------- ### End-to-End User Import Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/import/reference.md Demonstrates importing two users: one with a password and group membership, and another with an external authenticator. It shows how to build profile attributes, define password hashes, and specify group memberships. ```csharp public class UserImportService(IUserImporter importer, IUserProfileAdmin profileAdmin) { public async Task RunAsync(CancellationToken ct) { // Build profile attributes using the schema so values are type-validated. var schema = await profileAdmin.GetSchemaAsync(ct); var aliceAttributes = new AttributeValueCollection(schema); aliceAttributes.Set(AttributeCode.Create("email"), "alice@example.com"); aliceAttributes.Set(AttributeCode.Create("display_name"), "Alice"); // Represent a pre-hashed bcrypt password from the source system. // Hash and Salt are raw bytes; supply the actual bytes from your source data. var bcryptHash = new HashedPasswordData( algorithmId: "bcrypt", hash: new byte[] { /* raw hash bytes from source */ }, salt: new byte[] { /* raw salt bytes from source */ }, parameters: new Dictionary { ["cost"] = "12" }); var records = new List { new UserImportRecord { SubjectId = new UserSubjectId("user-001"), ProfileAttributes = aliceAttributes.Validate(), Authenticators = new AuthenticatorImport { Password = new PasswordImport(bcryptHash), }, Memberships = new MembershipImport { Groups = new[] { GroupId.Create("admins") }, }, }, new UserImportRecord { SubjectId = new UserSubjectId("user-002"), Authenticators = new AuthenticatorImport { ExternalAuthenticatorAddresses = new[] { new ExternalAuthenticatorAddress( Provider: "google", ProviderSubjectId: "google-sub-abc123" ), }, }, }, }; UserImportBatchResult result = await importer.ImportAsync(records, ct); Console.WriteLine($"Created: {result.CreatedCount}"); Console.WriteLine($"Updated: {result.UpdatedCount}"); Console.WriteLine($"Skipped: {result.SkippedCount}"); Console.WriteLine($"Failed: {result.FailedCount}"); foreach (UserImportResult r in result.Results) { if (r.Status == UserImportStatus.Failed) Console.WriteLine($" FAILED {r.SubjectId}: {r.Error}"); } } } ``` -------------------------------- ### CIBA Endpoint Request Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/reference/v8/endpoints/ciba.md This is an example of a POST request to the CIBA endpoint. It includes client credentials and required parameters like scope and login hint. ```http POST /connect/ciba client_id=client1& client_secret=secret& scope=openid api1& login_hint=alice ``` -------------------------------- ### Install Machine-To-Machine Token Management Package Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/accesstokenmanagement/index.mdx Install the NuGet package for automatic client credentials based access token management in worker and ASP.NET Core applications. ```bash dotnet add package Duende.AccessTokenManagement ``` -------------------------------- ### Identity Token Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/tokens/index.md An example of an identity token's JSON payload, containing user authentication details and protocol information. This token is intended for the client application. ```json { "iss": "https://localhost:5001", "nbf": 1609932802, "iat": 1609932802, "exp": 1609933102, "aud": "web_app", "amr": [ "pwd" ], "nonce": "63745529591...I3ZTIyOTZmZTNj", "sid": "F6E6F2EDE86EB8731EF609A4FE40ED89", "auth_time": 1609932794, "idp": "local", "sub": "88421113", "name": "Bob", } ``` -------------------------------- ### Create New Web Application Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/configuration/dcr.mdx Creates a new ASP.NET Core Web application project named 'Configuration'. ```bash dotnet new web -n Configuration ``` -------------------------------- ### TOTP QR Code URI Format Example Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/authentication/totp.mdx This is an example of the `otpauth://` URI scheme used for sharing TOTP secrets, which can be converted into a QR code for authenticator apps. ```text otpauth://totp/MyApp:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp&digits=6 ``` -------------------------------- ### Add Duende BFF with Options Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/bff/fundamentals/options.md Configure Duende BFF options at startup by passing a configuration delegate to AddBff. ```csharp builder.Services.AddBff(options => { // configure options here... }) ``` -------------------------------- ### Install OpenID Connect NuGet Package Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/quickstarts/2-interactive.md Add the `Microsoft.AspNetCore.Authentication.OpenIdConnect` NuGet package to your web client project to enable OpenID Connect authentication. ```console dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect ``` -------------------------------- ### Access Token Example (JWT) Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/tokens/index.md An example of an access token in JWT format, which embeds claims such as client ID, scopes, and expiration time. This token is used by clients to access resources. ```json { "iss": "https://localhost:5001", "nbf": 1609932801, "iat": 1609932801, "exp": 1609936401, "aud": "urn:resource1", "scope": "openid resource1.scope1 offline_access", "amr": [ "pwd" ], "client_id": "web_app", "sub": "88421113", "auth_time": 1609932794, "idp": "local", "sid": "F6E6F2EDE86EB8731EF609A4FE40ED89", "jti": "2C56A356A306E64AFC7D2C6399E23A17" } ``` -------------------------------- ### Configure IdentityServer with Console OTP Dispatcher Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/usermanagement/getting-started.mdx This snippet shows the basic setup for IdentityServer with user management enabled, using a console-based OTP dispatcher for testing. It includes essential IdentityServer configurations and database migration setup. ```csharp using Duende.IdentityServer; using Duende.Storage.Schema; using Duende.Storage.Sqlite; using Duende.UserManagement.Authentication.Otp; using Microsoft.AspNetCore.DataProtection; var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services .AddIdentityServer(options => { options.UserInteraction.LoginUrl = "/Account/Login"; options.UserInteraction.LogoutUrl = "/Account/Logout"; options.Events.RaiseErrorEvents = true; options.Events.RaiseInformationEvents = true; options.Events.RaiseFailureEvents = true; options.Events.RaiseSuccessEvents = true; }) .AddInMemoryIdentityResources(Config.IdentityResources) .AddInMemoryApiScopes(Config.ApiScopes) .AddInMemoryClients(Config.Clients) .AddUserManagement(options => { options.AddSqliteStore(o => { o.ConnectionString = "Data Source=usermanagement.db"; }); }); builder.Services.AddSingleton(); builder.Services.AddDataProtection() .SetApplicationName("OtpIdentityServerGettingStarted"); var app = builder.Build(); using (var scope = app.Services.CreateScope()) { await scope.ServiceProvider .GetRequiredService() .MigrateAsync(CancellationToken.None); } // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseIdentityServer(); app.UseAuthorization(); app.MapStaticAssets(); app.MapRazorPages() .WithStaticAssets(); app.Run(); ``` -------------------------------- ### Configure Client Configuration Store and Database Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/identityserver/configuration/dcr.mdx Register the client configuration store and configure the database connection string in Program.cs. ```csharp // Program.cs builder.Services.AddIdentityServer(options => { // ... }) .AddConfigurationApi() .AddClientConfigurationStore(); builder.Services.AddConfigurationStore(options => { options.ConfigureDbContext = dbBuilder => dbBuilder.UseSqlServer(Configuration.GetConnectionString("ConfigurationDb")); }); builder.Services.AddLicense(Configuration.GetSection("License")); ``` -------------------------------- ### Get User Session Information Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/astro/src/content/docs/bff/fundamentals/session/management/user.md Retrieves data about the currently logged-on user and their session status. This endpoint is typically called at application startup to check authentication and get user profile data, or periodically to verify session validity. ```APIDOC ## GET /bff/user ### Description Returns data about the currently logged-on user and the session. If there is no current session, it indicates the user is anonymous (default 401 status code). ### Method GET ### Endpoint /bff/user ### Response #### Success Response (200) Returns a JSON array containing claims in the ASP.NET Core authentication session and BFF-specific claims. #### Response Example ```json [ { "type": "sid", "value": "173E788068FFB728806501F4F46C52D6" }, { "type": "sub", "value": "88421113" }, { "type": "idp", "value": "local" }, { "type": "name", "value": "Bob Smith" }, { "type": "bff:logout_url", "value": "/logout?sid=173E788068FFB728806501F4F46C52D6" }, { "type": "bff:session_expires_in", "value": 28799 }, { "type": "bff:session_state", "value": "q-Hl1V9a7FCZE5o-vH9qpmyVKOaeVfMQBUJLrq-lDJU.013E58C33C7409C6011011B8291EF78A" } ] ``` ``` -------------------------------- ### Build .NET Solution Source: https://github.com/duendesoftware/docs.duendesoftware.com/blob/main/README.md Compile the .NET solution as part of the build process. ```bash dotnet build.cs dotnet-build ```