Skip to content

Authentication Guide: ConnectSoft API Library Template

The ConnectSoft API Library Template supports multiple authentication mechanisms to accommodate different API security requirements. This guide provides detailed information about each authentication type, their implementation, configuration, and best practices.

Authentication Types Overview

The template supports the following authentication mechanisms:

Authentication Type Use Case Security Level Configuration Complexity
None Public APIs None None
Basic Legacy APIs, simple auth Low Low
ApiKey Most modern APIs Medium Low
OAuth Enterprise APIs, token-based High Medium
OpenIDConnect Identity provider integration Very High High

None Authentication

Overview

None authentication is used for public APIs that don't require authentication. This is the default authentication type.

When to Use

  • Public APIs without authentication requirements
  • APIs that handle authentication externally (e.g., via API Gateway)
  • Development/testing scenarios

Configuration

No authentication configuration is required. The HTTP client is configured without authentication headers.

Example

dotnet new connectsoft-api-library \
  --api-service-name "PublicAPI" \
  --api-service-description "Public API client" \
  --authentication-type "None"

Generated Code

No authentication options classes are generated. The service extension method configures the HTTP client without authentication:

public static IServiceCollection AddPublicAPIService(this IServiceCollection services)
{
    services.AddHttpClient<IPublicAPIService, PublicAPIService>(configureClient =>
    {
        client.BaseAddress = new Uri(options.BaseUrl);
        client.Timeout = options.DefaultTimeout;
        // No authentication headers added
    });
}

Basic Authentication

Overview

Basic authentication uses HTTP Basic Authentication with Base64-encoded username and password credentials.

When to Use

  • Legacy APIs that require Basic authentication
  • Simple username/password authentication
  • Internal APIs with basic security requirements

Security Considerations

⚠️ Warning: Basic authentication sends credentials in Base64 encoding (not encryption). Always use HTTPS to protect credentials in transit.

Configuration

The template generates BasicAuthenticationOptions.cs when AuthenticationType=Basic:

public sealed class BasicAuthenticationOptions
{
    [Required]
    required public string Username { get; set; }

    [Required]
    required public string Password { get; set; }
}

appsettings.json

{
  "MyService": {
    "BaseUrl": "https://api.example.com",
    "BasicAuthentication": {
      "Username": "your-username",
      "Password": "your-password"
    }
  }
}

Implementation

The template automatically adds Basic authentication headers:

private static void AddBasicAuthenticationHeader(HttpClient client)
{
    if (options.BasicAuthentication != null)
    {
        var credentials = Convert.ToBase64String(
            Encoding.UTF8.GetBytes(
                $"{options.BasicAuthentication.Username}:{options.BasicAuthentication.Password}"));
        client.DefaultRequestHeaders.Authorization = 
            new AuthenticationHeaderValue("Basic", credentials);
    }
}

Service Registration

services.AddMyServiceOptions(configuration);
services.AddMyServiceService();

Example

dotnet new connectsoft-api-library \
  --api-service-name "LegacyAPI" \
  --api-service-description "Legacy API with Basic auth" \
  --authentication-type "Basic"

API Key Authentication

Overview

API Key authentication uses a key value sent in HTTP headers or query strings. This is the most common authentication method for modern APIs.

When to Use

  • REST APIs that use API keys
  • Third-party service integrations (e.g., Stripe, Twilio)
  • APIs with simple key-based authentication

Configuration

The template generates ApiKeyAuthenticationOptions.cs when AuthenticationType=ApiKey:

public sealed class ApiKeyAuthenticationOptions
{
    [Required]
    required public string ApiKey { get; set; }

    [Required]
    required public string HeaderName { get; set; } = "X-Api-Key";
}

appsettings.json

{
  "MyService": {
    "BaseUrl": "https://api.example.com",
    "ApiKeyAuthentication": {
      "ApiKey": "your-api-key-here",
      "HeaderName": "X-API-Key"
    }
  }
}

Common Header Names

Different APIs use different header names for API keys:

  • X-API-Key (default)
  • X-Api-Key
  • Authorization (with Bearer or ApiKey prefix)
  • X-API-KEY
  • Custom header names (e.g., X-Stripe-API-Key)

Implementation

The template automatically adds API key headers:

private static void AddApiKeyAuthenticationHeader(HttpClient client)
{
    if (options.ApiKeyAuthentication != null)
    {
        client.DefaultRequestHeaders.Add(
            options.ApiKeyAuthentication.HeaderName,
            options.ApiKeyAuthentication.ApiKey);
    }
}

Service Registration

services.AddMyServiceOptions(configuration);
services.AddMyServiceService();

Example

dotnet new connectsoft-api-library \
  --api-service-name "StripeClient" \
  --api-service-description "Stripe Payment API" \
  --authentication-type "ApiKey"

Best Practices

  1. Store Keys Securely: Never commit API keys to source control. Use:

    • Environment variables
    • Azure Key Vault
    • User Secrets (for development)
    • Secure configuration providers
  2. Use HTTPS: Always use HTTPS to protect API keys in transit.

  3. Rotate Keys: Regularly rotate API keys for security.

