An oauth2 client implementation providing the Device, Installed and Service Account flows.

Overview

Build Status codecov crates.io

yup-oauth2 is a utility library which implements several OAuth 2.0 flows. It's mainly used by google-apis-rs, to authenticate against Google services. (However, you're able to use it with raw HTTP requests as well; the flows are implemented as token sources yielding HTTP Bearer tokens). Note that the newer, asynchronous versions of this crate (version 4) are not compatible with google-apis-rs anymore/at the moment.

To use asynchronous APIs with the new yup-oauth2 (from version 4), use the async-google-apis code generator, which generates asynchronous API stubs for Google APIs and other providers who provide Discovery documents for their REST APIs. (WARNING: that project is still alpha-quality. Contributions are welcome)

The provider we have been testing the code against is also Google. However, the code itself is generic, and any OAuth provider behaving like Google will work as well. If you find one that doesn't, please let us know and/or contribute a fix!

Supported authorization types

  • Device flow (user enters code on authorization page)
  • Installed application flow (user visits URL, copies code to application, application uses code to obtain token). Used for services like GMail, Drive, ...
  • Service account flow: Non-interactive authorization of server-to-server communication based on public key cryptography. Used for services like Cloud Pubsub, Cloud Storage, ...

Usage

Please have a look at the API landing page for all the examples you will ever need.

A simple commandline program which authenticates any scope and prints token information can be found in the examples directory.

The video below shows the auth example in action. It's meant to be used as utility to record all server communication and improve protocol compliance.

usage

Versions

