Skip to content

Add OAuth2 token lifecycle authenticators (client credentials, refresh token, custom provider) #2361

Description

@alexeyzimarev

Problem

RestSharp's existing OAuth2 authenticators (OAuth2AuthorizationRequestHeaderAuthenticator, OAuth2UriQueryParameterAuthenticator) are static token stampers — they take a pre-obtained token and add it to requests. They don't handle token acquisition, caching, expiry, or refresh.

Users who need automatic token lifecycle management hit a circular dependency: an authenticator that calls a token endpoint needs an HttpClient, but it lives inside the RestClient it's attached to. This was reported in #2101 as "replace the authenticator after creating the client," but the actual need is self-managing authenticators that handle the token lifecycle internally.

Solution

Three new authenticators that manage the full OAuth2 token lifecycle using their own internal HttpClient for token endpoint calls:

OAuth2ClientCredentialsAuthenticator

Machine-to-machine flow. POSTs grant_type=client_credentials to the token endpoint. Caches the token and refreshes automatically when expired. Thread-safe via SemaphoreSlim with double-check pattern.

OAuth2RefreshTokenAuthenticator

User token flow. Takes initial access + refresh tokens. When the access token expires, POSTs grant_type=refresh_token. Handles refresh token rotation. Fires a callback when tokens change so callers can persist them.

OAuth2TokenAuthenticator

Generic delegate-based authenticator. Takes Func<CancellationToken, Task<OAuth2Token>> for non-standard flows. Caches the result and re-invokes the delegate on expiry.

Shared types

  • OAuth2TokenResponse — RFC 6749 Section 5.1 token response model
  • OAuth2TokenRequest — Configuration for token endpoint calls (URL, client ID/secret, scope, expiry buffer, callback)
  • OAuth2Token — Simple record for the delegate-based authenticator

Key design decisions

  • Each authenticator owns its own HttpClient for token endpoint calls (avoids circular dependency with RestClient)
  • User can provide their own HttpClient via OAuth2TokenRequest.HttpClient (e.g., for proxies or mTLS)
  • Action<OAuth2TokenResponse> callback for token persistence
  • No changes to existing APIs or behavior

Supersedes #2101.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions