JWT lib in rust

Overview

jsonwebtoken

Build Status

API documentation on docs.rs

See JSON Web Tokens for more information on what JSON Web Tokens are.

Installation

Add the following to Cargo.toml:

jsonwebtoken = "7"
serde = {version = "1.0", features = ["derive"] }

The minimum required Rust version is 1.40.

Algorithms

This library currently supports the following:

  • HS256
  • HS384
  • HS512
  • RS256
  • RS384
  • RS512
  • PS256
  • PS384
  • PS512
  • ES256
  • ES384

How to use

Complete examples are available in the examples directory: a basic one and one with a custom header.

In terms of imports and structs:

use serde::{Serialize, Deserialize};
use jsonwebtoken::{encode, decode, Header, Algorithm, Validation, EncodingKey, DecodingKey};

/// Our claims struct, it needs to derive `Serialize` and/or `Deserialize`
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
    sub: String,
    company: String,
    exp: usize,
}

Claims

The claims fields which can be validated. (see validation)

#[derive(Debug, Serialize, Deserialize)]
struct Claims {
    aud: String,         // Optional. Audience
    exp: usize,          // Required (validate_exp defaults to true in validation). Expiration time (as UTC timestamp)
    iat: usize,          // Optional. Issued at (as UTC timestamp)
    iss: String,         // Optional. Issuer
    nbf: usize,          // Optional. Not Before (as UTC timestamp)
    sub: String,         // Optional. Subject (whom token refers to)
}

Header

The default algorithm is HS256, which uses a shared secret.

let token = encode(&Header::default(), &my_claims, &EncodingKey::from_secret("secret".as_ref()))?;

Custom headers & changing algorithm

All the parameters from the RFC are supported but the default header only has typ and alg set. If you want to set the kid parameter or change the algorithm for example:

let mut header = Header::new(Algorithm::HS512);
header.kid = Some("blabla".to_owned());
let token = encode(&header, &my_claims, &EncodingKey::from_secret("secret".as_ref()))?;

Look at examples/custom_header.rs for a full working example.

Encoding

// HS256
let token = encode(&Header::default(), &my_claims, &EncodingKey::from_secret("secret".as_ref()))?;
// RSA
let token = encode(&Header::new(Algorithm::RS256), &my_claims, &EncodingKey::from_rsa_pem(include_bytes!("privkey.pem"))?)?;

Encoding a JWT takes 3 parameters:

  • a header: the Header struct
  • some claims: your own struct
  • a key/secret

When using HS256, HS2384 or HS512, the key is always a shared secret like in the example above. When using RSA/EC, the key should always be the content of the private key in the PEM or DER format.

If your key is in PEM format, it is better performance wise to generate the EncodingKey once in a lazy_static or something similar and reuse it.

Decoding

// `token` is a struct with 2 fields: `header` and `claims` where `claims` is your own struct.
let token = decode::<Claims>(&token, &DecodingKey::from_secret("secret".as_ref()), &Validation::default())?;

decode can error for a variety of reasons:

  • the token or its signature is invalid
  • the token had invalid base64
  • validation of at least one reserved claim failed

As with encoding, when using HS256, HS2384 or HS512, the key is always a shared secret like in the example above. When using RSA/EC, the key should always be the content of the public key in the PEM or DER format.

In some cases, for example if you don't know the algorithm used or need to grab the kid, you can choose to decode only the header:

let header = decode_header(&token)?;

This does not perform any signature verification or validate the token claims.

You can also decode a token using the public key components of a RSA key in base64 format. The main use-case is for JWK where your public key is in a JSON format like so:

{
   "kty":"RSA",
   "e":"AQAB",
   "kid":"6a7a119f-0876-4f7e-8d0f-bf3ea1391dd8",
   "n":"yRE6rHuNR0QbHO3H3Kt2pOKGVhQqGZXInOduQNxXzuKlvQTLUTv4l4sggh5_CYYi_cvI-SXVT9kPWSKXxJXBXd_4LkvcPuUakBoAkfh-eiFVMh2VrUyWyj3MFl0HTVF9KwRXLAcwkREiS3npThHRyIxuy0ZMeZfxVL5arMhw1SRELB8HoGfG_AtH89BIE9jDBHZ9dLelK9a184zAf8LwoPLxvJb3Il5nncqPcSfKDDodMFBIMc4lQzDKL5gvmiXLXB1AGLm8KBjfE8s3L5xqi-yUod-j8MtvIj812dkS4QMiRVN_by2h3ZY8LYVGrqZXZTcgn2ujn8uKjXLZVD5TdQ"
}
// `token` is a struct with 2 fields: `header` and `claims` where `claims` is your own struct.
let token = decode::<Claims>(&token, &DecodingKey::from_rsa_components(jwk["n"], jwk["e"]), &Validation::new(Algorithm::RS256))?;

