auth0.net

repository·master·Indexed 18 days ago

https://github.com/auth0/auth0.net

A .NET client library for interacting with Auth0's Authentication and Management APIs. It provides high-level wrappers for managing users, connections, and tenant resources, as well as tools for constructing authentication flows. The SDK includes the Auth0.ManagementApi and Auth0.AuthenticationApi NuGet packages, featuring support for OIDC compliance, token management via ITokenProvider, and dependency injection.

Tokens
77.9K
Snippets
240
Records
277
Agent score
60%

What's inside auth0.net

  1. Understand v8 Request and Response type naming conventions

    master

    v8 uses specific generated type classes for operations. When migrating from v7, look for these naming patterns:

    • Request body types: *RequestContent (e.g., CreateUserRequestContent)
    • Response types: *ResponseContent (e.g., GetUserResponseContent)
    • Response schema types: *ResponseSchema or *Schema (e.g., UserResponseSchema)
    • Query parameters: *RequestParameters (e.g., ListUsersRequestParameters)
    • List operations: Return a Pager<T> instead of IPagedList<T>.
  2. How ManagementClient and ITokenProvider work together

    master

    The recommended way to interact with the Management API is using the ManagementClient wrapper. It simplifies configuration and automates token management using an ITokenProvider.

    There are three primary ways to provide tokens:

    1. Client Credentials: Use ClientCredentialsTokenProvider for server-to-server authentication. Tokens are acquired and refreshed automatically.
    2. Async Delegate: Use DelegateTokenProvider to retrieve tokens from an external source (like a secret manager) via a delegate.
    3. Manual Token: If you already have a valid access token, you can bypass the wrapper and use ManagementApiClient directly.
    // Client Credentials (Recommended for server-to-server)
    var client = new ManagementClient(new ManagementClientOptions
    {
        Domain = "YOUR_AUTH0_DOMAIN",
        TokenProvider = new ClientCredentialsTokenProvider(
            domain: "YOUR_AUTH0_DOMAIN",
            clientId: "YOUR_CLIENT_ID",
            clientSecret: "YOUR_CLIENT_SECRET"
        )
    });
  3. Use hierarchical sub-clients in v8

    master

    v8 organizes related resources into a hierarchical sub-client structure for better discoverability. Instead of calling methods directly on the main client, navigate through sub-clients.

    Common Mappings:

    • client.Users.GetPermissionsAsync() $\rightarrow$ client.Users.Permissions.ListAsync()
    • client.Users.GetRolesAsync() $\rightarrow$ client.Users.Roles.ListAsync()
    • client.Users.AssignRolesAsync() $\rightarrow$ client.Users.Roles.AssignAsync()
    • client.Users.GetLogsAsync() $\rightarrow$ client.Users.Logs.ListAsync()
    • client.Organizations.GetAllMembersAsync() $\rightarrow$ client.Organizations.Members.ListAsync()
  4. Use the correct JSON serializer for ManagementApi

    master

    The SDK uses different JSON serialization stacks depending on the package:

    • Auth0.Core / Auth0.AuthenticationApi: Use both Newtonsoft.Json and System.Text.Json.
    • Auth0.ManagementApi: Uses System.Text.Json exclusively.

    When working within Auth0.ManagementApi, use System.Text.Json and avoid adding Newtonsoft.Json to the project.

  5. Understand the patterns used in the Auth0 .NET SDK

    master

    The SDK follows several architectural patterns that you can leverage when building integrations or mocks:

    • Builder Pattern: Used for constructing Authentication API URLs (e.g., AuthorizationUrlBuilder, LogoutUrlBuilder) via fluent methods like .WithState(...).
    • Provider/Strategy Pattern: The ManagementClient uses ITokenProvider implementations, such as ClientCredentialsTokenProvider or DelegateTokenProvider, to handle token acquisition.
    • Interface-per-client: Every client and sub-client provides an interface, making them suitable for Dependency Injection (DI) and unit testing with mocks.
    • Typed Exceptions: Errors are handled via a hierarchy starting with ApiException. Core includes ErrorApiException and RateLimitApiException, while the Management API provides specific exceptions based on HTTP status codes.
  6. Manage Auth0 Actions with ActionsClient

    master

    Use the client.Actions property to manage Auth0 Actions. Actions can be created, updated, deployed, tested, and deleted.

    Lifecycle Note:

    • When creating an action, it must be deployed and then bound to a trigger before it executes in a flow.
    • Updating an action does not affect user flows until the action is deployed.
    • Deploying an action creates a new immutable version. If the action is already bound to a trigger, the new version takes effect immediately.
  7. Use Optional<T> for PATCH operations

    master

    v8 uses the Optional<T> type for update/patch request fields to distinguish between three states:

    • Undefined: The field is not sent (remains unchanged on the server).
    • Defined with null: The field is sent as null (clears the field on the server).
    • Defined with value: The field is sent with the provided value (updates the field).

    Use Optional<T>.Of(null) to explicitly clear a field.

    using Auth0.ManagementApi.Core;
    
    // Update only specific fields
    var request = new UpdateUserRequestContent
    {
        Name = "John Doe" 
    };
    
    // Explicitly clear a field
    var clearNickname = new UpdateUserRequestContent
    {
        Nickname = Optional<string?>.Of(null)
    };
    
    // Check if a value is defined
    if (request.Name.IsDefined) 
    {
        var val = request.Name.Value;
    }
  8. Handle partial updates using Optional<T> in ManagementApi

    master

    The Management API uses a tri-state logic for PATCH requests to distinguish between three states: a value is provided, a value is explicitly set to null (to clear the field), or a value is not provided at all (to leave the field unchanged).

    To achieve this, request models use the Optional<T> wrapper.

    • To update a field: Assign the desired value to the Optional<T> property.
    • To clear a field (set to null on server): Use Optional<T>.Of(null).
    • To leave a field unchanged: Do not assign any value to the property (it remains Optional<T>.Undefined).

    Warning: Do not assign a raw null to an Optional<T> field, as this creates ambiguous intent and can lead to clobbering server data.

    // ✅ Good: Only sending what you mean
    var request = new UpdateUserRequestContent
    {
        Name = "John Doe"                     // sent
        // Email left as Optional<string?>.Undefined — not sent
    };
    
    var clear = new UpdateUserRequestContent
    {
        Nickname = Optional<string?>.Of(null) // sent as null → clears the field
    };
    
    // ❌ Bad: Ambiguous intent or incorrect clearing
    var request = new UpdateUserRequestContent
    {
        Name = "John Doe",
        Email = null,      // Ambiguous; don't assign raw null to an Optional<T> field
        Nickname = ""       // Empty string is not the same as "clear"
    };
  9. Authentication API compatibility in v8

    master

    The Auth0.AuthenticationApi package has not changed between v7 and v8. Code written for the Authentication API in v7 is fully compatible with v8. You can continue using AuthenticationApiClient to perform token requests as usual.

    // Works in both v7 and v8
    using Auth0.AuthenticationApi;
    
    var client = new AuthenticationApiClient(new Uri("https://YOUR_DOMAIN"));
    
    var tokenRequest = new ResourceOwnerTokenRequest
    {
        ClientId = "YOUR_CLIENT_ID",
        ClientSecret = "YOUR_CLIENT_SECRET",
        Username = "user@example.com",
        Password = "password",
        Scope = "openid profile"
    };
    
    var token = await client.GetTokenAsync(tokenRequest);
  10. Use Checkpoint Pagination for Connections

    master

    When retrieving large lists of connections (more than 1000), you must use Checkpoint Pagination to ensure all entries are captured.

    1. Initial Call: Call ListAsync without the From parameter.
    2. Subsequent Calls: If more results exist, the response will include a next value. Use this value in the From property of your next ListConnectionsQueryParameters object.
    3. Termination: When the next value is no longer included in the response, you have reached the end of the list.

    Parameters for checkpoint pagination:

    • from: The ID from which to start the selection.
    • take: The number of entries to retrieve (defaults to 50).
  11. Handle optional fields with Optional<T>

    master

    The SDK uses the Optional<T> type to distinguish between three states in request payloads (crucial for PATCH/update operations):

    1. Undefined: The field is not sent in the request (the server leaves the existing value unchanged).
    2. Defined with null: The field is sent as null (the server clears the value on the server).
    3. Defined with value: The field is sent with a specific value (the server updates the value).

    Use Optional<T>.Of(null) to explicitly clear a field, or simply omit the property to leave it unchanged.

    using Auth0.ManagementApi;
    using Auth0.ManagementApi.Core;
    
    // 1. Update only the name (others are Undefined and won't be sent)
    var request = new UpdateUserRequestContent
    {
        Name = "John Doe"
    };
    
    // 2. Explicitly clear a field (sends null)
    var clearNickname = new UpdateUserRequestContent
    {
        Nickname = Optional<string?>.Of(null)
    };
    
    // 3. Checking values
    if (request.Name.IsDefined)
    {
        Console.WriteLine($"Name will be updated to: {request.Name.Value}");
    }
    
    if (request.Email.TryGetValue(out var email))
    {
        Console.WriteLine($"Email: {email}");
    }