Version 1.x for Hyper versions bellow 12 Version 2.x for Hyper versions 12 and above

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • async/await plus a variety of other changes

    async/await plus a variety of other changes

    I'm sending this at the risk of overwhelming as I recognize it's a pretty large pull request. This started with moving to std::future::Future as discussed in #111 then snowballed into a variety of changes (hopefully improvements) that could be made while we were already breaking semver compatibility.

    Feel free to pick and choose which commits you like. The first commit is the only one necessary to get to std::future::Futures. As mentioned in the feature request this currently pins a few crates that are released with alpha labels. I would expect to wait for those dependencies to no longer be in alpha before releasing these changes.

    opened by ggriffiniii 46
  • feature: Enable fetching of OAuth credentials from the GCE metadata service

    feature: Enable fetching of OAuth credentials from the GCE metadata service

    This is highly optional, but also isn't really complicated (just calling an HTTP endpoint without much more authentication/authorization fuss): https://cloud.google.com/compute/docs/storing-retrieving-metadata.

    I'm glad about feedback on this, as it's vendor-proprietary; on the other hand, it doesn't restrict the other functionality.

    enhancement 
    opened by dermesser 14
  • Sharing ServiceAccountAccess between threads

    Sharing ServiceAccountAccess between threads

    @dermesser

    We use ServiceAccountAccess with Arc<RwLock<_>> for share between threads. But we can't it because build method returns impl GetToken in 3.1.x later.

    There is a workaround?

    opened by alu 11
  • open webbrowser with url for the user

    open webbrowser with url for the user

    googles python api has that as an option. very convenient as the auth URL doesn't have to be copied from terminal, especially with the installed-app-flow no copy/paste needed, ever.

    this is a quickhack showing it works in rust too. I guess you might want to make this optional somehow? Please let me know how to integrate this for your library.

    opened by mike-kfed 10
  • Consider making `Authenticator` a `Clone`

    Consider making `Authenticator` a `Clone`

    In many instances the libraries based on yup_oauth2 will take the Authenticator by value. This, however, prevents reuse of the tokens between different libraries or even instances of whatever type represents some sort of behaviour of a single library.

    It seems like the primary reason Authenticator currently cannot be Clone is its implementation of Storage, which internally stores a Mutex<HashMap<_, _>>. A trivial solution would be to wrap that into an Arc, however, using some lock-free thread-safe storage would likely be a more lasting solution.

    opened by nagisa 10
  • fix(openssl): Update to 0.9.x

    fix(openssl): Update to 0.9.x

    Hey so I tried to use this on MacOS and ran into the typical rust openssl include error. This was fixed in openssl 0.9.4. I figured updating yup-oauth2 would help others that run into a similar issue.

    opened by martell 10
  • --all-features and --no-default-features

    --all-features and --no-default-features

    This adjusts the code and documentation for --all-features and --no-default-features to work correctly. With --no-default-features no DefaultAuthenticator is made available. Users are in control of picking the Connector they want to use, and are not forced to stomach a dependency on rustls or hyper-tls if their TLS implementation of choice doesn't happen to match one of the two.

    To indicate this, the unstable doc_cfg feature is used to build documentation on docs.rs. That way the generated documentation has notices on these types that look as such:

    This is supported on crate features hyper-rustls or hyper-tls only.

    Additionally this functionality is tested via additional coverage in the Actions' CI.

    This, I believe, should be a backwards compatible change, with a very small exception – users who have RUSTDOCFLAGS='--cfg=yup_oauth2_docsrs' set and are building with a non-nightly compiler will observe failures to generate documentation.

    opened by nagisa 9
  • Custom token storage

    Custom token storage

    Related to: https://github.com/dermesser/yup-oauth2/issues/145

    Allow users to build their own token storage system by implementing the TokenStorage trait. This allows use of more secure storage mechanisms like OS keychains, encrypted files, or secret-management tools.

    Custom storage providers are Box-ed to avoid adding more generics to the API — the indirection cost will only apply if using a custom store.

    I've added anyhow to allow easy handling of a wide range of errors from custom storage providers.

    As discussed in the linked issue, this approach uses boxing to extend the existing storage enum and minimise API changes.

    The one significant API change is that Storage.set and thus Authenticator.token() now require &mut self, so caller will need to store the Authenticator with in a mutable variable.

    opened by djrodgerspryor 9
  • feat(storage): Implement DiskTokenStorage

    feat(storage): Implement DiskTokenStorage

    DiskTokenStorage is a TokenStorage that stores its tokens in a JSON file on disk. That file can be read in later, and the tokens in it reused. (The idea for using a cache file is from here: https://developers.google.com/drive/v3/web/quickstart/go#step_3_set_up_the_sample)

    opened by dermesser 9
  • Is there any particular reason TokenStorage uses token scope hashes instead of subset matching

    Is there any particular reason TokenStorage uses token scope hashes instead of subset matching

    I am building a small app that does many things in Google Cloud. You can imagine it uses multiple scopes at the same time.

    Right now, in order to authenticate against a set of scopes - I can use your lib to get the necessary token.

    Now, google-apis-rs targets scopes one-by-one, for every call it makes. Which means that TokenStorage in yup-auth2 can't find them as it uses hashing of token scopes.

    I would like to inquire if there is any particular reason this method is used and whether a pull request fixing this would make sense.

    opened by andreycizov 8
  • Unable to use programmatic_auth not possible

    Unable to use programmatic_auth not possible

    Using programmatic_auth as auth_uri it failes to generate a correct URL.

    redirect_uri and response_type aren't allowed but they get added using FlowType::InstalledInteractive.

    Google says Parameter not allowed for this message type: redirect_uri and Parameter not allowed for this message type: response_type

    also the scopes need to be devided by a + instead of spaces.

    After that it would be nice to get the code which is in the cookie "oauth_token".

    This is needed for generating the correct token for using the hangouts chat api (see hangups). Idea is to do automatic logins/auths. 100% from CLI

    Did I miss something?

    opened by MTRNord 8
  • Custom redirect URI

    Custom redirect URI

    Hi @dermesser is there an example on how to add a custom redirect URI? I'm using the example from the custom flow and I realized that the token never gets to the URI, because of the HTTPredirect method.

    opened by hannydevelop 1
  • Add user authentication to the ADC flow.

    Add user authentication to the ADC flow.

    According to google's docs [1], the ADC strategy is

    1. env variable
    2. user credentials
    3. metadata server

    Currently, this crate does 1 and 3; this PR inserts 2 in there.

    [1] https://cloud.google.com/docs/authentication/application-default-credentials

    Note that this is a breaking change, and it also breaks the test for me locally because I have user credentials configured. Presumably the CI doesn't so I guess they'll succeed there? But this isn't great so I've marked it as a draft.

    opened by jneem 2
  • Can we make the structs JSONToken & JSONTokens Public?

    Can we make the structs JSONToken & JSONTokens Public?

    I was wondering if there was a reason for why the 2 structs and their methods, e.g. load_from_file, are not public?

    https://github.com/dermesser/yup-oauth2/blob/78b79cf92cf71fd183fbe07fb44a2f29529a49b0/src/storage.rs#L185-L351

    Because, from the way I read the code, I could reuse it to write my own TokenStorage implementation and keep the same json-token-format as the one used by this library without having to re-implement the code

    https://github.com/dermesser/yup-oauth2/blob/78b79cf92cf71fd183fbe07fb44a2f29529a49b0/src/storage.rs#L116-L124

    Is there something I am missing or not understanding?

    opened by dvaerum 2
  • Is there a way to stub authenticators?

    Is there a way to stub authenticators?

    I've been poking around trying to write a local emulator testing scheme for some code against the firestore and pubsub emulators. As others have seen in google-apis-rs (https://github.com/Byron/google-apis-rs/discussions/313) authenticators are a required part of the structure.

    From what I can see https://github.com/dermesser/yup-oauth2/blob/dcc35ac2e027c66bd1f5dfc192dfdaa68d17f364/src/authenticator.rs#L688-L694 has a fixed set of authentication flows and no trait that I could implement and allow for some sort of "EmptyAuthFlow" to be passed in.

    Is there any mechanism I'm missing where I could pass an authentication flow that doesn't actually request anything from a server or is it something where upstream should be allowing a "no authentication" flow and bypassing yup-oauth?

    opened by emarcotte 3
  • The DefaultHyperClient does not support http - Issue with metadata server authentication

    The DefaultHyperClient does not support http - Issue with metadata server authentication

    When using the InstanceMetadata authentication, the default hyper client only enforces https, and the call to the metadata server fails (returning the following error: Token retrieval failed with error: error trying to connect: Unsupported scheme http)

    My current solution is to simply create a custom client as seen below:

        match yup_oauth2::ApplicationDefaultCredentialsAuthenticator::with_client(
            opts,
            hyper::Client::builder().build(
                hyper_rustls::HttpsConnectorBuilder::new()
                    .with_native_roots()
                    .https_or_http()
                    .enable_http1()
                    .enable_http2()
                    .build(),
            ),
        )
        .await
        {
            yup_oauth2::authenticator::ApplicationDefaultCredentialsTypes::InstanceMetadata(
                auth_builder,
            ) => {
                Ok(auth_builder.build().unwrap())
            }
            yup_oauth2::authenticator::ApplicationDefaultCredentialsTypes::ServiceAccount(auth_builder) => {
                Ok(auth_builder.build().await.unwrap())
                }
        }
    
    opened by pseguin2011 1
  • optional rustls

    optional rustls

    Would it be possible to make rustls an optional dependency? I'm not sure how to get around a couple of security warnings for ring https://github.com/briansmith/ring/issues/1463, which is used by rustls.

    It looks like the only direct dependency is in service_account.rs:

    https://github.com/dermesser/yup-oauth2/blob/ac0e5f606a9506ad6792ef3991ae6f1f8ed408b4/src/service_account.rs#L20-L25

    That was written long before pks8 library started. May be it can be used instead of rustls directly. https://docs.rs/pkcs8/

    Does that conceptually make sense?

    opened by cataggar 3
Owner
Lewin Bormann
Site-Reliability-Engineer-on-the-loose / Physicist-in-training
Lewin Bormann
A OAuth2 server library, for use in combination with actix or other frontends, featuring a set of configurable and pluggable backends.

oxide-auth A OAuth2 server library, for use in combination with common web servers, featuring a set of configurable and pluggable backends. About oxid

null 471 Dec 29, 2022
vault client using jwt authentication that define environment variables from vault secrets before executing into something else

envlt envlt, like env, allows you to define environment variables and then execute into something else, but instead of static values, it uses using si

Eric Burghard 6 Nov 13, 2022
OpenSK is an open-source implementation for security keys written in Rust that supports both FIDO U2F and FIDO2 standards.

OpenSK This repository contains a Rust implementation of a FIDO2 authenticator. We developed this as a Tock OS application and it has been successfull

Google 2.4k Jan 2, 2023
An implementation for an authentication API for Rocket applications.

rocket_auth rocket_auth provides a ready-to-use backend agnostic API for authentication management. For more information visit the documentation at ht

null 62 Dec 19, 2022
A paseto implementation in rust.

Paseto Rust Paseto is everything you love about JOSE (JWT, JWE, JWS) without any of the many design deficits that plague the JOSE standards. This is d

Instructure, Inc. 145 Nov 7, 2022
An implementation of webauthn components for Rustlang servers

Webauthn-rs Webauthn is a modern approach to hardware based authentication, consisting of a user with an authenticator device, a browser or client tha

Kanidm 232 Jan 8, 2023
A minimal jwt implementation for OIDC

Compact JWT Json Web Tokens (JWT) are a popular method for creating signed transparent tokens that can be verified by clients and servers. They are en

Kanidm 4 Dec 29, 2021
ROCCA cipher implementation for Rust.

ROCCA for Rust This is a Rust implementation of the ROCCA authenticated cipher, ported from the Zig implementation. ROCCA is key committing, has a 256

Frank Denis 6 Sep 30, 2022
RSA implementation in pure Rust

RSA A portable RSA implementation in pure Rust. ⚠️ WARNING: This crate has been audited by a 3rd party, but a full blog post with the results and the

Rust Crypto 346 Jan 4, 2023
WebCipher - JWT encryption/decryption algorithms + a JWK Store implementation

webcipher provides JWT authentication utilities and storage mechanism for caching keys and optimizing decryption/encryption processes.

Wavy 1 May 1, 2022
SD-JWT Rust Reference Implementation

SD-JWT Rust Reference Implementation This is the reference implementation of the IETF SD-JWT specification written in Rust. Supported version: 6. Note

OpenWallet Foundation Labs 4 Dec 19, 2023
Rust library for HTTP authentication. Parses challenge lists, responds to Basic and Digest challenges. Likely to be extended with server support and additional auth schemes.

Rust library for HTTP authentication. Parses challenge lists, responds to Basic and Digest challenges. Likely to be extended with server support and a

Scott Lamb 3 Jun 10, 2022
Highly flexible library to manage and orchestrate JWT workflow

JWT Vault Highly flexible library to manage and orchestrate JWT workflow Examples | Website | Chat TODO Add more examples Improve coverage Features Ma

Saurav Gupta 65 Nov 8, 2022
Fast, simple and REST compliant file-server with public/private key authentication written in Rust

stormi Stormi is a fast and simple file-server with public/private key authentication How does it work? Stormi accepts multipart/form-data form with m

Polygon 2 Dec 8, 2022
Decode, explore, and sign JWTs

JWT Explorer A utility for inspecting, modifying, and attacking JWTs. Supports Windows and Linux and probably also works on macOS but this has not bee

David Young 9 Nov 9, 2022
Simple backend app with Actix-web, JWT and MongoDB

Actix Web JWT Example Simple backend app with Actix-web, JWT and MongoDB (JWT Token, Protect Route, Login & Register) While developing the web service

Emre 124 Dec 31, 2022
Tools for manipulating JSON Web Tokens, JWS, JWE, and JWK in Rust

Rusty JWT Tools A collection of JWT utilities. This repository is part of the source code of Wire. You can find more information at wire.com or by con

Wire Swiss GmbH 4 Nov 22, 2022
A set of Rust libraries to interact with apple's private APIs and servers.

apple-private-apis A set of Rust libraries to interact with apple's private APIs and servers, made for use in SideInstaller. Library Description omnis

SideStore Team 4 Jan 25, 2023
Simple crate to login to Pinterest and get the cookies via Chromiumoxide to simulate a browser

Simple crate to login to Pinterest and get the cookies via Chromiumoxide to simulate a browser (open a real browser actually), to use the Pinterest API without needing a developer account or an API key or anything that costs money :).

Anas 3 Oct 5, 2023