-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature request] Decode JWT without verification #75
Comments
Thank you for writing up your use case, and your suggestion. You should put the key set in one of the header parameters. I have not built support for those headers yet. Support is tracked in #15. The philosophy I am trying to adopt for this library (inspired by the design of others such as That being said, it is certainly doable with the public API that the library provides now. It requires a little bit of digging through the implementation detail. Let me give you an example. The The So, assuming you want to extract values from the JWS header prior to verifying its signature, you can do this: extern crate biscuit;
use biscuit::{Compact, Empty};
use biscuit::jws;
fn main() {
// Token's payload is arbitrary bytes
let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IlJhbmRvbSBieXRlcyJ9.\
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcG\
xlLmNvbS9pc19yb290Ijp0cnVlfQ.\
E5ahoj_gMO8WZzSUhquWuBkPLGZm18zaLbyHUQA7TIs";
let compact = Compact::decode(&token);
let header: jws::Header<Empty> = compact.part(0).unwrap();
println!("{:?}", header);
let payload: Vec<u8> = compact.part(1).unwrap();
println!("{:?}", payload);
let signature: Vec<u8> = compact.part(2).unwrap();
println!("{:?}", signature);
}
Please let me know if you disagree with my sentiment above, and I would gladly add an API for this operation, or at least provide examples. |
Thanks for the example! I generally agree with the sentiment, that is should be obvious to the user that they are potentially shooting themselves in the foot when using trickier parts of the library. However, I think that this can be achieved in better ways than forcing the use of a more cumbersome API. One good way to prevent misuse in Rust in my experience is to put the "risky" operations into a trait that is not imported with the default wildcard import (e.g. Another way to prevent misuse (which I think is the main philosophy of the |
Thanks for your views. Do you think what I've provided as example code is sufficient, or I should have something closer to the My code example requires more understanding of the various "parts" of a JWS (and subsequently JWE) compact serialisation. |
@lawliet89 I appreciate your dedication to the philosophy of safety in the API. However, I'm not sure that should come at the expense of the philosophy of JWTs themselves, particularly in a JWT library. JWTs, as I'm sure you know, are transparent by design, in contrast to, say, OAuth. I think the API of any JWT library should reflect this and it should be considered a first-class, straightforward feature to "peer into" an unencrypted JWT, especially for the use case of determining the very means necessary to do the verification in the first place. I cannot think of a library I've come across that doesn't allow this. Whether or not Rust is doing them all one better is an argument, but I cannot say I find the argument convincing yet. In other words, I cannot really imagine what an API might be that wasn't clearly intentional and thereby safe enough. Perhaps I'm missing something about the use-case for the If I'm not completely off-target about how the API might change here, I'd be interested in helping put together a PR. |
I guess there's also a concern about having hold of a |
I am not sure what you mean by this statement. If by transparent, you mean that the contents are transparent, then yes: unencrypted JWTs are already transparent. But encrypted JWTs are still not transparent. This issue is primarily about using signatures to check the authenticity and integrity of the JWT themselves.
It's in the spec to allow you to simply not have a signature for your JWT. I will look into adding a function to allow "peering" into the contents of the payload without checking the signature.
That's my main concern. I don't really want to complicate the design of the library too much, though. Anyway, please note that if you use encrypted JWTs (type |
@lawliet89 Thanks for the response.
Correct, but do you mean they're already transparent with biscuit, meaning there's a first-class API for viewing the contents without providing the secret needed to verify the signature? If so, then I might have jumped the gun, but I had come to the same conclusion as @hobofan in my poking around. I think we're both focused on the fact that I can, for example, use a tool like https://www.jsonwebtoken.io/ without knowing the signing key, but we can't (afaik) with biscuit or not easily. A flow I have in mind is something like this:
I also might want to know if I'm even the intended audience before I even bother to determine if I know the issuer and how I might go about validating them and their token. If I'm not, I'll 403 them and carry on. The algorithm you posted above gets most of the way there for these use-cases.
Of course. I assumed the conversation was already focused on JWS not JWE, but I should have been clear that that was what I was focused on.
Got it. Makes sense.
Awesome. Let me know if I can help. It would be lovely to receive a token and then immediately be able to do things like |
I am adding them as we speak. The functions will basically be convenient wrappers around the example code I've posted earlier in this issue. |
Please take a look at #88. If the API looks OK, I'll merge that in. |
As far as I can see it, right now there is no way to access to payload/decoding a JWT without verifying the signature. I can see how it generally isn't good to encourage such a usage, but I think there are some valid reasons to allow it.
My use-case:
I am using JWTs in a microservice environment, where there is a central auth server that gives out the JWTs. Currently, the other microservices get the public key to verify the JWT from a fixed route on the auth service. This limits the system to one key pair for the whole system, which is rather inflexible.
What I would like to do is allow multiple auth servers/multiple key pairs to exist in the system. To do this, I would put the URL of the respective public key into the payload of the JWT. As long as the URL is limited to a whitelist of acceptable public key URLs, this should represent a secure system. However, this would require the payload to be read without the JWT signature being verified since the relevant public key is not yet known at that point.
EDIT: The same thing applies to the JWT headers, since the
jku
,jwk
,kid
,x5u
,x5c
,x5t
, andx5t#S256
header fields provide a way to achieve the use-case I wrote about above.The text was updated successfully, but these errors were encountered: