Skip to content
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

Merged
merged 23 commits into from
Jun 27, 2020
Merged

Support multiple relying parties #296

merged 23 commits into from
Jun 27, 2020

Conversation

padulafacundo
Copy link
Contributor

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.

@padulafacundo padulafacundo marked this pull request as ready for review January 3, 2020 13:04
@grzuy
Copy link
Contributor

grzuy commented Jan 9, 2020

Nice work!
Interesting to see this prototyped...

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)
Copy link
Contributor

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... :-)

Copy link
Collaborator

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 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know :-)
Thanks.

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
)
Copy link
Contributor

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 👌

@brauliomartinezlm
Copy link
Member

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.
Let me know if you find any issues after my rebase. I'll be trying to move this PR forward in the following days, but I want to take some time to see if we can avoid passing that relying party parameter through so many layers as we are.

@grzuy grzuy changed the title Relying Party model Support multiple relying parties Feb 22, 2020
@brauliomartinezlm
Copy link
Member

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 🙏

@grzuy grzuy marked this pull request as draft April 26, 2020 21:32
lib/webauthn/relying_party.rb Outdated Show resolved Hide resolved
lib/webauthn/relying_party.rb Outdated Show resolved Hide resolved
lib/webauthn/relying_party.rb Outdated Show resolved Hide resolved
lib/webauthn/relying_party.rb Outdated Show resolved Hide resolved
@grzuy grzuy marked this pull request as ready for review May 16, 2020 22:07
lib/webauthn/authenticator_attestation_response.rb Outdated Show resolved Hide resolved
spec/conformance/conformance_cache_store.rb Outdated Show resolved Hide resolved
lib/webauthn/signature_verifier.rb Outdated Show resolved Hide resolved
@bdewater
Copy link
Collaborator

Except for some linter issues this seems ready to go?

@brauliomartinezlm
Copy link
Member

brauliomartinezlm commented Jun 22, 2020

@bdewater yeah, we're really close.
In my TODO list there is:

  • Fixing Rubocop in this PR (DONE)
  • Make sure/validate we are comfortable with the API for verify_authentication with the block syntax with the alternative to pass in public_key and sign_count in case you don't want to use the block. For this I would love @bdewater and @grzuy feedback specially. You can see the usage in both the demo app or this comprehensive test I wrote for the new API and the coexistence with the old
  • Update README to reflect the new API (might be done in a followup PR if we want to have this in sooner as the current docs are still a valid usage)

@bdewater
Copy link
Collaborator

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 /docs would be better?

@grzuy
Copy link
Contributor

grzuy commented Jun 27, 2020

  • Make sure/validate we are comfortable with the API for verify_authentication with the block syntax with the alternative to pass in public_key and sign_count in case you don't want to use the block. For this I would love @bdewater and @grzuy feedback specially.

I think this PR is a good fit for a v3.0.0.alpha1.

We unblock people needing/asking this for a few months already, we potentially collect some feedback on the new RelyingParty public API, and we have some wiggle room for making some minor adjustments if needed before freezing the API on v3.0.0.

@grzuy
Copy link
Contributor

grzuy commented Jun 27, 2020

I think this is a good fit for a v3.0.0.alpha1.

Will release this within the next hour.

@grzuy
Copy link
Contributor

grzuy commented Jun 27, 2020

  • Update README to reflect the new API (might be done in a followup PR if we want to have this in sooner as the current docs are still a valid usage)

Follow up PR sounds good to me.

@grzuy grzuy merged commit 2f54c92 into master Jun 27, 2020
@grzuy grzuy deleted the relying_party branch June 27, 2020 20:43
@grzuy
Copy link
Contributor

grzuy commented Jun 27, 2020

Excellent work @padulafacundo and @brauliomartinezlm 🙌 🙌

Thanks @bdewater for all the code review help here also!

@grzuy
Copy link
Contributor

grzuy commented Jun 27, 2020

Anyone feel free to continue providing feedback/comments on this PR despite merged.

Copy link

@sandstrom sandstrom left a 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)

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

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)
Copy link

@sandstrom sandstrom Jun 29, 2020

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)

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?

@grzuy
Copy link
Contributor

grzuy commented Jun 29, 2020

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.

Thank you very much for taking the time to review and provide feedback!
We appreciate it :-)

Either way I'm happy to see that there is now support for multiple PRs within the same app. That's awesome! smile

grzuy added a commit that referenced this pull request Feb 28, 2021
grzuy pushed a commit that referenced this pull request Feb 28, 2021
This reverts commit dbff817.

Co-authored-by: Braulio Martinez <[email protected]>
bdewater pushed a commit that referenced this pull request Sep 8, 2022
* 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]>
@bdewater bdewater mentioned this pull request Sep 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants