Crate clio_auth

source ·
Expand description

OAuth 2.0 helper for CLI and desktop applications.

This package facilitates the OAuth 2.0 Authorization Code with PKCE flow for command line and desktop GUI applications. It works hand-in-hand with the oauth2 crate by providing the “missing pieces” for the flow: a web server to handle the authorization callback, and opening the browser with the authorization link.

Usage

General usage is as follows:

  1. Configure a CliOAuthBuilder and build a CliOAuth helper
  2. Configure an oauth2::Client
  3. Start the authorization flow
  4. Validate and obtain the authorization code
  5. Exchange the code for a token

Example

This example is adapted directly from the oauth2 package documentation (“Asynchronous API”), and demonstrates how CliOAuth fills in the gaps.

use anyhow;
use oauth2::{
    AuthorizationCode,
    AuthUrl,
    ClientId,
    ClientSecret,
    CsrfToken,
    PkceCodeChallenge,
    RedirectUrl,
    Scope,
    TokenResponse,
    TokenUrl
};
use oauth2::basic::BasicClient;
use oauth2::reqwest::async_http_client;
use url::Url;

// CliOAuth: Build helper with default options
let mut auth = clio_auth::CliOAuth::builder().build().unwrap();        // (1)
// Create an OAuth2 client by specifying the client ID, client secret, authorization URL and
// token URL.
let client =
    BasicClient::new(
        ClientId::new("client_id".to_string()),
        Some(ClientSecret::new("client_secret".to_string())),
        AuthUrl::new("http://authorize".to_string())?,
        Some(TokenUrl::new("http://token".to_string())?)
    )
    // CliOAuth: Use the local redirect URL
    .set_redirect_uri(auth.redirect_url());                           // (2)

// CliOAuth: The PKCE challenge is handled internally. Just authorize... (3)
match auth.authorize(&oauth_client).await {
    Ok(()) => info!("authorized successfully"),
    Err(e) => warn!("uh oh! {:?}", e),
};
// CliOAuth: The browser is opened to the authorization URL              (3)

// Once the user has been redirected to the redirect URL, you'll have access to the
// authorization code. For security reasons, your code should verify that the `state`
// parameter returned by the server matches `csrf_state`.
// CliOAuth: Validation must be performed to acquire the authorization code. CliOAuth handles
// the CSRF verification.
match auth.validate() {                                              // (4)
    Ok(AuthContext {
        auth_code,
        pkce_verifier,
        state: _,
    }) => {
        // Now you can trade it for an access token.
        let token_result = client
            .exchange_code(auth_code)                                // (5)
            // Set the PKCE code verifier.
            .set_pkce_verifier(pkce_verifier)
            .request_async(async_http_client)
            .await?;
        // Unwrapping token_result will either produce a Token or a RequestTokenError.
    },
    Err(e) => warn!("uh oh! {:?}", e),
}

Breaking it down…

  1. CliOAuth construction starts with a builder, which allows you to customize the way the authorization helper is configured. See the builder doc for more details about configuration.
  2. CliOAuth constructs the authorization URL based on the address & port it is running on. The URL is provided to the oauth2::Client during construction.
  3. Invoking the CliOAuth::authorize method will do the following things:
    • Launch a local web server
    • Generate the CSRF protection token (state parameter)
    • Open the user’s browser with the URL to initiate the authorization flow
    • Receive the redirect from the IdP that contains the incoming authorization code
    • Shutdown the local web server
  4. Invoking the CliOAuth::validate method will verify that an auth code was received and that the state parameter matches the expected value. If validation succeeds, the auth code and PKCE verifier will be returned to the caller.
  5. The auth code and PKCE verifier are provided to the exchange code flow.

Structs

Enums

  • Errors that can occur during the authorization flow.
  • Errors that can occur during helper configuration.
  • Errors that can occur from the internal web server during the OAuth flow.

Type Aliases