pub struct OAuth2Client {
pub provider_config: ProviderConfig,
/* private fields */
}Expand description
OAuth 2.1 client wrapper supporting all modern flows
Fields§
§provider_config: ProviderConfigProvider-specific configuration
Implementations§
Source§impl OAuth2Client
impl OAuth2Client
Sourcepub fn new(
config: &OAuth2Config,
provider_type: ProviderType,
) -> McpResult<Self>
pub fn new( config: &OAuth2Config, provider_type: ProviderType, ) -> McpResult<Self>
Create an OAuth 2.1 client supporting all flows
Sourcepub fn auth_code_client(&self) -> &BasicClient
pub fn auth_code_client(&self) -> &BasicClient
Get access to the authorization code client
Sourcepub fn client_credentials_client(&self) -> Option<&BasicClient>
pub fn client_credentials_client(&self) -> Option<&BasicClient>
Get access to the client credentials client (if available)
Sourcepub fn device_code_client(&self) -> Option<&BasicClient>
pub fn device_code_client(&self) -> Option<&BasicClient>
Get access to the device code client (if available)
Sourcepub fn provider_config(&self) -> &ProviderConfig
pub fn provider_config(&self) -> &ProviderConfig
Get the provider configuration
Start authorization code flow with PKCE
This initiates the OAuth 2.1 authorization code flow with PKCE (RFC 7636) for enhanced security, especially for public clients.
§PKCE Code Verifier Storage (CRITICAL SECURITY REQUIREMENT)
The returned code_verifier MUST be securely stored and associated with the state parameter until the authorization code is exchanged for tokens.
Storage Options (from most to least secure):
-
Server-side encrypted session (RECOMMENDED for web apps)
- Store in server session with HttpOnly, Secure, SameSite=Lax cookies
- Associate with state parameter for CSRF protection
- Automatic cleanup after exchange or timeout
-
Redis/Database with TTL (RECOMMENDED for distributed systems)
- Key: state parameter, Value: encrypted code_verifier
- Set TTL to match authorization timeout (typically 10 minutes)
- Use server-side encryption at rest
-
In-memory for SPAs (ACCEPTABLE for public clients only)
- Store in JavaScript closure or React state (NOT localStorage/sessionStorage)
- Clear immediately after token exchange
- Risk: XSS can steal verifier
NEVER:
- Store in localStorage or sessionStorage (XSS risk)
- Send to client in URL or query parameters
- Log or expose in error messages
§Arguments
scopes- Requested OAuth scopesstate- CSRF protection state parameter (use cryptographically random value)
§Returns
Tuple of (authorization_url, PKCE code_verifier for secure storage)
§Example
// Server-side web app (RECOMMENDED)
let state = generate_csrf_token(); // Cryptographically random
let (auth_url, code_verifier) = client.authorization_code_flow(scopes, state.clone());
// Store securely server-side
session.insert("oauth_state", state);
session.insert("pkce_verifier", code_verifier); // Encrypted session
// Redirect user
redirect_to(auth_url);Sourcepub async fn exchange_code_for_token(
&self,
code: String,
code_verifier: String,
) -> McpResult<TokenInfo>
pub async fn exchange_code_for_token( &self, code: String, code_verifier: String, ) -> McpResult<TokenInfo>
Exchange authorization code for access token
This exchanges the authorization code received from the OAuth provider for an access token using PKCE (RFC 7636).
§Arguments
code- Authorization code from OAuth providercode_verifier- PKCE code verifier (from authorization_code_flow)
§Returns
TokenInfo containing access token and refresh token (if available)
Sourcepub async fn refresh_access_token(
&self,
refresh_token: &str,
) -> McpResult<TokenInfo>
pub async fn refresh_access_token( &self, refresh_token: &str, ) -> McpResult<TokenInfo>
Refresh an access token with automatic refresh token rotation
This uses a refresh token to obtain a new access token without requiring user interaction. OAuth 2.1 and RFC 9700 recommend refresh token rotation where the server issues a new refresh token with each refresh request.
§Refresh Token Rotation (OAuth 2.1 / RFC 9700 Best Practice)
When the server supports rotation:
- A new refresh token is returned in the response
- The old refresh token should be discarded immediately
- Store and use the new refresh token for future requests
- This prevents token theft detection
Important: Always check if token_info.refresh_token is present in
the response. If present, you MUST replace your stored refresh token
with the new one. If absent, continue using the current refresh token.
§Arguments
refresh_token- The current refresh token
§Returns
New TokenInfo with:
- Fresh access token (always present)
- New refresh token (if server supports rotation)
§Example
let mut stored_refresh_token = "current_refresh_token";
let new_tokens = client.refresh_access_token(stored_refresh_token).await?;
// Check for refresh token rotation
if let Some(new_refresh_token) = &new_tokens.refresh_token {
// Server rotated the token - update storage
stored_refresh_token = new_refresh_token;
println!("Refresh token rotated (security best practice)");
}
// Use new access token
let access_token = new_tokens.access_token;Sourcepub async fn revoke_token(&self, token_info: &TokenInfo) -> McpResult<()>
pub async fn revoke_token(&self, token_info: &TokenInfo) -> McpResult<()>
Revoke a token using RFC 7009 Token Revocation
Per RFC 7009 Section 2, prefer revoking refresh tokens (which MUST be supported by the server if issued) over access tokens (which MAY be supported).
§Arguments
token_info- Token information containing access and/or refresh token
§Returns
Ok if revocation succeeded or token was already invalid (per RFC 7009)
§Errors
Returns error if:
- No revocation endpoint was configured
- Network/HTTP error occurred
- Server returned an error response
Sourcepub fn is_token_expired(&self, token: &TokenInfo) -> bool
pub fn is_token_expired(&self, token: &TokenInfo) -> bool
Validate that an access token is still valid
This checks if a token has expired based on expiration time. Note: This is a client-side check only; servers may have revoked the token.
Trait Implementations§
Source§impl Clone for OAuth2Client
impl Clone for OAuth2Client
Source§fn clone(&self) -> OAuth2Client
fn clone(&self) -> OAuth2Client
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more