OAuth2 Authentication

Overview

OAuth2 authentication uses the OAuth 2.0 client credentials flow for token-based authentication. The template integrates with ConnectSoft.Extensions.Http.OAuth2 for automatic token acquisition and refresh.

When to Use

  • Enterprise APIs using OAuth 2.0
  • Microsoft Graph API
  • Azure AD protected APIs
  • APIs requiring token-based authentication

Prerequisites

The template automatically adds the ConnectSoft.Extensions.Http.OAuth2 package when AuthenticationType=OAuth or AuthenticationType=OpenIDConnect.

Configuration

OAuth2 configuration is embedded in the service options:

{
  "MyService": {
    "BaseUrl": "https://api.example.com",
    "OAuth2Authentication": {
      "ClientName": "MyService",
      "OAuthHttpHandler": {
        "OAuth2Options": {
          "TokenEndpoint": "https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token",
          "DefaultTimeout": "00:00:10",
          "ClientId": "your-client-id",
          "ClientSecret": "your-client-secret",
          "GrantType": "ClientCredentials",
          "CredentialsTransportMethod": "FormRequestBody",
          "TokenRequestContentType": "FormUrlEncoded",
          "Scope": [ "https://graph.microsoft.com/.default" ],
          "SetGrantTypeOnQueryString": false,
          "CredentialsKeyNames": {
            "client_id": "client_id",
            "client_secret": "client_secret",
            "grant_type": "grant_type"
          },
          "AccessTokenResponseOptions": {
            "KeyNames": {
              "AccessToken": "access_token",
              "TokenType": "token_type",
              "ExpiresIn": "expires_in"
            }
          }
        },
        "HttpClientFactoryEnabled": true,
        "IgnoreRefreshTokens": false
      }
    }
  }
}

Implementation

The template automatically configures OAuth2 authentication:

private static void AddOAuth2Authentication(this IServiceCollection services, HttpClient client)
{
    if (options.OAuth2Authentication != null)
    {
        services.AddOAuth2ClientFrom<MyServiceOptions>(
            clientName: "MyService",
            selector: o => o.OAuth2Authentication,
            configureOAuth2Options: o =>
            {
                o.AccessTokenResponseOptions.UseDefaultSystemTextJsonDeserializer();
            });
    }
}

Token Flow

sequenceDiagram
    participant Client
    participant Service
    participant OAuth2Handler
    participant TokenEndpoint
    participant API

    Client->>Service: Request
    Service->>OAuth2Handler: Get Token
    OAuth2Handler->>TokenEndpoint: Request Token
    TokenEndpoint->>OAuth2Handler: Access Token
    OAuth2Handler->>Service: Token (cached)
    Service->>API: Authenticated Request
    API->>Service: Response
    Service->>Client: Result
Hold "Alt" / "Option" to enable pan & zoom

Service Registration

services.AddMyServiceOptions(configuration);
services.AddMyServiceService();

Example

dotnet new connectsoft-api-library \
  --api-service-name "MicrosoftGraph" \
  --api-service-description "Microsoft Graph API" \
  --authentication-type "OAuth"

Best Practices

  1. Secure Client Secrets: Store client secrets securely:

    • Azure Key Vault
    • Environment variables
    • User Secrets (for development)
  2. Token Caching: The OAuth2 handler automatically caches and refreshes tokens.

  3. Scope Management: Request only the scopes needed for your application.

  4. Error Handling: Handle token acquisition failures gracefully.

OpenID Connect Authentication

Overview

OpenID Connect authentication extends OAuth2 with identity provider integration and token validation. It provides additional security through token validation and issuer verification.

When to Use

  • APIs requiring identity provider integration
  • Single Sign-On (SSO) scenarios
  • APIs with strict token validation requirements
  • Enterprise applications with identity provider integration

Prerequisites

Same as OAuth2: The ConnectSoft.Extensions.Http.OAuth2 package is automatically added.

Configuration

OpenID Connect configuration extends OAuth2 with validation settings:

{
  "MyService": {
    "BaseUrl": "https://api.example.com",
    "OAuth2Authentication": {
      "ClientName": "MyService",
      "OAuthHttpHandler": {
        "OAuth2Options": {
          /* Same as OAuth2 configuration */
        },
        "HttpClientFactoryEnabled": true,
        "IgnoreRefreshTokens": false
      },
      "OpenIdConnect": {
        "Authority": "https://login.microsoftonline.com/{tenant-id}/v2.0",
        "ValidIssuers": [
          "https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token"
        ],
        "ValidAudiences": [ "your-client-id" ],
        "ValidateLifetime": true,
        "ValidateIssuerSigningKey": true,
        "ClockSkew": "00:05:00",
        "AdditionalTrustedSigningKeys": [],
        "RequireHttpsMetadata": true
      }
    }
  }
}

Implementation

The template configures OpenID Connect validation in addition to OAuth2:

