-
Notifications
You must be signed in to change notification settings - Fork 53
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
Support multiple relying parties #296
Conversation
Nice work! I think this is something to seriously consider merging at some point, maybe after waiting a bit for other pieces to mature and settle on. Thank you! |
@@ -13,26 +13,26 @@ class FormatNotSupportedError < Error; end | |||
ATTESTATION_FORMAT_ANDROID_KEY = "android-key" | |||
ATTESTATION_FORMAT_TPM = "tpm" | |||
|
|||
def self.from(format, statement) | |||
def self.from(format, statement, relying_party: WebAuthn.configuration.relying_party) |
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.
[We talked about this IRL, but writing a comment for the record]
This extra keyword argument feels a little bit odd, but I can't think of a better alternative right 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 like it - passing configuration to be used as an argument, by default being a copy of the global configuration. I'm a little torn on the 'relying party' name but I'll not 🚲🏡 too much here 😄
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.
Good to know :-)
Thanks.
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.
Did you use a keyword for backwards compatibility? If you are doing a major version bump perhaps you should change this first? (to positional args, or change all of them to keyword args)
public_key: public_key, | ||
sign_count: sign_count, | ||
user_verification: user_verification | ||
) |
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 like this... Feels semantically right that no credential is returned unless it's been verified 👌
ab07f0a
to
2ae33e7
Compare
I have just rebased this PR that with the extraction of TPM to a gem and the refactor of moving things to the an attestation object was quite an update. |
2ae33e7
to
3441374
Compare
782d6bc
to
1408dce
Compare
Hey folks! I've rebased this PR again. I'm planning to do what I said in my previous comment shortly, hope to have the time this time 🙏 |
ee0e581
to
2d6d49a
Compare
40e8ad8
to
1c739ca
Compare
1c739ca
to
3181c5c
Compare
46fc826
to
899c3a0
Compare
Except for some linter issues this seems ready to go? |
@bdewater yeah, we're really close.
|
a22a381
to
df318ca
Compare
df318ca
to
fdff64d
Compare
At first glance this looks fine, I will make time this weekend for a more thorough review. Regarding the readme: I was thinking it's getting pretty long and I'm not sure if a lot of people will need this. Perhaps a markdown file in |
I think this PR is a good fit for a We unblock people needing/asking this for a few months already, we potentially collect some feedback on the new |
Will release this within the next hour. |
Follow up PR sounds good to me. |
Excellent work @padulafacundo and @brauliomartinezlm 🙌 🙌 Thanks @bdewater for all the code review help here also! |
Anyone feel free to continue providing feedback/comments on this PR despite merged. |
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.
Since I submitted the original issue (#285) around this I thought I'd add some feedback here.
Sorry for being late to the game, I hadn't noticed the activity that's taken place here. Some of my suggestions may be "too late", also they are fairly subjective so do what you want with them.
Either way I'm happy to see that there is now support for multiple PRs within the same app. That's awesome! 😄
@@ -13,26 +13,26 @@ class FormatNotSupportedError < Error; end | |||
ATTESTATION_FORMAT_ANDROID_KEY = "android-key" | |||
ATTESTATION_FORMAT_TPM = "tpm" | |||
|
|||
def self.from(format, statement) | |||
def self.from(format, statement, relying_party: WebAuthn.configuration.relying_party) |
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.
Did you use a keyword for backwards compatibility? If you are doing a major version bump perhaps you should change this first? (to positional args, or change all of them to keyword args)
raise RootCertificateFinderNotSupportedError, "Finder must implement `find` method" | ||
end | ||
end | ||
def rp_id |
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.
Is there a reason why you aren't spelling out def relying_party
?
def self.from_get(credential) | ||
WebAuthn::PublicKeyCredentialWithAssertion.from_client(credential) | ||
def self.from_get(credential, relying_party: WebAuthn.configuration.relying_party) | ||
WebAuthn::PublicKeyCredentialWithAssertion.from_client(credential, relying_party: relying_party) |
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.
Quite subjective, but if I where you I think I'd move the API over to something like this:
relying_party = WebAuthn::RelyingParty.new(…)
relying_party.public_key_credential_with_attestation(credential)
Closer to how most data base adapters (for example) operate. Everything is based of a single client instance. If I wanted to avoid RelyingParty.new
I'd maybe add the possibility to keep a WebAuthn.default_rp
that was still configurable via configure
.
I'd probably cease support for the current API (for simplicity and less maintenance). With a clear "upgrade guide" for different method calls it should still be a simple migration.
If I wanted to support existing API plus new "relying party instance API", I would replace most (all?) methods that take a relying party instance as an argument with a similarly named method on the relying party instance, such that the instance can pass itself in instead. In other words, all diffs in this PR that add an argument passing in RP I'd instead add that method on RP instance.
rp[:name] ||= configuration.rp_name | ||
rp[:id] ||= configuration.rp_id | ||
rp[:name] ||= relying_party.name | ||
rp[:id] ||= relying_party.id | ||
|
||
RPEntity.new(**rp) |
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.
For consistency, would it make sense to rename this to RelyingPartyEntity
?
Thank you very much for taking the time to review and provide feedback!
|
This reverts commit dbff817. Co-authored-by: Braulio Martinez <[email protected]>
* WIP: Relying Party model * fixup! WIP: Relying Party model * refactor: make `WebAuthn.configuration` a wrapper for a `RelyingParty` instance * fixup! refactor: make `WebAuthn.configuration` a wrapper for a `RelyingParty` instance * refactor: delegate Configuration methods * refactor: always pass a RelyingParty * use relying party on when creating options * refactor: remove unnecessary aliases * fix: make reader private * refactor: make parent class AuthenticatorResponse responsible for relying party * fix: post rebase fixes * test: get rid of all keyword 2.7 warnings * fix: rebase trailing diff * fix: make rubocop happy * fix: make AttestationObject#deserialize accept relying_party param * refactor: algorithm validation uses relying party configuration * fix: make RP initializer use finders setter to process params correctly * fix: cache store should recieve origin from server * refactor: CR comments on API flexibility * refactor: CR comments * test: add functional comprehensive test for multiple RPs and a default configuration * refactor: Allow #verify_authentication to be used with or without a block * style: fix rubocop Co-authored-by: Braulio Martinez <[email protected]>
Create a new
RelyingParty
class to allow the user of the gem to set up multiple instances (tries to solve #285).This class also makes the registration/authentication ceremonies simpler.