keats / jsonwebtoken Goto Github PK
View Code? Open in Web Editor NEWJWT lib in rust
License: MIT License
JWT lib in rust
License: MIT License
I have a key that is not valid UTF-8. Currently it's possible to encode, but not decode using such a key.
I've been working on a PR that makes decode
take AsRef<[u8]>
(like encode
), but on the way I've found that this breaks decode::<Claims>(..)
usage because of additional type parameters. The other options are:
decode<T: Part>(token: &str, secret: &AsRef<[u8]>, algorithm: ...) -> Result<T, ...>
, no idea why this works???decode::<Claims, _>
if necessary.Hi,
I am looking for some advice with regards to decode and verification of tokens signed with RS256. We seem to be receiving invalid signature
errors when passing in the suggested der
public key format.
For some back story, We currently have remote systems generating and signing these tokens, the JWT token we need to verify is signed remotely by a nodejs process leveraging this library (https://github.com/auth0/node-jsonwebtoken). Much of the implementation details with regards to signing are fairly typical, but I have some uncertainty with regards to converting and passing the .der
format to your library.
For some information on the RSA signing, as well as the public key conversion and some example implementation, I submit the following info.
# generates private.pem
ssh-keygen -t rsa -b 2048 -f private.pem -N ''
# generates public.pem
openssl rsa -in private.pem -pubout -outform PEM -out public.pem
which are then converted to the .der
format with the following.
openssl rsa -pubin -in public.pem -outform DER -out public.der
fn load_key(filename: &str) -> Vec<u8> {
let mut buffer = Vec::<u8>::new();
let mut file = File::open(filename).unwrap();
file.read_to_end(&mut buffer).unwrap();
buffer
}
fn main() {
let encoded = "<encoded jwt string>";
// this works fine, suggesting the token is correct.
let decoded = dangerous_unsafe_decode::<Claims>(&encoded).unwrap();
// seems to fail with "invalid signature".
let public_key = load_key("./public.der");
let validation = Validation::new(Algorithm::RS256);
let decoded = decode::<Claims>(&encoded, &public_key, &validation).unwrap();
}
Any assistance you could provide would be hugely appreciated.
Regards
S
This header works:
{
"alg": "HS256",
"typ": "JWT"
}
This doesn't:
{
"typ": "JWT",
"alg": "HS256"
}
Version 1.1.5 no longer works because the ring 0.3.1 dependency fails to compile. The latest master with ring 0.6 compiles successfully. Tested on latest nightly.
I'm struggle to encode using a private key in hexadecimal format.
I need to convert library from another language.
The key in hex are like this one a3ed0dd27cbfa62e13e340fb3dbb86895b99d5fd330a80e799baffcb1d29c17a
I've tried to decode, or even encapsulate with other libraries like signatory but I can't make it work.
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?
sccache currently is depending on a patch: #74
Ok so I am trying to use this crate and I keep getting expired signature
when I try and decode my jwt when the client sends it back to me. I have a field in my struct that gets encoded as a jwt called exp
of type usize
and ive set it to 3600
(1 hour) but it just seems to be ignored. Am I doing something wrong and if so, what is the correct way to set the expiration time of the token?
Nevermind, I realized I had to use now + an hour. ๐ closing issue.
I have a known valid token, verified with https://jwt.io/. Yet, no matter what I do jsonwebtoken declares InvalidSignature
. Here's an example:
fn main() {
let token = "eyJ0e...available privately on request......hbQQ";
let pem = "-----BEGIN CERTIFICATE-----
MIIC/TCCAeWgAwIBAgIJIayPWv6q6acCMA0GCSqGSIb3DQEBCwUAMBwxGjAYBgNV
BAMTEW51dmVtZnMuYXV0aDAuY29tMB4XDTE5MDEyMTAxMTEyNloXDTMyMDkyOTAx
MTEyNlowHDEaMBgGA1UEAxMRbnV2ZW1mcy5hdXRoMC5jb20wggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCvsckLZecpNoAx1nsJRo2h1WyEb2Kc7Guard/j
pxxD7QMjCdOPGtWdoAq2yqKceKGhhojgqFMCBhx/eqeScaAl2Kvf59cl7JWxDVJ+
n9givgQVPy5ZczvimZZMQCwr8F7/IJ2kkTdVR0ytNclVGZqmxzrSiTIev0Hlf09W
JaQipRNI5Yv7yCYv1/P6xXozmdtmO0yjjNEXCY/+T36n8S72XUkX6VfKx09ZkLbT
y9gxyg9X7idnr2Jg93m9RmyO8xay1vQBZxkxM4kKYOlLOGpoulolALfgkf9cR09G
zojQxuBKfROCYVLfHMsN3IiNSs1J40/iPea1r+ZsDiTPrbZdAgMBAAGjQjBAMA8G
A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEBuuLqv76vx3TZ7DIe/Y3pk6MjTMA4G
A1UdDwEB/wQEAwIChDANBgkqhkiG9w0BAQsFAAOCAQEAq3fyyi8Sl92P54gIxOhV
Q5OXet4bhETaW792XgMWhfcG/ppbZwT1krWflDps9BzSfNI7WpPAdreYk+hKSuCu
oNVU0imgha+1SKwxcRbW6Gx9XTn7aTIqP7xxk5uRLO79O5Dhy0d/1YVHpJJK2lKZ
Ridu3W1hbBvXPWgtl4jgYPYmoUcFH/jv0PP4H1ka7rnV6JLtqEBB1naSfYhA3U9s
3VvcS03EPDZIoiNzsiPu4qepVbf/mprxFEztR9HCqHGE+1oBxmt+wjfVRgIDGHcY
rWr2f6rC/AfuqOsPayb4SLQIFujxqJ0nwy3CUrlAlfQvYOnrkMQoccj2nklY86kl
Gw==
-----END CERTIFICATE-----";
let der = openssl::x509::X509::from_pem(pem.as_bytes())
.unwrap()
.to_der()
.unwrap();
let decoded = jsonwebtoken::decode::<AccessToken>(
token,
&der,
&jsonwebtoken::Validation {
algorithms: vec![jsonwebtoken::Algorithm::RS256],
..Default::default()
},
);
println!("{:?}", decoded)
}
No matter what jsonwebtoken returns Err(Error(InvalidSignature))
. The payload looks like:
{
"https://hasura.io/jwt/claims": {
"x-hasura-default-role": "user",
"x-hasura-allowed-roles": [
"user"
],
"x-hasura-user-id": "......."
},
"iss": "https://nuvemfs.auth0.com/",
"sub": "google-oauth2|.......",
"aud": [
"https://nuvenmfs/api",
"https://nuvemfs.auth0.com/userinfo"
],
"iat": 1552895641,
"exp": 1552982041,
"azp": "......",
"scope": "openid profile email offline_access"
}
main.rs
extern crate jsonwebtoken;
#[macro_use]
extern crate serde_derive;
extern crate serde;
use jsonwebtoken::{decode, encode, Header, Validation};
#[derive(Debug, Serialize, Deserialize)]
struct Meta {
id: i32,
}
fn main() {
let v = Validation {
leeway: 5,
validate_exp: true,
iss: Some("iss no check".to_string()),
sub: Some("sub no check".to_string()),
..Validation::default()
};
let meta = Meta { id: 32 };
let token = encode(&Header::default(), &meta, "secret".as_ref()).unwrap();
println!("{:#?}", v);
println!("{:}", token);
if let Ok(new_meta) = decode::<Meta>(&token, "secret".as_ref(), &v) {
println!("{}", "succed");
println!("{:?}", new_meta);
} else {
println!("{}", "failed");
}
}
output
Validation {
leeway: 5,
validate_exp: true,
validate_iat: true,
validate_nbf: true,
aud: None,
iss: Some(
"iss no check"
),
sub: Some(
"sub no check"
),
algorithms: [
HS256
]
}
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MzJ9.BtzaL8AzJJtMOqPWZM2sSmOfTSje5osCILeWGEpWqBA
{
"id": Number(
32
)
}
Validation {
leeway: 5,
validate_exp: true,
validate_iat: true,
validate_nbf: true,
aud: None,
iss: Some(
"iss no check"
),
sub: Some(
"sub no check"
),
algorithms: [
HS256
]
}
succed
TokenData { header: Header { typ: Some("JWT"), alg: HS256, cty: None, jku: None, kid: None, x5u: None, x5t: None }, claims: Meta { id: 32 } }
From https://github.com/Keats/jsonwebtoken/blob/master/src/validation.rs#L121-L147
if let Some(exp) = claims.get("exp") {
if options.validate_exp && from_value::<i64>(exp.clone())? < now - options.leeway {
return Err(ErrorKind::ExpiredSignature.into());
}
}
if let Some(nbf) = claims.get("nbf") {
if options.validate_nbf && from_value::<i64>(nbf.clone())? > now + options.leeway {
return Err(ErrorKind::ImmatureSignature.into());
}
}
if let Some(iss) = claims.get("iss") {
if let Some(ref correct_iss) = options.iss {
if from_value::<String>(iss.clone())? != *correct_iss {
return Err(ErrorKind::InvalidIssuer.into());
}
}
}
if let Some(sub) = claims.get("sub") {
if let Some(ref correct_sub) = options.sub {
if from_value::<String>(sub.clone())? != *correct_sub {
return Err(ErrorKind::InvalidSubject.into());
}
}
}
Should check options.validate_exp
then echeck claims.get("exp")
, the others are probably the same.
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
Please specify that in the test folder, the correct public key for private_rsa_key.pem
is public_rsa_key_8.pem
and not public_rsa_key.pem
. Looking at the tests where the *.der
files are one would assume that it's public_rsa_key.pem
that is the correct one but I only got the test token verified by using public_rsa_key_8.pem
and thought there was something wrong in my base64
to bytearray conversion :)
The listing for jsonwebtoken on https://jwt.io/#libraries-io seems to be outdated, e.g. it claims you don't support exp
checking. You can submit a PR to update it at their repo:
https://github.com/jsonwebtoken/jsonwebtoken.github.io/blob/master/views/website/libraries/13-Rust.json#L38-L68
trying to use this with auth0, where its only possible to get the x509 certificate that is used for signing
openssl x509 -in auth0.pem -outform DER -out auth0.der
doesnt seem to work. i'm getting ' Error(InvalidSignature)'.
the same token validates fine on jwt.io with that certificate.
@Keats I think that the Validation type's aud field and the aud validation logic requires reconsideration.
The Validation
type should use aud: Option<String>
, not Option<Value>
. The jwt spec states that aud can be one or more strings, and this remains true for the aud claim within a jwt. However, this rule does not apply to the Validation config's aud field. The Validation aud field is a name (who am I -- a service named "one"). This name is used to check audience membership with the jwt's aud claim.
Suppose a token server creates a subject a new token that is valid for use with server's "one" and "two". One way to accomplish this is by setting the aud claim within the jwt to ["one", "two"].
Consider server "one" registers its name, "one", for the aud field within its Validation config (directly, without the need for set_audience). When it authenticates a request that contains a jwt token where the aud claim is ["one", "two"], server "one" ought to consider this token valid because "one" is a member of the intended audience. Further, server "two" ought to validate the same, assuming it registered "two" within its Validation config. Yet, the current validation logic does not take this into consideration. The current validation logic is all-or-nothing. What I propose instead is a check for audience membership.
The jwt spec seems to require the use of a serde_json::Value type for the claim's aud field so as to consider String or Vec. Consequently, the new aud validation logic will need to convert to compatible types that can then check Validation.aud for membership.
Does this make sense? Do you agree? I can submit a PR for this, if so.
Essentially the following, and open to ideas as to how to optimize this further:
use serde_json::{from_value, to_value, Value};
fn validate_aud_claim(from_config: String, from_jwt: Value) -> Result<(), &'static str>{
let aud_from_claim: Vec<String> = match from_jwt.is_array() {
true => from_value(from_jwt).unwrap(),
false => match from_jwt.is_string() {
true => vec![from_jwt.to_string()],
false => panic!("invalid aud type") // change to Error..
}
};
if aud_from_claim.iter().any(|val| *val == from_config){
Ok(())
} else {
Err("error")
}
}
fn main() {
let from_config = "two".to_string();
let from_claim = to_value(vec!["one", "two"]).unwrap();
let result = validate_aud_claim(from_config, from_claim);
dbg!(result);
let from_config = "one".to_string();
let from_claim = to_value("three").unwrap();
let result = validate_aud_claim(from_config, from_claim);
dbg!(result);
}
I'm making a library that extends jwt and adds some extra validation to the claims, and have run into a problem. Since I'd like the user of my library to define their Claims
struct, I don't want to provide the type, but I'd like to perform some validation on it nonetheless.
// My validate function:
pub fn validate<T: DeserializeOwned>(token: &str, key: &[u8], validation: &Validation) -> Result<TokenData<T>, Error> {
let token_data = decode::<T>(&token, "secret".as_ref(), &Validation::default())?;
// HERE: I need to perform some validation on the claims.
// Some fields will be marked as mandatory, etc...
token_data.claims_map.get("iss").expect("No `iss` claim found");
Ok(token_data)
}
I'd like a way to receive the Map<String, Value>
found here so that I can perform some checks on the payload before returning it to the user. Unfortunately, I can't rely on the user's custom T
struct since that may not have the claims the library will need to validate.
Could we consider adding another field to the TokenData
struct which includes the Map<String, Value>
struct as well?
Hey! I've gotten a new issue on my cli tool (mike-engel/jwt-cli#4) which was fixed in 3.0 with typ
being optional. 3.0 did, however, break one use case of my tool which is to just see the contents of a JWT without verifying the signature (debugging, etc). I used to use the validate_signature
option in Validation
, which was removed in 3.0.
Would you be open to having a separate method to just decode a token without verification? I looked through a couple of issues and didn't see the reason for removing validate_signature
, but I'm sure there was one.
Thanks!
Looking at https://github.com/Keats/jsonwebtoken/blob/master/src/validation.rs#L128
It seems odd that if exp
is not in the token validation fails. Otherwise exp
-less tokens insta-fail with Validator::default()
.
I'd vote for changing this so that its not an error if exp is asked to be validated and exp is not present.
I have a rust service that needs to verify JWTs from 3rd-party services that I do not control. The 3rd party service (Portier, in this case) supplies the RSA public components (n
modulus, and e
exponent). Given that jsonwebtoken can only read DER encoded keys
and that I cannot manually run the recommended command-line options for OpenSSL, what is the recommended way of being able to decode a JWT using JsonWebToken in a rust service?
Currently, I have been able to get an ssh public key from the rsa components (n, e) https://github.com/coreos/openssh-keys/blob/master/src/lib.rs#L363 but that seems like a dead end since a public ssh key doesn't seem to be easily converted to DER.
Any ideas?
That requires changing the serialization
file as well for lifetimes
Although the standard requires it, not all jwt providers are standards compliant. It would be nice if this lib was more tolerant of the missing field.
error: multiple packages link to native library `ring-asm`, but a native library can be linked only once
package `ring v0.11.0`
... which is depended on by `cookie v0.9.2`
... which is depended on by `rocket v0.3.14`
... which is depended on by `rocket_contrib v0.3.14`
... which is depended on by `xxx v0.1.0 (file:///home/xx/xx)`
links to native library `ring-asm`
package `ring v0.12.1`
... which is depended on by `jsonwebtoken v4.0.1`
... which is depended on by `xxx v0.1.0 (file:///home/xx/xx)`
also links to native library `ring-asm`
I know this is not the responsibility of jsonwebtoken, but this should be left open until resolved since rocket is a well known framework.
v2.0.3
is compatible
I'm thinking of trying to implement the ACME protocol (e.g. LetsEncrypt), which requires JWS. Would you consider splitting that part of the functionality into a separate library or at least making the appropriate parts public?
Hey there! First off, thanks for making what's shaping up to be a great crate!
I'm new to Rust, and getting my toes wet by building a jwt cli tool. I'd love to contribute back to this project, but I'm not sure where I would be most helpful. Docs? Some easy feature? I'm not sure what you have in progress already so let me know if I can help.
As error-chain is currently deprecated ( rust-lang-deprecated/failure#181 ), I would propose to move to failure which is lots of traction in the rust community.
Hi, i tried to use this library to secure a micro service but i was unable to verify the signature based on the public key from our auth service. I was converting the public key from the PEM into the DER format but without success. I have read the notice in the README and found a related issue but all this suggested is that i have to create the DER file out of the private key
from the auth server. I am not an expert in crypto and i don't really know why this is necessary in your specific case (and why i cannot just build the DER from the public PEM key like openssl rsa -pubin -inform PEM -in public_key.pem -outform DER -out public_key.der
) but isn't this a total deal breaker to require the private key
in an asymmetric crypto schema?
I am not getting the private key
from our auth department to create a public key
in DER format to use this library. Am i missing something or is this library just not suitable for my case?
In order to provide an accurate key for some applications (e.g. OpenID Connect for Google), we need to be able to access the kid (Key ID) field of the header. I could also imagine other fields in the header would be necessary to find the validation context.
The current API allows by decoding a JWT with no signature verification, however I feel that it would be less error-prone if there were a separate function to access the header directly. In that case, you wouldn't have a non-validated payload in the code, and have less chance of accidentally using it without appropriate validation.
The simplest way would be just to add a function decode_header
like so:
fn decode_header(token: &str) -> Result<header::Header> ...
If algorithm is not explicitly enforced via Validation, library will happily accept "forged" token where RS256 algorithm is replaced with HS256 and token is signed with RSA public key used as a secret.
Not sure what could be done here as this isn't the library issue per se, but rather unsafe usage of it. Maybe warning in the documentation?
Alternatively, library could accept the only one algorithm as a parameter. Since key you need to pass to decode is specific to the algorithm anyway, the current signature of (token: &str, key: &[u8], validation: &Validation) is not very useful.
Hello,
I try to figure out how to validate a jwt issued by Firebase Auth service.
I try with this code with no chance :
let private_key = "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgk******3sPj2xm0C\nl76YeEQy0+BJqSvNq5Z05g==\n-----END PRIVATE KEY-----\n";
let mut validation = Validation::new(Algorithm::RS256);
let header = decode_header(&token).unwrap();
eprintln!("Token header: {:?}", header);
let token = decode::<Claims>(&token, private_key.as_ref(), &validation);
eprintln!("Token : {:?}", token.unwrap());
And Claim struct:
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String
}
The header is correctly parsed but the claim cannot be verified (InvalidSignature). Since I'm new to this, maybe I did something wrong, can someone help me please ?
PR welcome, otherwise I'll do it when I have time
RS256, RS384 and RS512
validation::validate
assumes all relevant date fields are serialized as i64
as they are passed to serde_json::from_value::<i64>
.
Per default this is not the case for e.g. chrono::DateTime
which seems to be the de-facto standard type to represent timestamps.
It took me several hours to realize the error happens in validate
as the error message said something along the lines of found string "<valid timestamp with timezone string>". expected i64
which I interpreted as a failure in parsing the claims themselves.
I am not too familiar with serde
and chrono
internals but it should be possible to deserialize the complete chrono::DateTime
and compare this with now
obtained earlier in the function.
I am a little busy right now, but might whip up a PR in the next days..
In the documentation (https://docs.rs/jsonwebtoken/5.0.1/jsonwebtoken/struct.Validation.html#structfield.validate_iat) it's mentioned that the validate_iat
and validate_nbf
fields are true
by default, but in the source (https://docs.rs/jsonwebtoken/5.0.1/src/jsonwebtoken/validation.rs.html#98-99) the default value is false
. This is also the behavior of the current release (5.0.1).
Currently the TokenData struct does not appear to be made public, and thus does not appear in the documentation. To my understanding, this will eventually cause an error during building as well. A top-level pub use
should handle this, as you do with Header
.
Documentation says to provide validation leeway in milliseconds but it seems to actually work as seconds.
Any plan to support JWE support?
chrono
is a very popular date and time library and defaults to serializing as ISO strings instead of timestamps as per the JWT spec. It'd be nice to have an example using the #[serde(with = "..")]
attribute. I can submit a PR with this example if it is accepted for inclusion.
Hi,
This project seems to use untrusted = 0.5
as I can see from the cargo.toml file on master branch. Recently a security issue was fixed as part of 0.6.2 release. Please refer to rustsec/advisory-db@3c0458d .
Kindly ignore if this is irrelevant or fixed on another branch.
Thanks.
.
version: 6.0.1
algorithm: Algorithm::RS512
I just add nbf for 4200 sec from now. After 5-10 sec. i try to validate this token but it is pass (set leeway just 60 sec. but it should not be pass). so i think it not validate nbf time. (My purpose is for validate refresh_token that can use after access_token expired or refresh_token.claims.nbf = access_token.claims.exp
)
my claims:
{
"exp": 1567042832,
"nbf": 1567042232,
"iat": 1567038032
}
my validation:
let validation = Validation {
leeway: 60,
algorithms: vec![Algorithm::RS512],
..Validation::default()
};
let token_data = match decode::<T>(&token, &PUBLIC_KEY, &validation) {
Ok(c) => c,
Err(err) => match *err.kind() {
ErrorKind::InvalidToken => {
error!("InvalidToken");
return None;
},
ErrorKind::InvalidAudience => {
error!("InvalidAudience");
return None;
},
ErrorKind::InvalidIssuer => {
error!("InvalidIssuer");
return None;
},
ErrorKind::InvalidSignature => {
error!("InvalidSignature");
return None;
},
ErrorKind::ExpiredSignature => {
error!("ExpiredSignature");
return None;
},
_ => {
error!("TokenError");
return None;
}
},
};
No longer can compile
/ring-3628119f6179288e/out/obj/crypto/aes/asm/aes-x86_64.S:3:1: error: unknown directive .type _x86_64_AES_encrypt,@function ^
ring currently requires a lot of host specific build tools, which now makes this package unable to cross compile. At least keep this able to cross compile until ring gets it's build chain setup better.
Not immediately though, wait till it is easily usable on stable (see macros 1.1 stabilisation)
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
ES256, ES384 and ES512
I've just been informed in the Rust IRC channel that rust-crypto is abandoned and should not be used anymore. As example of critical fixes that are not merged, I was given DaGenix/rust-crypto#349
Libraries that probably have the primitives rust-jwt needs:
As specified in https://tools.ietf.org/html/rfc7518#section-3.5
The RSASSA-PSS signature verification algorithm is supported by ring
I appreciate the challenge of chasing Ring's versions, but ATM jsonwebtoken can't be used with rustls (which depends on ring 0.14).
Is that process basically mechanical? i.e. Bump Ring, test, bump version, publish?
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.
Anyone have some insight on what I'm doing wrong here?
Thanks
ring
has been upgraded to 0.3.0 and has yanked all previous versions, causing jsonwebtoken
to fail to resolve dependencies:
> cargo build
Updating registry `https://github.com/rust-lang/crates.io-index`
error: no matching package named `ring` found (required by `jsonwebtoken`)
location searched: registry https://github.com/rust-lang/crates.io-index
version required: ^0.2
versions found: 0.3.0
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.