services.AddOAuth2ClientFrom<MyServiceOptions>(
    clientName: "MyService",
    selector: o => o.OAuth2Authentication,
    configureOAuth2Options: o =>
    {
        o.AccessTokenResponseOptions.UseDefaultSystemTextJsonDeserializer();
        // OpenID Connect validation is configured automatically
    });

Token Validation

OpenID Connect adds token validation:

  • Issuer Validation: Verifies token issuer matches expected authority
  • Audience Validation: Verifies token audience matches client ID
  • Lifetime Validation: Verifies token hasn't expired
  • Signing Key Validation: Verifies token signature
  • Clock Skew: Allows for time synchronization differences

Service Registration

services.AddMyServiceOptions(configuration);
services.AddMyServiceService();

Example

dotnet new connectsoft-api-library \
  --api-service-name "EnterpriseAPI" \
  --api-service-description "Enterprise API with OpenID Connect" \
  --authentication-type "OpenIDConnect"

Best Practices

  1. Authority Configuration: Ensure the authority URL matches your identity provider.
  2. Audience Validation: Always validate token audiences to prevent token misuse.
  3. Signing Key Validation: Enable signing key validation for production.
  4. Clock Skew: Configure appropriate clock skew for time synchronization.

Authentication Selection Guide

Decision Tree

Is authentication required?
├─ No → Use "None"
└─ Yes → What type of authentication?
    ├─ Username/Password → Use "Basic" (with HTTPS)
    ├─ API Key → Use "ApiKey"
    ├─ Token-based (OAuth 2.0) → Use "OAuth"
    └─ Token-based with validation → Use "OpenIDConnect"

Comparison Table

Feature None Basic ApiKey OAuth OpenIDConnect
Security Level None Low Medium High Very High
Token Management N/A N/A N/A Automatic Automatic + Validation
Configuration Complexity None Low Low Medium High
Token Refresh N/A N/A N/A Yes Yes
Token Validation N/A N/A N/A No Yes
Best For Public APIs Legacy APIs Modern APIs Enterprise APIs Enterprise + SSO

Security Best Practices

General Guidelines

  1. Always Use HTTPS: Protect credentials and tokens in transit.

  2. Secure Storage: Never store credentials or keys in source code:

    • Use Azure Key Vault
    • Use environment variables
    • Use User Secrets (development only)
  3. Credential Rotation: Regularly rotate API keys and client secrets.

  4. Least Privilege: Request only the permissions/scopes needed.

  5. Error Handling: Don't expose sensitive information in error messages.

API Key Security

  • Store keys in secure configuration providers
  • Rotate keys regularly
  • Use different keys for different environments
  • Monitor key usage for anomalies

OAuth2/OpenID Connect Security

  • Store client secrets securely
  • Use appropriate token lifetimes
  • Validate tokens in production
  • Monitor token usage and refresh patterns
  • Implement proper error handling for token failures

Troubleshooting

Common Issues

Basic Authentication Fails

Problem: 401 Unauthorized errors.

Solutions:

  • Verify username and password are correct
  • Ensure HTTPS is used
  • Check Base64 encoding is correct
  • Verify credentials haven't expired

API Key Not Working

Problem: 401 Unauthorized or 403 Forbidden errors.

Solutions:

  • Verify API key is correct
  • Check header name matches API requirements
  • Ensure API key hasn't expired
  • Verify API key has required permissions

OAuth2 Token Acquisition Fails

Problem: Token endpoint returns errors.

Solutions:

  • Verify client ID and secret are correct
  • Check token endpoint URL is correct
  • Verify scopes are valid
  • Check network connectivity to token endpoint
  • Review token endpoint error responses

OpenID Connect Validation Fails

Problem: Token validation errors.

Solutions:

  • Verify authority URL is correct
  • Check valid issuers match token issuer
  • Verify audience matches client ID
  • Check token hasn't expired
  • Verify signing keys are accessible

Configuration Examples

Complete Configuration Example (API Key)

{
  "MyService": {
    "BaseUrl": "https://api.example.com",
    "DefaultTimeout": "00:00:30",
    "ApiKeyAuthentication": {
      "ApiKey": "your-api-key-here",
      "HeaderName": "X-API-Key"
    },
    "WebProxy": {
      "UseProxy": false
    },
    "EnableHttpStandardResilience": true,
    "HttpStandardResilience": {
      /* resilience configuration */
    }
  }
}

Complete Configuration Example (OAuth2)

{
  "MyService": {
    "BaseUrl": "https://api.example.com",
    "DefaultTimeout": "00:00:30",
    "OAuth2Authentication": {
      "ClientName": "MyService",
      "OAuthHttpHandler": {
        "OAuth2Options": {
          "TokenEndpoint": "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token",
          "ClientId": "your-client-id",
          "ClientSecret": "your-client-secret",
          "GrantType": "ClientCredentials",
          "Scope": [ "https://api.example.com/.default" ]
        }
      }
    }
  }
}

Conclusion

The ConnectSoft API Library Template provides comprehensive authentication support for various API security requirements. By choosing the appropriate authentication type and following security best practices, you can build secure and reliable API client libraries.

For more information, see: