Keats / jsonwebtoken

JWT lib in rust
MIT License
1.67k stars 266 forks source link

While decoding: Error(Json(Error("duplicate field `resource_access`", #254

Closed ymwjbxxq closed 2 years ago

ymwjbxxq commented 2 years ago

Hello,

I cannot understand where the problem is, so I try here.

The claiming structure is like this (not standard):

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Claims {
    pub aud: String,
    pub sub: String,
    pub email: String,
    pub exp: usize,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub resource_access: Option<ResourceAccess> -> THIS IS THE PROBLEM
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct ResourceAccess {
    #[serde(rename = "my-super-app")]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub app: Option<App>,
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct App {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub roles: Option<Vec<String>>,
}

If I decode with jwt.io the token, I get a payload data and if I write a unit test, I can deserialize correctly.

 #[test]
    fn serde_claim() -> Result<()> {
        // ARRANGE
        let data = r#"
        {
  "exp": 1654242297,
  "iss": "https://domain",
  "aud": "soemthing,
  "sub": "b@b.com",
  "resource_access": {
    "my-super-app": {
      "roles": [
        "my-super-app-role"
      ]
    }
  },
  "email": "xxx@xxx.com"
}"#;

        // ACT
        let v: Value = serde_json::from_str(data)?;
        let result: Claims = serde_json::from_value(v)?;

        assert!(result.resource_access.unwrap().app.unwrap().roles.is_some());
        Ok(())
    }

When I use decode functionality:

 let token_data = decode::<Claims>(
                        &token,
                        &key,
                        &validation,
                    ).unwrap();

I get the error:

Err value: Error(Json(Error("duplicate field resource_access",`

But if I remove "resource_access" from the Claim struct, it is all passing.

#[test]
    fn decode_token() -> Result<()> {
        // ARRANGE
        let token = r#"token"#;

        let n = r#"token"#;
        let e = r#"something"#;

        let mut validation = Validation::new(Algorithm::RS256);
        validation.validate_exp = false;

        let key = &DecodingKey::from_rsa_components(&n, &"something").unwrap();

        // ACT
        let token_data = decode::<Claims>(
                        &token,
                        &key,
                        &validation,
                    ).unwrap();

        // ASSERT
...
        Ok(())
    }

Any idea of what I am doing wrong?

Thanks, Dan

ymwjbxxq commented 2 years ago

I have fixed the problem

let token_data = decode::<Value>(
                        &token,
                        &key,
                        &validation,
                    ).unwrap();
 let result: Claims = serde_json::from_value(token_data.claims)?;

Not sure why but great