-
Notifications
You must be signed in to change notification settings - Fork 263
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
fixed aud validation and changed aud field type to Option<String> #103
Conversation
I am not sure the audience validation is always ever a single string, see jpadilla/pyjwt#205 for example. |
@Keats This is a test of membership. Note that the specification refers to a principal, not a plural principals. The singular principal name is what is saved in the Validation's aud String . The validation test is for membership: is this String in the list presented in the jwt? As the jsonwebtoken stands today, a system can only validate aud that directly matches that provided in the jwt. I am advancing a PR that considers a jwt created for authentication across a number of systems. In other words, my PR supports the following: Token Server to Recipient: "Here's a token that you can use to authenticate with systems A, B, or C." Where as the current jsonwebtoken validation requires many identity tokens be created: Token Server to Recipient: "Here's a token that you can use to authenticate with systems A" |
@Keats this requires your consideration, still.. |
Right, it's closer to the spec, but libraries in other languages do allow validation against an array even if they didn't before, as seen in the PR linked above. |
@Keats Are you in agreement about the need for membership test and is it clear what I'm trying to achieve with it? The idea is that the token could have a comprehensive list of audience members that is a superset to Validation's aud field. I have no issues with sticking to the serde_json::Value for the aud field within Validation. This just requires a set operation instead of what I've initially provided. Also, it requires consideration of whether to verify that ALL or ANY of the list members be present in the token's aud. Supposing that Validation.aud: <Option> = ["one", "two"], the membership test is EITHER that A) both are present within the token's aud or B) any are present within the token's aud Thoughts? |
@Keats yes? |
I see the issue now. |
@Keats I've updated the PR. All tests pass. The latest involves no breaking change on set_audience public api. However, aud field is public and the type is now HashSet so this will introduce breaks for those who have not used set_audience. Using HashSet is preferable to deriving a HashSet for every Validation computation. Let me know what you think.. |
@Keats ready for review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you do the PR on the v7 branch? Since it does contain a breaking change.
This means we can also change set_audience
to something like add_audience
that takes a &str and not expose Value
at all.
let aud = to_value(audience) | ||
.unwrap_or_else(|_| panic!("Failed to_value within set_audience)")); | ||
let aud = Validation::convert_aud(&aud) | ||
.unwrap_or_else(|_| panic!("Failed convert_aud within set_audience")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this definitely should not panic should I would just replace the unwrap_or_else with expect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unwrap_or_else
is the idiomatic recommendation by clippy for expect
, which panics as does the unwrap that is there now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what you're trying to achieve with add_audience(&str)
. Audience is set in one call. It isn't incrementally built.
I can resubmit this as 0.7..
moved to |
Validation type's aud field and the aud validation logic requires reconsideration.
The Validation type should use aud:
Option<String>
, notOption<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.the aud field of a jwt 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.