### Complete Descope OIDC Integration Setup Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/05-oidc-integration.md This comprehensive example demonstrates the full setup for Descope OIDC authentication within a .NET application's startup configuration. It includes adding authentication services, configuring Descope options, and setting up authorization policies. ```csharp var builder = WebApplication.CreateBuilder(args); // Add authentication builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie() .AddDescopeOidc(options => { options.ProjectId = builder.Configuration["Descope:ProjectId"]!; options.ClientSecret = builder.Configuration["Descope:ClientSecret"]; options.FlowId = "sign-up-or-in"; options.RequireHttpsMetadata = !builder.Environment.IsDevelopment(); options.PostLogoutRedirectUri = builder.Configuration["Descope:PostLogoutRedirectUri"]; }); // Add authorization builder.Services.AddAuthorization(options => { options.AddPolicy("Admin", policy => policy.RequireRole("admin")); }); var app = builder.Build(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.MapRazorPages(); app.Run(); ``` -------------------------------- ### Start WebAuthn Setup for Two-Factor Authentication Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Initiates the setup process for WebAuthn (Security Keys/Passkeys) authentication. Requires a friendly name for the device and the user's refresh JWT. ```csharp var response = await client.Auth.V1.Webauthn.Update.Start.PostWithJwtAsync( new WebauthnAddDeviceStartRequest { FriendlyName = "My Key" }, refreshJwt ); ``` -------------------------------- ### Integration Test Configuration Example (JSON) Source: https://github.com/descope/descope-dotnet/blob/main/README-maintainer.md Example structure for `appsettingsTest.json` used for local integration testing. Requires ProjectId, ManagementKey, and optionally BaseURL and Unsafe settings. ```json { "AppSettings": { "ProjectId": "P**************a", "ManagementKey": "K********************************", "BaseURL": "http://localhost:8000", "Unsafe": "true" } } ``` -------------------------------- ### WebAuthn Start Request Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/08-configuration-and-types.md Defines the request to start a WebAuthn device addition. Optionally includes a friendly name for the device. ```csharp public class WebauthnAddDeviceStartRequest { public string? FriendlyName { get; set; } } ``` -------------------------------- ### Install Descope .NET SDK Source: https://github.com/descope/descope-dotnet/blob/main/README.md Use the dotnet CLI to add the Descope package to your project. ```bash dotnet add package Descope ``` -------------------------------- ### Set Up Two-Factor Authentication (WebAuthn) Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Initiates the setup process for WebAuthn authentication (e.g., security keys, passkeys). ```APIDOC ## Set Up Two-Factor Authentication (WebAuthn) ### Description Starts the process for adding a WebAuthn authenticator (like a security key or passkey) to the user's account. ### Method `client.Auth.V1.Webauthn.Update.Start.PostWithJwtAsync(request, refreshJwt)` ### Parameters #### Request Body - **request** (WebauthnAddDeviceStartRequest) - Required - Object containing details for starting WebAuthn setup. - **FriendlyName** (string) - Optional - A user-friendly name for the authenticator. - **refreshJwt** (string) - Required - The refresh JWT for authentication. ``` -------------------------------- ### StartWebAuthnUpdate.PostWithJwtAsync Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/03-authentication-extensions.md Starts the WebAuthn device registration process (security keys, passkeys). Requires a refresh JWT. ```APIDOC ## StartWebAuthnUpdate.PostWithJwtAsync ### Description Starts the WebAuthn device registration process (security keys, passkeys). Requires a refresh JWT. ### Method POST (implied by PostWithJwtAsync) ### Endpoint (Not explicitly defined, inferred from context) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **request** (WebauthnAddDeviceStartRequest) - Required - Request with device friendly name. - **refreshJwt** (string) - Required - Refresh JWT token. Cannot be empty. ### Request Example ```csharp var response = await client.Auth.V1.Webauthn.Update.Start.PostWithJwtAsync( new WebauthnAddDeviceStartRequest { FriendlyName = "My Security Key" }, refreshJwt); // Provide transaction ID and options to client for device registration var transactionId = response?.TransactionId; ``` ### Response #### Success Response (200) - **WebauthnStartResponse** - Containing transaction ID and WebAuthn options. ``` -------------------------------- ### WebAuthn Start Registration Response Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Provides the transaction ID and WebAuthn options required to start the WebAuthn registration process. ```csharp public class WebauthnStartResponse { public string? TransactionId { get; set; } public string? Options { get; set; } // WebAuthn options JSON } ``` -------------------------------- ### Check and Install Kiota Source: https://github.com/descope/descope-dotnet/blob/main/README-maintainer.md Verifies if the Kiota CLI tool is installed and installs it if it's missing. ```bash make check-kiota ``` -------------------------------- ### Start WebAuthn Update with JWT Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/03-authentication-extensions.md Starts the WebAuthn device registration process using a refresh JWT. Requires a refresh JWT and provides transaction ID and WebAuthn options for client-side device registration. ```csharp var response = await client.Auth.V1.Webauthn.Update.Start.PostWithJwtAsync( new WebauthnAddDeviceStartRequest { FriendlyName = "My Security Key" }, refreshJwt); // Provide transaction ID and options to client for device registration var transactionId = response?.TransactionId; ``` -------------------------------- ### Running the Descope Demo Application with .NET Source: https://github.com/descope/descope-dotnet/blob/main/Descope.Example.WebApp/README.md These commands demonstrate how to run the Descope OIDC demo web application using different .NET framework versions. The application will start on http://localhost:5000 or the next available port. ```bash # .NET 6.0 dotnet run --framework net6.0 ``` ```bash # .NET 8.0 dotnet run --framework net8.0 ``` ```bash # .NET 9.0 dotnet run --framework net9.0 ``` ```bash # .NET 10.0 dotnet run --framework net10.0 ``` -------------------------------- ### Set Up Two-Factor Authentication (TOTP) Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Initiates the setup process for Time-based One-Time Password (TOTP) authentication using an authenticator app. ```APIDOC ## Set Up Two-Factor Authentication (TOTP) ### Description Starts the process for setting up TOTP authentication, providing a provisioning URL or QR code for the user's authenticator app. ### Method `client.Auth.V1.Totp.Update.PostWithJwtAsync(request, refreshJwt)` ### Parameters #### Request Body - **request** (TOTPUpdateRequest) - Required - An empty object for this operation. - **refreshJwt** (string) - Required - The refresh JWT for authentication. ``` -------------------------------- ### ErrorDetails C# Constructor Example Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/08-configuration-and-types.md Demonstrates creating an ErrorDetails object in C# from provided error information. ```csharp var error = new ErrorDetails( "invalid_token", "Token validation failed", "kid not found in cache" ); // error.ExceptionMessage: "[invalid_token]: Token validation failed (kid not found in cache)" ``` -------------------------------- ### Validate() Method Example Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/05-oidc-integration.md Shows how to validate that the `ProjectId` is set. The `Validate` method throws a `DescopeException` if the `ProjectId` is empty, ensuring essential configuration is present. ```csharp options.Validate(); // Throws if ProjectId is empty ``` -------------------------------- ### Basic Descope OIDC Setup Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/05-oidc-integration.md Use this snippet to add Descope OIDC authentication with default settings. Ensure you have configured your Project ID and Client Secret in the application's configuration. ```csharp var builder = WebApplication.CreateBuilder(args); builder.Services .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie() .AddDescopeOidc(options => { options.ProjectId = builder.Configuration["Descope:ProjectId"]!; options.ClientSecret = builder.Configuration["Descope:ClientSecret"]; }); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); ``` -------------------------------- ### Run Tests with Coverage Source: https://github.com/descope/descope-dotnet/blob/main/README-maintainer.md Executes tests and generates a coverage report. Requires the ReportGenerator tool to be installed. ```bash make cover ``` -------------------------------- ### WebAuthn Start Response Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/08-configuration-and-types.md Represents the response when initiating a WebAuthn operation. Contains a transaction ID and WebAuthn API options. ```csharp public class WebauthnStartResponse { public string? TransactionId { get; set; } public string? Options { get; set; } // WebAuthn API options (JSON) } ``` -------------------------------- ### Example of Extension Method for Auth Operations Source: https://github.com/descope/descope-dotnet/blob/main/CLAUDE.md Illustrates an extension method pattern for Descope authentication operations, wrapping Kiota-generated methods with cleaner APIs and explicit parameter handling. ```csharp // PostWithJwtAsync / GetWithJwtAsync — Auth operations requiring a refresh JWT // PostWithKeyAsync — Operations requiring an access key // GetWithIdAsync / GetWithTenantIdAsync / GetWithIdentifierAsync — Management lookups // PostWithSettingsResponseAsync / PostWithJsonOutputAsync — Typed response helpers ``` -------------------------------- ### Set Up TOTP for Two-Factor Authentication Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Starts the process for setting up Time-based One-Time Password (TOTP) authentication using an authenticator app. The response contains a provisioning URL or QR code to share with the user. ```csharp var response = await client.Auth.V1.Totp.Update.PostWithJwtAsync( new TOTPUpdateRequest(), refreshJwt ); // Share response.Provisioning URL or QR code with user ``` -------------------------------- ### Getting Matched Permissions Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/02-token-operations.md Return a list of permissions from a given set that are actually present in the token. This helps determine available actions. ```csharp var available = token.GetMatchedPermissions( new List { "read", "write", "delete" } ); // Returns: ["read", "write"] if only those are in the token ``` -------------------------------- ### WebAuthn - Start Registration Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Initiates the WebAuthn registration process for a user. This operation requires a refresh JWT and returns transaction details and options for the client-side. ```APIDOC ## POST /v1/auth/webauthn/update/start ### Description Initiates the WebAuthn registration process. Requires a refresh JWT. ### Method POST ### Endpoint /v1/auth/webauthn/update/start ### Response #### Success Response (200) - **TransactionId** (string) - Optional - The ID of the WebAuthn transaction. - **Options** (string) - Optional - WebAuthn options JSON for client-side processing. ``` -------------------------------- ### Get Project-Wide Password Settings Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/04-management-extensions.md Loads password settings for the entire project, without tenant-specific filtering. Returns the project's password policy settings. ```csharp var settings = await client.Mgmt.V1.Password.Settings.GetForProjectAsync(); var isEnabled = settings?.Enabled ?? false; ``` -------------------------------- ### Access Key Authentication Header Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Example of the Authorization header format for Access Key authentication, used for server-to-server authentication. ```text Authorization: {accessKey} ``` -------------------------------- ### Get Password Settings by Tenant ID Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/04-management-extensions.md Loads password settings for a specific tenant using its ID. Ensure the tenant ID is not empty. ```csharp var settings = await client.Mgmt.V1.Password.Settings.GetWithTenantIdAsync("tenant_xyz"); Console.WriteLine($"Min length: {settings?.MinLength}"); Console.WriteLine($"Requires uppercase: {settings?.Uppercase}"); ``` -------------------------------- ### GetAuthority() Method Example Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/05-oidc-integration.md Demonstrates how to get the OIDC Authority URL by combining the BaseUrl and ProjectId. The `GetAuthority` method returns the issuer URL in the format `{BaseUrl}/{ProjectId}`. ```csharp var options = new DescopeOidcOptions { ProjectId = "proj_xyz" }; var authority = options.GetAuthority(); // Returns: "https://api.descope.com/proj_xyz" ``` -------------------------------- ### ErrorDetails JSON Example Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/08-configuration-and-types.md Example of a structured error response from the Descope API. ```json { "errorCode": "invalid_token", "errorDescription": "Token validation failed", "errorMessage": "kid not found in cache" } ``` -------------------------------- ### Set Up OpenID Connect (Basic) Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Configures basic OpenID Connect authentication using Descope. ```APIDOC ## Set Up OpenID Connect (Basic) ### Description Configures the application to use Descope as an OpenID Connect provider, integrating with ASP.NET Core's authentication system. ### Method `builder.Services.AddAuthentication(...).AddCookie().AddDescopeOidc(options => {...})` ### Parameters #### Request Body - **options** (DescopeOidcOptions) - Required - Configuration options for Descope OIDC. - **ProjectId** (string) - Required - Your Descope project ID. ``` -------------------------------- ### Run Quick SDK Tests (Bash) Source: https://github.com/descope/descope-dotnet/blob/main/README-maintainer.md Executes tests for the net8.0 framework only, recommended for faster feedback during development. ```bash # Quick run (net8.0 only) - recommended during development make test-quick ``` -------------------------------- ### Run Quick Tests (net8.0) Source: https://github.com/descope/descope-dotnet/blob/main/README-maintainer.md Execute unit tests specifically for the net8.0 framework. This is a faster option for development cycles. ```bash make test-quick ``` -------------------------------- ### Display Makefile Help Source: https://github.com/descope/descope-dotnet/blob/main/README-maintainer.md Shows a list of all available targets in the Makefile along with their descriptions. ```bash make help ``` -------------------------------- ### Get Password Policy Settings Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Retrieves the current password policy settings for the project. ```APIDOC ## Get Password Policy Settings ### Description Fetches the project's password complexity and other related policy settings. ### Method `client.Mgmt.V1.Password.Settings.GetForProjectAsync()` ``` -------------------------------- ### Get Password Settings Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Retrieves the password settings for a specific tenant or the entire project. ```APIDOC ## GET /v1/mgmt/password/settings ### Description Retrieves the current password settings. ### Method GET ### Endpoint /v1/mgmt/password/settings ### Parameters #### Query Parameters - **tenantId** (string) - Optional - The ID of the tenant to retrieve settings for. If not provided, project-level settings are returned. ``` -------------------------------- ### Get Password Policy Settings Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Retrieves the project's password policy settings. ```csharp var settings = await client.Mgmt.V1.Password.Settings.GetForProjectAsync(); ``` -------------------------------- ### Initialize Descope Client with Factory Pattern Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Use the factory pattern for standalone client initialization. Configure the Project ID. ```csharp var client = DescopeManagementClientFactory.Create(new DescopeClientOptions { ProjectId = "your_project_id" }); ``` -------------------------------- ### Client Initialization Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Information on how to initialize the Descope client, including configuration options, dependency injection for ASP.NET, factory patterns for standalone applications, testing with mocked adapters, and the main client interface. ```APIDOC ## Client Initialization This section covers the various ways to initialize and configure the Descope client in your .NET application. ### Key Components: - **DescopeClientOptions**: A configuration class containing all available options for client construction. - **Dependency Injection**: Use `AddDescopeClient()` for seamless integration within ASP.NET Core applications. - **Factory Pattern**: For standalone applications, utilize `DescopeManagementClientFactory.Create()` to instantiate the client. - **Testing**: Employ `CreateForTest()` when you need to use mocked adapters for unit testing. - **IDescopeClient**: The primary interface representing the Descope client. ``` -------------------------------- ### Get Auth History Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Retrieves the authentication history for the current user using their refresh JWT. ```APIDOC ## GET /v1/auth/me/history ### Description Fetches the authentication event history for the current user, requiring a refresh JWT for access. ### Method GET ### Endpoint /v1/auth/me/history ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **AuthHistory** (array) - A list of authentication history events. - **MethodKind** (string) - The type of authentication method used (e.g., "otp_sms", "magic_link"). - **Timestamp** (DateTime) - The date and time when the authentication event occurred. #### Response Example { "AuthHistory": [ { "MethodKind": "otp_sms", "Timestamp": "2023-10-27T10:00:00Z" }, { "MethodKind": "magic_link", "Timestamp": "2023-10-26T15:30:00Z" } ] } ``` -------------------------------- ### Initiate SSO Auth with Query Params Async Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/03-authentication-extensions.md Initiates an SSO authentication flow with specified query parameters. This method is used to redirect users to an Identity Provider (IdP) for authentication. Tenant ID is required and cannot be empty. ```csharp var response = await client.Auth.V1.Sso.Authorize.PostWithQueryParamsAsync( new LoginOptions(), tenant: "acme_corp", redirectUrl: "https://myapp.com/auth/callback", forceAuthn: true, test: false); // Redirect user to SSO URL var redirectUrl = response?.RedirectUrl; ``` -------------------------------- ### Get Current User Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Retrieves information about the currently authenticated user using their refresh JWT. ```APIDOC ## GET /v1/auth/me ### Description Retrieves the details of the currently logged-in user based on the provided refresh JWT. ### Method GET ### Endpoint /v1/auth/me ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **Id** (string) - The unique identifier of the user. - **Name** (string) - The name of the user. - **Email** (string) - The email address of the user. - **VerifiedEmail** (boolean) - Indicates if the user's email has been verified. - **Phone** (string) - The phone number of the user. - **VerifiedPhone** (boolean) - Indicates if the user's phone number has been verified. #### Response Example { "Id": "user-id-123", "Name": "John Doe", "Email": "john.doe@example.com", "VerifiedEmail": true, "Phone": "+1234567890", "VerifiedPhone": false } ``` -------------------------------- ### Get User With Identifier Async Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/06-errors-and-exceptions.md Retrieves a user by identifier, catching DescopeException if the identifier is empty. ```csharp try { await client.Mgmt.V1.User.GetWithIdentifierAsync(""); } catch (DescopeException ex) { Console.WriteLine(ex.Message); // "Identifier is required for loading a user" } ``` -------------------------------- ### Initialize the Client (Factory Pattern) Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Standalone initialization of the Descope client using a factory pattern. ```APIDOC ## Initialize the Client (Factory Pattern) ### Description Create a standalone Descope management client instance using the factory pattern. ### Method `DescopeManagementClientFactory.Create(new DescopeClientOptions {...})` ### Parameters #### Request Body - **ProjectId** (string) - Required - Your Descope project ID. ``` -------------------------------- ### Initialize the Client (Dependency Injection) Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Recommended way to initialize the Descope client using dependency injection in ASP.NET Core applications. ```APIDOC ## Initialize the Client (Dependency Injection) ### Description Use this method to register the Descope client with the service collection for dependency injection. ### Method `builder.Services.AddDescopeClient(new DescopeClientOptions {...})` ### Parameters #### Request Body - **ProjectId** (string) - Required - Your Descope project ID. - **ManagementKey** (string) - Optional - Your Descope management key. ``` -------------------------------- ### Set Up OpenID Connect (Custom Flow) Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Configures OpenID Connect with a custom flow and development settings. ```APIDOC ## Set Up OpenID Connect (Custom Flow) ### Description Configures Descope OIDC with a specific flow ID and adjusts metadata requirements for development environments. ### Method `builder.Services.AddDescopeOidc(options => {...})` ### Parameters #### Request Body - **options** (DescopeOidcOptions) - Required - Configuration options for Descope OIDC. - **ProjectId** (string) - Required - Your Descope project ID. - **FlowId** (string) - Optional - The ID of the custom Descope flow to use. - **RequireHttpsMetadata** (bool) - Optional - Set to false for development environments if not using HTTPS. ``` -------------------------------- ### Create Descope Client for Testing Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/01-client-initialization.md Initialize an `IDescopeClient` with mocked request adapters for testing purposes. This allows you to simulate responses from authentication and management endpoints. An optional `HttpClient` can be provided for HTTP-level mocking. ```csharp var authAdapterMock = new MockRequestAdapter(); var mgmtAdapterMock = new MockRequestAdapter(); var options = new DescopeClientOptions { ProjectId = "test_proj" }; var httpClientMock = new HttpClient(); var client = DescopeManagementClientFactory.CreateForTest( authAdapterMock, mgmtAdapterMock, options, httpClientMock ); // Now use client with mocked responses ``` -------------------------------- ### Create Descope Client Instance using Factory Source: https://github.com/descope/descope-dotnet/blob/main/README.md Use DescopeManagementClientFactory.Create to manually instantiate a Descope client instance. ```csharp var client = DescopeManagementClientFactory.Create(new DescopeClientOptions { ProjectId = "your-project-id", ManagementKey = "your-management-key" }); ``` -------------------------------- ### Initialize Descope Client with Dependency Injection Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Use dependency injection for client initialization in ASP.NET Core applications. Configure Project ID and Management Key. ```csharp builder.Services.AddDescopeClient(new DescopeClientOptions { ProjectId = "your_project_id", ManagementKey = "your_management_key" }); ``` -------------------------------- ### Getting Matched Roles Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/02-token-operations.md Identify which roles from a provided list are present in the token. This is useful for determining user privileges. ```csharp var roles = token.GetMatchedRoles(new List { "admin", "user" }); // Returns: ["user"] if only user role is present ``` -------------------------------- ### Configure Descope Client Options Source: https://github.com/descope/descope-dotnet/blob/main/README.md Instantiate DescopeClientOptions with your project ID and optional keys for management and authentication APIs. Base URL and FGA cache URL can also be configured. ```csharp var options = new DescopeClientOptions { ProjectId = "your-project-id", // Required ManagementKey = "your-management-key", // Optional, for management APIs AuthManagementKey = "your-auth-key", // Optional, for accessing disabled auth APIs BaseUrl = "https://api.descope.com", // Optional, auto-detected from project ID FgaCacheUrl = "https://fga.example.com", // Optional, if using the Descope FGA Cache Docker Container IsUnsafe = false // Optional, for dev/test only }; ``` -------------------------------- ### Retrieving Tenant IDs Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/02-token-operations.md Get a list of all tenant IDs associated with the current token. This is useful for multi-tenant applications. ```csharp var tenants = token.GetTenants(); // Returns: ["tenant_1", "tenant_2", ...] ``` -------------------------------- ### Initialize Descope Client Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/INDEX.md Configure the Descope client for dependency injection or factory creation. Ensure ProjectId and ManagementKey are provided for full functionality. ```csharp builder.Services.AddDescopeClient(new DescopeClientOptions { ProjectId = "proj_xyz", ManagementKey = "key_..." }); ``` ```csharp var client = DescopeManagementClientFactory.Create(new DescopeClientOptions { ProjectId = "proj_xyz" }); ``` -------------------------------- ### Typical Descope .NET Flow Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/00-START-HERE.md Demonstrates client initialization, session validation, authorization checks, and updating user email using the Descope .NET SDK. Use this for a general overview of common operations. ```csharp // 1. Initialize builder.Services.AddDescopeClient(new DescopeClientOptions { ProjectId = "your_project_id", ManagementKey = "your_management_key" }); // 2. In a controller or service public class AuthService { private readonly IDescopeClient _client; public AuthService(IDescopeClient client) => _client = client; // 3. Validate session (fast, local) public async Task IsSessionValid(string sessionJwt) { try { var token = await _client.Auth.ValidateSessionAsync(sessionJwt); return token.Expiration > DateTime.UtcNow; } catch (DescopeException) { return false; } } // 4. Check authorization public async Task CanWrite(string sessionJwt, string tenantId) { try { var token = await _client.Auth.ValidateSessionAsync(sessionJwt); return token.ValidatePermissions( new List { "documents:write" }, tenant: tenantId ); } catch (DescopeException) { return false; } } // 5. Update user (authenticated) public async Task UpdateEmail(string newEmail, string refreshJwt) { try { var response = await _client.Auth.V1.Magiclink.Update.Email .PostWithJwtAsync( new UpdateUserEmailMagicLinkRequest { Email = newEmail }, refreshJwt ); // Magic link sent } catch (DescopeException ex) { Console.WriteLine($"Error: {ex.ErrorCode} - {ex.ErrorDescription}"); throw; } } } ``` -------------------------------- ### Run All SDK Tests (Bash) Source: https://github.com/descope/descope-dotnet/blob/main/README-maintainer.md Executes all unit and integration tests across all supported .NET frameworks (net6.0, net8.0, net9.0, net10.0). ```bash # All frameworks (net6.0, net8.0, net9.0, net10.0) make test ``` -------------------------------- ### Getting Tenant-Specific Claim Values Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/02-token-operations.md Retrieve a specific claim value for a given tenant. This allows access to tenant-scoped data. ```csharp var tenantPerm = token.GetTenantValue("tenant_1", "permissions"); ``` -------------------------------- ### Build and Test Commands for Descope .NET SDK Source: https://github.com/descope/descope-dotnet/blob/main/CLAUDE.md Provides common make commands for regenerating Kiota files, building the project, running unit tests, and cleaning artifacts. Use `dotnet build` or `dotnet test` for specific build/test operations. ```bash make ``` ```bash make dotnet-build ``` ```bash make test-quick ``` ```bash make test ``` ```bash make cover ``` ```bash make clean ``` -------------------------------- ### Bearer Token Authentication Header Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Example of the Authorization header format for Bearer token authentication, typically used for authenticated user operations. ```text Authorization: Bearer {refreshJwt} ``` -------------------------------- ### Configure Descope OIDC with Dependency Injection Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Sets up authentication using Descope's OpenID Connect provider with dependency injection. Requires the Project ID. ```csharp builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie() .AddDescopeOidc(options => { options.ProjectId = "your_project_id"; }); ``` -------------------------------- ### Run All Tests Source: https://github.com/descope/descope-dotnet/blob/main/README-maintainer.md Execute unit tests across all supported .NET frameworks (net6.0, net8.0, net9.0, net10.0). ```bash make test ``` -------------------------------- ### Search Descope .NET SDK on NuGet Source: https://github.com/descope/descope-dotnet/blob/main/README-maintainer.md Use this command to list available Descope .NET SDK versions on NuGet. This helps verify that a newly released version is published and accessible. ```bash dotnet package search Descope ``` -------------------------------- ### Example Descope API Error Response Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/06-errors-and-exceptions.md Illustrates the structure of a typical JSON error response from the Descope API, including errorCode, errorDescription, and errorMessage. ```json HTTP/1.1 400 Bad Request Content-Type: application/json { "errorCode": "invalid_argument", "errorDescription": "Email already exists", "errorMessage": "user@example.com is already registered" } ``` -------------------------------- ### Get Auth History with JWT Async Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/03-authentication-extensions.md Retrieves the authentication history for the current user using a refresh JWT. Ensure the refresh JWT is not empty. ```csharp var history = await client.Auth.V1.Me.History.GetWithJwtAsync(refreshJwt); foreach (var event in history?.AuthHistory ?? new List()) { Console.WriteLine($"Event: {event.MethodKind} at {event.Timestamp}"); } ``` -------------------------------- ### Get Auth History Response Structure Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Defines the structure for the response when retrieving authentication history. Contains a list of authentication events with their methods and timestamps. ```csharp public class MeAuthHistoryResponse { public List? AuthHistory { get; set; } } public class AuthHistoryEvent { public string? MethodKind { get; set; } // e.g., "otp_sms", "magic_link" public DateTime? Timestamp { get; set; } } ``` -------------------------------- ### Run SDK Tests with Coverage Report (Bash) Source: https://github.com/descope/descope-dotnet/blob/main/README-maintainer.md Executes all SDK tests and generates a code coverage report. ```bash # With coverage report make cover ``` -------------------------------- ### Get Current User Response Structure Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Defines the structure for the response when retrieving current user information. Includes basic user details and verification status. ```csharp public class ResponseUser { public string? Id { get; set; } public string? Name { get; set; } public string? Email { get; set; } public bool? VerifiedEmail { get; set; } public string? Phone { get; set; } public bool? VerifiedPhone { get; set; } // ... additional fields } ``` -------------------------------- ### Run All Tests Source: https://github.com/descope/descope-dotnet/blob/main/Descope.Test/README.md Execute all unit tests within the Descope.Test.csproj project using the dotnet CLI. ```bash dotnet test Descope.Test/Descope.Test.csproj ``` -------------------------------- ### Load SSO Settings (V1) Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Retrieves the SSO settings for a given tenant. ```APIDOC ## GET /v1/mgmt/sso/settings ### Description Retrieves the Single Sign-On (SSO) settings for a specified tenant. ### Method GET ### Endpoint /v1/mgmt/sso/settings ### Parameters #### Query Parameters - **tenantId** (string) - Required - The ID of the tenant whose SSO settings are to be retrieved. ``` -------------------------------- ### Load Tenant by ID using C# Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/04-management-extensions.md Loads a tenant by its ID. Ensure the tenant ID is not empty to avoid exceptions. ```csharp var tenant = await client.Mgmt.V1.Tenant.GetWithIdAsync("tenant_acme"); Console.WriteLine($"Name: {tenant?.Name}"); Console.WriteLine($"Domain: {tenant?.Domain}"); ``` -------------------------------- ### UserInfo.GetWithJwtAsync Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/03-authentication-extensions.md Gets the current user's details using a refresh JWT. This method allows retrieval of user profile information by providing a valid refresh token. ```APIDOC ## UserInfo.GetWithJwtAsync ### Description Gets the current user's details using a refresh JWT. This method allows retrieval of user profile information by providing a valid refresh token. ### Method GET ### Endpoint /v1/auth/me ### Parameters #### Query Parameters - **refreshJwt** (string) - Required - Refresh JWT token. Cannot be empty. ### Request Example ```json { "refreshJwt": "your_refresh_jwt" } ``` ### Response #### Success Response (200) - **name** (string) - User's name. - **email** (string) - User's email address. - **verifiedEmail** (boolean) - Indicates if the email is verified. #### Response Example ```json { "name": "John Doe", "email": "john.doe@example.com", "verifiedEmail": true } ``` ``` -------------------------------- ### Authentication Extensions Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Overview of authentication-related extensions, including magic link and OTP updates, password changes, TOTP and WebAuthn setup, session management, tenant selection, and SSO integration. ```APIDOC ## Authentication Extensions This section outlines various extensions and methods for handling different authentication flows and user management tasks. ### Features: - **Magic Link Updates**: Facilitates email and phone number updates using magic links. - **Enchanted Link Updates**: Supports authentication and updates via enchanted links. - **OTP Updates**: Enables email and phone number updates using One-Time Passwords (OTP) delivered via SMS, Voice, or WhatsApp. - **Password Updates**: Provides functionality for users to change their passwords. - **TOTP Updates**: Assists in setting up Two-Factor Authentication using authenticator apps. - **WebAuthn Updates**: Manages the registration of security keys, including passkeys. - **Session Management**: Includes operations for refreshing sessions, logging out users, retrieving user information, and accessing authentication history. - **Tenant Selection**: Allows users to switch between tenants within their active session. - **SSO Integration**: Supports SAML and OIDC authorization flows, including the use of query parameters. - **Access Key Exchange**: Enables server-to-server authentication by exchanging access keys for session JWTs. ``` -------------------------------- ### Load SSO Settings by Tenant ID (V2) Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/04-management-extensions.md Retrieves SSO settings for a specific tenant using the V2 API. The tenant ID must not be empty. ```csharp var ssoSettings = await client.Mgmt.V2.Sso.Settings.GetWithTenantIdAsync("tenant_acme"); // Check SAML/OIDC configuration ``` -------------------------------- ### Regenerate Kiota Files and Build SDK Source: https://github.com/descope/descope-dotnet/blob/main/README-maintainer.md Run this command to regenerate Kiota client files and build the C# project. It's the most common workflow for maintainers. ```bash make ``` -------------------------------- ### Get Password Settings Response Model Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/08-configuration-and-types.md Defines the structure for retrieving password policy settings from Descope. Includes various boolean flags and integer settings for password complexity and lockout. ```csharp public class GetPasswordSettingsResponse { public bool? Enabled { get; set; } public int? MinLength { get; set; } public bool? Lowercase { get; set; } public bool? Uppercase { get; set; } public bool? Number { get; set; } public bool? NonAlphanumeric { get; set; } public bool? EnablePasswordStrength { get; set; } public int? PasswordStrengthScore { get; set; } public bool? Expiration { get; set; } public int? ExpirationWeeks { get; set; } public bool? Reuse { get; set; } public int? ReuseAmount { get; set; } public bool? Lock { get; set; } public int? LockAttempts { get; set; } public bool? TempLock { get; set; } public int? TempLockAttempts { get; set; } public int? TempLockDuration { get; set; } public string? TenantId { get; set; } } ``` -------------------------------- ### Get User Details with Refresh JWT Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/03-authentication-extensions.md Retrieve current user details using a refresh JWT. The refresh JWT cannot be empty. The response contains user information such as email, phone, and name. ```csharp var user = await client.Auth.V1.Me.GetWithJwtAsync(refreshJwt); Console.WriteLine($"User: {user?.Name}"); Console.WriteLine($"Email: {user?.Email}"); Console.WriteLine($"Verified: {user?.VerifiedEmail}"); ``` -------------------------------- ### SSO Authorize Extensions - PostWithQueryParamsAsync Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/03-authentication-extensions.md Initiates the SSO authentication flow with comprehensive query parameters. ```APIDOC ## SSO Authorize Extensions - PostWithQueryParamsAsync ### Description Initiates SSO authentication flow with comprehensive query parameters (tenant, redirect URL, OIDC prompt, etc.). ### Method ```csharp public static async Task PostWithQueryParamsAsync( this Descope.Auth.V1.Auth.Sso.Authorize.AuthorizeRequestBuilder requestBuilder, LoginOptions request, string tenant, string? redirectUrl = null, string[]? prompt = null, string? loginHint = null, bool? forceAuthn = null, bool? test = null, CancellationToken cancellationToken = default) ``` ### Parameters #### Path Parameters - **requestBuilder** (AuthorizeRequestBuilder) - Required - SSO authorize request builder. - **request** (LoginOptions) - Required - Login options (typically empty). - **tenant** (string) - Required - Tenant ID for SSO. Cannot be empty. - **redirectUrl** (string?) - Optional - URL to redirect to after SSO authentication. - **prompt** (string[]?) - Optional - OIDC prompt values (e.g., ["login"], ["consent"]). - **loginHint** (string?) - Optional - Hint to pre-fill username in IdP form. - **forceAuthn** (bool?) - Optional - Force re-authentication even if user has active session. - **test** (bool?) - Optional - Enable test mode. - **cancellationToken** (CancellationToken) - Optional - Cancellation token. ### Response #### Success Response - **SAMLRedirectResponse?** - Containing the SSO redirect URL. ### Exceptions - `DescopeException`: Thrown if tenant is empty. ### Request Example ```csharp var response = await client.Auth.V1.Sso.Authorize.PostWithQueryParamsAsync( new LoginOptions(), tenant: "acme_corp", redirectUrl: "https://myapp.com/auth/callback", forceAuthn: true, test: false); // Redirect user to SSO URL var redirectUrl = response?.RedirectUrl; ``` ``` -------------------------------- ### Regional URL Detection Examples Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/08-configuration-and-types.md Illustrates how the Descope API base URL is determined based on the Project ID length. Shorter IDs use the default URL, while longer IDs extract a region for a regional endpoint. ```csharp // Project ID: "proj_xyz" (8 chars) // Detected URL: https://api.descope.com // Project ID: "proj_usea_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" (41 chars) // Extracted region: "usea" // Detected URL: https://api.usea.descope.com ``` -------------------------------- ### Create Mock DescopeClient with Simple Response Source: https://github.com/descope/descope-dotnet/blob/main/Descope.Test/README.md Use this method to create a mock DescopeClient when only the response object needs to be provided. It simplifies testing by allowing direct specification of the expected response. ```csharp var mockResponse = new JWTResponse { SessionJwt = "token", ... }; var descopeClient = TestDescopeClientFactory.CreateWithResponse(mockResponse); ``` -------------------------------- ### GetPasswordSettings.GetForProjectAsync Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/04-management-extensions.md Loads password settings for the entire project, without tenant-specific filtering. ```APIDOC ## GetPasswordSettings.GetForProjectAsync ### Description Loads password settings for the entire project (no tenant filtering). ### Method `public static async Task GetForProjectAsync( this Descope.Mgmt.V1.Mgmt.Password.Settings.SettingsRequestBuilder requestBuilder, CancellationToken cancellationToken = default) ` ### Returns GetPasswordSettingsResponse for the project. ### Example ```csharp var settings = await client.Mgmt.V1.Password.Settings.GetForProjectAsync(); var isEnabled = settings?.Enabled ?? false; ``` ``` -------------------------------- ### AddDescopeOidc(AuthenticationBuilder, Action) Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/05-oidc-integration.md Adds Descope OpenID Connect authentication using inline configuration. This method configures the authentication builder with Descope OIDC, allowing for basic setup via a lambda expression for options. ```APIDOC ## AddDescopeOidc(AuthenticationBuilder, Action) ### Description Adds Descope OpenID Connect authentication using inline configuration. ### Method Signature ```csharp public static AuthenticationBuilder AddDescopeOidc( this AuthenticationBuilder builder, Action configureOptions) ``` ### Parameters #### Path Parameters - `builder` (AuthenticationBuilder) - Required - Authentication builder from `services.AddAuthentication()`. - `configureOptions` (Action) - Required - Lambda to configure options. ### Behavior - Configures OpenID Connect authentication with Authorization Code flow and PKCE by default. - Automatically detects regional base URLs for project IDs with 32+ characters. - Maps Descope claims to standard claim types (name, roles). - For HTTP development (RequireHttpsMetadata=false), configures SameSite=Lax on correlation and nonce cookies. - Preserves any user-provided event handlers without overwriting. ### Example — Basic OIDC Setup ```csharp var builder = WebApplication.CreateBuilder(args); builder.Services .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie() .AddDescopeOidc(options => { options.ProjectId = builder.Configuration["Descope:ProjectId"]!; options.ClientSecret = builder.Configuration["Descope:ClientSecret"]; }); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); ``` ### Example — Custom Flow with Development Settings ```csharp builder.Services.AddAuthentication() .AddCookie() .AddDescopeOidc(options => { options.ProjectId = "proj_xyz"; options.FlowId = "sign-up-or-in"; options.CallbackPath = "/auth/callback"; options.PostLogoutRedirectUri = "https://localhost:5000/"; options.RequireHttpsMetadata = false; // For local development }); ``` ### Example — Custom Scopes ```csharp builder.Services.AddAuthentication() .AddDescopeOidc(options => { options.ProjectId = "proj_xyz"; options.Scope = "openid profile email custom_scope"; }); ``` ``` -------------------------------- ### Configure Descope Client with Options Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/08-configuration-and-types.md Configure the Descope client in ASP.NET applications by loading settings from configuration sources like appsettings.json. Ensure the ProjectId is not null. ```csharp builder.Services.AddDescopeClient(new DescopeClientOptions { ProjectId = builder.Configuration["Descope:ProjectId"]!, ManagementKey = builder.Configuration["Descope:ManagementKey"], BaseUrl = builder.Configuration["Descope:BaseUrl"] }); ``` -------------------------------- ### Create Standalone Descope Client Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/01-client-initialization.md Use this method to create a standalone `IDescopeClient` instance. Ensure `ProjectId` is provided in `DescopeClientOptions`. This method configures dedicated HTTP clients and a handler pipeline, including optional unsafe certificate handling. ```csharp var options = new DescopeClientOptions { ProjectId = "your_project_id", ManagementKey = "your_management_key", IsUnsafe = true // For development only }; var client = DescopeManagementClientFactory.Create(options); var user = await client.Mgmt.V1.User.GetWithIdentifierAsync("user@example.com"); ``` -------------------------------- ### DescopeClient Implementation Structure Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/01-client-initialization.md Provides a concrete implementation of IDescopeClient, wrapping generated clients and offering a stable public API for Management and Authentication. ```csharp public class DescopeClient : IDescopeClient { public class DescopeMgmtClient { public Mgmt.V1.Mgmt.MgmtRequestBuilder V1 { get; } public Mgmt.V2.Mgmt.MgmtRequestBuilder V2 { get; } } public class DescopeAuthClient : ITokenActions { public Auth.V1.Auth.AuthRequestBuilder V1 { get; } public Task ValidateSessionAsync(string sessionJwt) public Task RefreshSessionAsync(string refreshJwt) public Task ValidateAndRefreshSession(string sessionJwt, string refreshJwt) public Task ExchangeAccessKey(string accessKey, AccessKeyLoginOptions? options) } public DescopeMgmtClient Mgmt { get; } public DescopeAuthClient Auth { get; } } ``` -------------------------------- ### Descope .NET SDK Project Structure Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/README.md Overview of the Descope .NET SDK's directory structure, showing the separation between hand-written SDK wrappers, generated client code, and the project file. ```tree Descope/ ├── Sdk/ # Hand-written SDK wrapper │ ├── Auth/ # Token operations and extensions │ ├── Mgmt/ # Management extensions │ ├── Oidc/ # OIDC integration (NET6+) │ ├── Factories/ # Client creation │ ├── Errors/ # Exception classes │ └── Internal/ # Middleware and helpers ├── Generated/ # Kiota-generated client code │ ├── Auth/ # Auth API v1 │ └── Mgmt/ # Management API v1 and v2 └── Descope.csproj ``` -------------------------------- ### Create User Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Creates a new user with specified details including identifier, email, phone, and name. ```APIDOC ## POST /v1/mgmt/user/create ### Description Creates a new user in the system. ### Method POST ### Endpoint /v1/mgmt/user/create ### Request Body - **Identifier** (string) - Required - The unique identifier for the user. - **Email** (string) - Optional - The user's email address. - **VerifiedEmail** (boolean) - Optional - Indicates if the email has been verified. - **Phone** (string) - Optional - The user's phone number. - **VerifiedPhone** (boolean) - Optional - Indicates if the phone number has been verified. - **Name** (string) - Optional - The user's full name. - **Additional fields** - Optional - Other user-related fields. ``` -------------------------------- ### Register Descope Client with DI Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/01-client-initialization.md Use the `AddDescopeClient` extension method to register the Descope client with the service collection. Provide your Project ID and Management Key in `DescopeClientOptions`. The client is registered as a singleton. ```csharp var builder = WebApplication.CreateBuilder(args); // Register Descope client with DI builder.Services.AddDescopeClient(new DescopeClientOptions { ProjectId = "your_project_id", ManagementKey = "your_management_key" }); // In a controller or service public class MyService { private readonly IDescopeClient _client; public MyService(IDescopeClient client) { _client = client; } public async Task MyMethod() { var token = await _client.Auth.ValidateSessionAsync(sessionJwt); } } ``` -------------------------------- ### Create User Request Model Source: https://github.com/descope/descope-dotnet/blob/main/_autodocs/07-api-endpoints-reference.md Defines the structure for creating a new user, including identifier, email, phone, and name. Additional fields can be included as needed. ```csharp public class CreateUserRequest { public string Identifier { get; set; } public string? Email { get; set; } public bool? VerifiedEmail { get; set; } public string? Phone { get; set; } public bool? VerifiedPhone { get; set; } public string? Name { get; set; } // ... additional fields } ```