If your key is in PEM format, it is better performance wise to generate the DecodingKey once in a lazy_static or something similar and reuse it.

Convert SEC1 private key to PKCS8

jsonwebtoken currently only supports PKCS8 format for private EC keys. If your key has BEGIN EC PRIVATE KEY at the top, this is a SEC1 type and can be converted to PKCS8 like so:

openssl pkcs8 -topk8 -nocrypt -in sec1.pem -out pkcs8.pem

Validation

This library validates automatically the exp claim and nbf is validated if present. You can also validate the sub, iss and aud but those require setting the expected value in the Validation struct.

Since validating time fields is always a bit tricky due to clock skew, you can add some leeway to the iat, exp and nbf validation by setting the leeway field.

Last but not least, you will need to set the algorithm(s) allowed for this token if you are not using HS256.

#[derive(Debug, Clone, PartialEq)]
struct Validation {
    pub leeway: u64,                    // Default: 0
    pub validate_exp: bool,             // Default: true
    pub validate_nbf: bool,             // Default: false
    pub aud: Option<HashSet<String>>,   // Default: None
    pub iss: Option<String>,            // Default: None
    pub sub: Option<String>,            // Default: None
    pub algorithms: Vec<Algorithm>,     // Default: vec![Algorithm::HS256]
}
use jsonwebtoken::{Validation, Algorithm};

// Default validation: the only algo allowed is HS256
let validation = Validation::default();
// Quick way to setup a validation where only the algorithm changes
let validation = Validation::new(Algorithm::HS512);
// Adding some leeway (in seconds) for exp and nbf checks
let mut validation = Validation {leeway: 60, ..Default::default()};
// Checking issuer
let mut validation = Validation {iss: Some("issuer".to_string()), ..Default::default()};
// Setting audience
let mut validation = Validation::default();
validation.set_audience(&"Me"); // string
validation.set_audience(&["Me", "You"]); // array of strings

Look at examples/validation.rs for a full working example.

Comments
  • v7 discussion

    v7 discussion

    There are quite a few changes happening in the PRs: more input format for RSA (#69, #74), ECDSA signing & verification (#73) as well as some Validation changes.

    I have already removed the iat check in the next branch since it isn't something that should be checked.

    Right now, Validation::algorithms is a vec. I don't remember why but it shouldn't be the case, it should be an algorithm: Algorithm instead, I will accept a PR for that or do it myself later.

    #69 also adds a standalone verify_rsa fn, which I'm wondering if we can somehow streamline it with the rest of the crate.

    Since Rust doesn't have default parameters, we always have to pass a Validation struct currently. Maybe we can put the decoding onto this struct instead so you get something like:

    // currently
    let token = decode::<Claims>(&token, "secret".as_ref(), &Validation::default())?;
    
    // possible
    // `JwtDecoder` has the same fields as the current `Validation`
    let token = JwtDecoder::default().decode_hs256::<Claims>(&token, "secret".as_ref())?;
    

    This way we don't have a single function where we are trying to fit all arguments inside and the user has to select explicitely which decode fn to use. This solves the vec of algorithms at the same time and allows having better documentation for each. The downside is duplication of those functions/docs for the various digest values (decode_hs256, decode_hs384, decode_hs512 for each algo).

    Any other ideas/criticisms/things missing?

    ccing the people involved in various issues/PRs recently @AaronFriel @jbg @Jake-Shadle @matthew-nichols-westtel @greglearns

    help wanted question 
    opened by Keats 86
  • The exp claim should be optional

    The exp claim should be optional

    According to the RFC, the exp claim should be optional: https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4

    4.1.4. "exp" (Expiration Time) Claim ... Use of this claim is OPTIONAL.

    I saw that you suggested that the user just set an expiration very far in the future. This works for new tokens, however it doesn't work for tokens created previously (e.g. if you're migrating tokens to a new service).

    opened by cloutiertyler 35
  • Decoding with x509 certs

    Decoding with x509 certs

    I'm having a hard time authenticating a token using a x5c. (MS OAuth/Azure)

    Below is the code...

    // Trying to isolate the problem by only checking the signature. 
    let validation_config = jsonwebtoken::Validation {
                algorithms: vec![jsonwebtoken::Algorithm::RS256],
                leeway: 0,
                validate_exp: false,
                validate_iat: false,
                validate_nbf: false,
                aud: None,
                iss: None,
                sub: None
            };
    let token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIn...";
    let x5c_cert = "MIIDBTCCAe2gAwIBAgIQKOfEJNDyDplBSXKYcM..."; 
    
    let raw_der = base64::decode_config(der, base64::STANDARD).unwrap();
    let d = jsonwebtoken::decode::<MsOAuthPayload>(&token, &raw_der, &validation_config);
    

    The above always returns InvalidSignature.

    • RS265 is the correct algo.
    • The cert is correct. I tried it on jwt.io by adding a BEGIN/END cert and it validates fine.
    • I used ssl to convert the BEGIN/END pem to DER and the bytes match up from the base 64 decode.
    • The key URL is: https://login.microsoftonline.com/common/discovery/v2.0/keys but my specific tenant returns the same keys.

    Anyone have some insight on what I'm doing wrong here?

    Thanks

    opened by gpit2286 34
  • forked. Have features, want to contribute.

    forked. Have features, want to contribute.

    https://github.com/cmsd2/rust-jwt

    As discussed briefly out-of-band, I've been working on some features.

    Off the top of my head, rsa, arbitrary Json payloads like the other jwt libs, claims parsing, serde, jwk keys and sets.

    Can we pool efforts?

    opened by cmsd2 34
  • Add PEM decoding support (#106)

    Add PEM decoding support (#106)

    • Add PEM support with pem and simple_asn1. Documentation TODO

    • Make pkcs1 and pkcs8 versions of the RSA key, confirm they pass tests.

    • Add documentation, simplify

    • Update readme

    • Bump pem version

    • Remove extra print

    opened by Keats 32
  • DecodingKey::from_rsa_components fails when modulus encoded with standard base64 character set

    DecodingKey::from_rsa_components fails when modulus encoded with standard base64 character set

    Hello!

    jsonwebtoken version: 7.2.0 rustc version: rustc 1.47.0 (18bf6b4f0 2020-10-07)

    I have built a token validator for tokens served from AWS Cognito using their JWKS. The validation steps are

    • fetch the JWKs
    • find the appropriate JWK data for the token (decode_header, extract kid, look up corresponding key in JWKs)
    • pass the modulus and exponent to DecodingKey::from_rsa_components
    • validate as usual

    Out of the box, validation fails with a rather obscure Error(Base64(InvalidByte(52, 43))). After digging into it for a while, I discovered that AWS Cognito JWKs are using the standard base64 character set, which trips up the b64_decode wrapper.

    Here is a test case that demonstrates the same issue using the PKCS8 keypair in the test suite:

    #[test]
    fn rsa_modulus_exponent_standard_charset() {
        let privkey_pem = include_bytes!("private_rsa_key_pkcs8.pem");
    
        // modulus encoded as base64 from public_rsa_key_pkcs8.pem
        // $ openssl rsa -pubin -in public_rsa_key_pkcs8.pem -text -noout | egrep '^    ' | xxd -r -p | base64 | tr -d '\n'
        let n = "AMkROqx7jUdEGxztx9yrdqTihlYUKhmVyJznbkDcV87ipb0Ey1E7+JeLIIIefwmGIv3LyPkl1U/ZD1kil8SVwV3f+C5L3D7lGpAaAJH4fnohVTIdla1Mlso9zBZdB01RfSsEVywHMJERIkt56U4R0ciMbstGTHmX8VS+WqzIcNUkRCwfB6BnxvwLR/PQSBPYwwR2fXS3pSvWtfOMwH/C8KDy8byW9yJeZ53Kj3Enygw6HTBQSDHOJUMwyi+YL5oly1wdQBi5vCgY3xPLNy+caovslKHfo/DLbyI/NdnZEuEDIkVTf28tod2WPC2FRq6mV2U3IJ9ro5/Lio1y2VQ+U3U=";
    
        // $ openssl rsa -pubin -in public_rsa_key_pkcs8.pem -text -noout | awk '/Exponent/ { printf "0x%06x",$2 }' | xxd -r -p | base64
        let e = "AQAB";
    
        // transcoding the modulus into the URL safe charset allows the test to pass
        // let n = "AMkROqx7jUdEGxztx9yrdqTihlYUKhmVyJznbkDcV87ipb0Ey1E7-JeLIIIefwmGIv3LyPkl1U_ZD1kil8SVwV3f-C5L3D7lGpAaAJH4fnohVTIdla1Mlso9zBZdB01RfSsEVywHMJERIkt56U4R0ciMbstGTHmX8VS-WqzIcNUkRCwfB6BnxvwLR_PQSBPYwwR2fXS3pSvWtfOMwH_C8KDy8byW9yJeZ53Kj3Enygw6HTBQSDHOJUMwyi-YL5oly1wdQBi5vCgY3xPLNy-caovslKHfo_DLbyI_NdnZEuEDIkVTf28tod2WPC2FRq6mV2U3IJ9ro5_Lio1y2VQ-U3U=";
    
        let my_claims = Claims {
            sub: "[email protected]".to_string(),
            company: "ACME".to_string(),
            exp: Utc::now().timestamp() + 10000,
        };
    
        for &alg in RSA_ALGORITHMS {
            let token =
                encode(&Header::new(alg), &my_claims, &EncodingKey::from_rsa_pem(privkey_pem).unwrap())
                    .unwrap();
    
            let token_data = decode::<Claims>(
                &token,
                &DecodingKey::from_rsa_components(n, e),
                &Validation::new(alg),
            )
            .unwrap();
    
            assert_eq!(my_claims, token_data.claims);
            assert!(token_data.header.kid.is_none());
        }
    }
    

    Test output:

    $ cargo test
       Compiling jsonwebtoken v7.2.0 (/home/drocco/source/sandbox/rust/jsonwebtoken)
        Finished test [unoptimized + debuginfo] target(s) in 1.19s
         Running target/debug/deps/jsonwebtoken-a8164d7fdb367e8b
    ...
    failures:
    
    ---- rsa::rsa_modulus_exponent_standard_charset stdout ----
    thread 'rsa::rsa_modulus_exponent_standard_charset' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Base64(InvalidByte(52, 43)))', tests/rsa/mod.rs:173:10
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    
    failures:
        rsa::rsa_modulus_exponent_standard_charset
    
    test result: FAILED. 10 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
    
    error: test failed, to rerun pass '--test lib'
    

    Environment:

    $ rustup show
    Default host: x86_64-unknown-linux-gnu
    rustup home:  /home/drocco/.rustup
    
    installed toolchains
    --------------------
    
    stable-x86_64-unknown-linux-gnu (default)
    nightly-x86_64-unknown-linux-gnu
    
    active toolchain
    ----------------
    
    stable-x86_64-unknown-linux-gnu (default)
    rustc 1.47.0 (18bf6b4f0 2020-10-07)
    
    
    opened by drocco007 18
  • DecodingKey is difficult to re-use

    DecodingKey is difficult to re-use

    impl<'a> DecodingKey<'a> {
        pub fn from_rsa_pem(key: &'a [u8]) -> Result<Self> {
            let pem_key = PemEncodedKey::new(key)?;
            let content = pem_key.as_rsa_key()?;
            Ok(DecodingKey {
                family: AlgorithmFamily::Rsa,
                kind: DecodingKeyKind::SecretOrDer(Cow::Owned(content.to_vec())),
            })
        }
    }
    

    This constructs a DecodingKey that owns all of its state, but the signature suggests that it borrows the input key. As a result, the only way to construct a DecodingKey<'static> for lazy_static or once_cell is to leak the input key (or unsafely transmute the lifetime of the input key and hope that DecodingKey never changes its implementation to actually.borrow the input).

    opened by tjwilson90 18
  • Fix Broken chrono Example

    Fix Broken chrono Example

    Hi,

    the provided example for custom chrono headers (https://github.com/Keats/jsonwebtoken/blob/master/examples/custom_chrono.rs) does not work, if the chrono timestamp contains milliseconds. I discovered this when implementing a test property for myself that ensured, encoding and decoding results in the identity.

    One if my failures looked like this:

    [src/auth.rs:131] cookie = DeviceCookie { 
        sub: "\u{0}",                                                                    
        nonce: "\u{0}",                       
        exp: 2020-04-22T13:42:23.284112768Z,                                             
    }                                    
    [src/auth.rs:131] parsed = DeviceCookie {                                            
        sub: "\u{0}",                                                                    
        nonce: "\u{0}",                                                                  
        exp: 2020-04-22T13:42:23Z,     
    }
    

    As you can see, cookie (the identity) has milliseconds set but since the serializer in the example serializes only the timestamp to the second, the milliseconds get lost and the tokens are no longer the same.

    I updated the example to use Utc::timestamp_nanos for serializing and deserializing. This solves the issue. I also added a slightly modified version of my test property to the example to ensure, that everythink works as intended.

    I also fixed the existing tests since the example didn't compile and after fixing it and running cargo test --example=custom_chrono, the round_trip test fails:

    test jwt_numeric_date::tests::round_trip ... FAILED
    test jwt_numeric_date::tests::should_fail_on_invalid_timestamp ... ok
    test jwt_numeric_date::tests::to_token_and_parse_equals_identity ... ok
    
    failures:
    
    ---- jwt_numeric_date::tests::round_trip stdout ----
    thread 'jwt_numeric_date::tests::round_trip' panicked at 'attempt to multiply with overflow', /home/me/.cargo/registry/src/github.com-1ecc6299db9ec823/chrono-0.4.11/src/naive/datetime.rs:342:21
    

    Running the tests in release mode (cargo test --release --example=custom_chrono) works fine since the overflow checks are disabled for release builds.

    Adding the following to Cargo.toml would solve the problem, too, but I don't know if you want this.

    [profile.test]
    overflow-checks = false
    

    After disabling overflow checks for tests and running the test again, it fails with an assertion error:

    thread 'jwt_numeric_date::tests::round_trip' panicked at 'assertion failed: `(left == right)`
      left: `"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJDdXN0b20gRGF0ZVRpbWUgc2VyL2RlIiwiaWF0IjowLCJleHAiOi00Mzg5ODA4MTQ3NDE5MTAzMjMyfQ.P2cnrIjFilrosSMBZeI5KaNDZxkxVir8l_cpvZbAP30"`,
     right: `"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJDdXN0b20gRGF0ZVRpbWUgc2VyL2RlIiwiaWF0IjowLCJleHAiOjMyNTAzNjgwMDAwfQ.RTgha0S53MjPC2pMA4e2oMzaBxSY3DMjiYR2qFfV55A"`', examples/custom_chrono.rs:63:13
    

    I'm not quite sure, what to to with this test...

    opened by vbrandl 15
  • failed to encode: Error(InvalidRsaKey)

    failed to encode: Error(InvalidRsaKey)

    I get this error when trying to encode() with RS256:

    thread 'main' panicked at 'failed to encode(): Error(InvalidRsaKey)', src/main.rs:240:21`
    

    Here's my line of code that uses encode() and it straight out of the /examples:

        let token = match encode(&Header::new(Algorithm::RS256), &set_jwt_payload(options.clone()), &private_key) {
            Ok(t) => t,
            Err(err) => panic!("failed to encode(): {:?}", err), // in practice you would return the error
        };
    

    But when I use &Header::default() for encode's header parameter, it works fine. I'm using this function to convert a KEY to the DER format:

    • https://github.com/cfsamson/azure-jwt/blob/c3d6239fed10b23e834f0e9f0cb0ae39618c4118/src/lib.rs#L636

    Thank you for any insights.

    opened by mikeumus 15
  • Add some verifications of fields

    Add some verifications of fields

    exp and nbf could be added (see https://tools.ietf.org/html/rfc7519#section-4.1.1 for details on those fields).

    The tricky thing without default args is how to handle the leeway. It seems the decode fn will need a struct of all the possible options, which means we could add verification for more fields that way

    opened by Keats 14
  • Support more header parameters

    Support more header parameters

    This adds support for the crit header parameter (RFC 7515), and additional header parameters via a params map.

    I added logic for the crit header to check for invalid uses. Applications must do additional checking of crit to ensure they can understand any listed parameters.

    To make the params map work, I removed Hash from the derive attribute of the Header struct. If this is a problem, I could try to find an alternative solution.

    I added tests for the crit parameter checking and to show use of the params map flattened into the header struct.

    opened by clehner 12
  • Does adding from_rsa_components() for EncodingKey make sense?

    Does adding from_rsa_components() for EncodingKey make sense?

    I'm presently using the rsa crate and creating a private/public key pair, then creating an EncodingKey from that. For now, it seems that I must convert the private key to a PEM encoded string and then create EncodingKey from that. I would like to skip that step if I may. I took a brief look at the code and it seems that DecodingKey and EncodingKey are built up differently, so it's not obvious to me if adding an from_rsa_components() to EncodingKey is a good idea or not. But it sure would be convenient. If you have any suggestions, I can give it a try myself and submit a PR.

    opened by nlfiedler 1
  • Problem with dependency time

    Problem with dependency time

    Hello @Keats
    I have a problem with dependency: error: failed to select a version for the requirement time = "=0.3.17" How to fix it?

    Cargo.toml:

    [package]
    name = "jwt_tests"
    version = "0.1.0"
    edition = "2018"
    
    [dependencies]
    jsonwebtoken = "8"
    serde = {version = "1.0", features = ["derive"] }
    

    My compiler: rust 1.54 (required by yocto).

    log:

    $ cargo +1.54 b
        Updating crates.io index
    error: failed to select a version for the requirement `time = "=0.3.17"`
    candidate versions found which didn't match: 0.3.15, 0.3.14, 0.3.13, ...
    location searched: crates.io index
    required by package `simple_asn1 v0.6.2`
        ... which is depended on by `jsonwebtoken v8.2.0`
        ... which is depended on by `speedy_tests v0.1.0 (/home/mhanusek/work/code/rnd/jwt_tests)`
    
    opened by hanusek 0
  • Would it be possible to make DecodingKey more test friendly?

    Would it be possible to make DecodingKey more test friendly?

    Currently DecodingKey::as_bytes is crate public which means you can't even get the secret out of the DecodingKey that you originally put in.

    Additionally it does not implement Debug or PartialEq so once you create a DecodingKey you cannot compare for testing purposes ever. This is really a pain point if you're trying to test your decoding logic to support many algorithms and keys using JWK as well as static secrets.

    DecodingKey should really implement the std::cmp::PartialEq interface at the very least.

    A similar issue exists with Algorithm where you have to resort to matching in order to implement Debug on types using it. Ideally the library would handle this case as well converting Algorithm back to a string.

    opened by tkrause 2
  • Fixed decoding of token when validation has multiple families of algorithms

    Fixed decoding of token when validation has multiple families of algorithms

    Currently if you have

            let mut validation = Validation::default();
            validation.algorithms = vec![
                Algorithm::HS256,
                Algorithm::HS384,
                Algorithm::HS512,
                Algorithm::RS256,
                Algorithm::RS384,
                Algorithm::RS512,
            ];
    

    and try to validate a RS256 signed token, you will get a Error::InvalidAlgorithm due to the section:

            for alg in &validation.algorithms {
                if key.family != alg.family() {
                    return Err(new_error(ErrorKind::InvalidAlgorithm));
                }
            }
    

    This section should check whether the key is one of the accepted families. Currently it checks if an algorithm is accepted with a different family, and if so rejects the key.

    opened by Wassasin 1
Owner
Vincent Prouillet
Vincent Prouillet
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
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
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
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
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
Example application using a Vue frontend with Rust backend that has authentication + authorization.

This project contains a Rust server that serves a single page application and has authentication + JWT-based authorization.

null 43 Dec 9, 2022
Authorization Server with Rust using Tonic

authorization-server Authorization Server with Rust using Tonic. Function implemented User registration and profile store Change password Login Token

sora 3 Oct 5, 2021
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
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
Extensible, strongly-typed Rust OAuth2 client library

OAuth2 An extensible, strongly-typed implementation of OAuth2 (RFC 6749). Documentation is available on docs.rs. Release notes are available on GitHub

David Ramos 602 Dec 25, 2022
An auth system/library for Rust applications

Rust : Forbidden (WIP) An experimental auth library for Rust applications. Goals This crate is to define a common set of traits and idioms to provide

Mario Montoya 9 Nov 8, 2022
Authenticate to Minecraft using the Microsoft Authentication Scheme from Rust.

Authenticating to Minecraft with the Microsoft Authentication Scheme from Rust This program showcases an implementation of the microsoft authenticatio

ALinuxPerson 17 Dec 22, 2022
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
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
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
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
🔥 Firebase authentication for Rust 🦀

Fire Auth Rust wrapper for Firebase Authentication REST API Installation Add the following to Cargo.toml: fireauth = "0.1.5" How to use First you need

UwU 11 Nov 12, 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
Xbox live authentication flow for Minecraft with Rust.

MC Auth Xbox live authentication flow for Minecraft in Rust. Why? In order to create tools for Minecraft based on rust that implement the user profile

Minecraft Rust 3 Jan 15, 2023