Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upImplement idP resolution using OpenID Connect Discovery #13
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
onli
Aug 2, 2016
Member
Hi @binki. I remember that we talked in an IRC meeting about this. I think that the WebFinger lookup was used in one model, maybe that was an idea of @skorokithakis at that time? Currently and as far as I could see, https://github.com/letsauth/ladaemon uses the discovery URL, see https://github.com/letsauth/ladaemon/blob/master/src/oidc.rs#L42. But I think that's where the webfinger lookup could be added.
|
Hi @binki. I remember that we talked in an IRC meeting about this. I think that the WebFinger lookup was used in one model, maybe that was an idea of @skorokithakis at that time? Currently and as far as I could see, https://github.com/letsauth/ladaemon uses the discovery URL, see https://github.com/letsauth/ladaemon/blob/master/src/oidc.rs#L42. But I think that's where the webfinger lookup could be added. |
onli
added
the
enhancement
label
Aug 2, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
binki
Aug 2, 2016
I ended up finding a discussion of something similar in the ML archives after the fact. Thanks for pointing to the spot in the source, maybe I’ll find time to play with the daemon, but I’m not sure yet.
binki
commented
Aug 2, 2016
|
I ended up finding a discussion of something similar in the ML archives after the fact. Thanks for pointing to the spot in the source, maybe I’ll find time to play with the daemon, but I’m not sure yet. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
binki
Aug 3, 2016
So, I’ve started trying to write my own dummy idP since I don’t know off-hand of any example implementations. So far I have a faked out webfinger: https://client.webfinger.net/lookup?resource=ohnobinki%40turbo.coffee . We’ll see if I get any futher… ;-).
binki
commented
Aug 3, 2016
|
So, I’ve started trying to write my own dummy idP since I don’t know off-hand of any example implementations. So far I have a faked out webfinger: https://client.webfinger.net/lookup?resource=ohnobinki%40turbo.coffee . We’ll see if I get any futher… ;-). |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
callahad
Aug 4, 2016
Member
(Pinging @rfk to get his blog post up on OpenID Connect and the quality of its dynamic registration spec...)
|
(Pinging @rfk to get his blog post up on OpenID Connect and the quality of its dynamic registration spec...) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
callahad
Aug 4, 2016
Member
Actually, I somehow missed the attachment on one of @rfk's responses in that mailing list thread. That's a very good place to start.
at a glance it appears that decentralized idP lookup based on email address is already defined by a well-accepted standard and the standard which letsauth is using as a basis for its own protocol, nonetheless.
That's also my understanding. Without having actually implemented it, Webfinger does indeed look reasonable for discovery of a user's identity provider... but then we have to solve the problem of our daemon being able to talk to that provider without having been previously introduced and registered.
Similarly, what protocol does the provider speak? How do we make that easy enough for individuals with their own domain to become their own identity providers?
I don't have the headspace to tackle this right now, but I'd absolutely love it if someone (@binki, et al.) began exploring in this direction. It can be cleanly added to our list of auth strategies in the future, so it's not a blocker for v1.0, but we will need to solve this problem before we can claim to have lived up to our goal of empowering people to self-certify.
|
Actually, I somehow missed the attachment on one of @rfk's responses in that mailing list thread. That's a very good place to start.
That's also my understanding. Without having actually implemented it, Webfinger does indeed look reasonable for discovery of a user's identity provider... but then we have to solve the problem of our daemon being able to talk to that provider without having been previously introduced and registered. Similarly, what protocol does the provider speak? How do we make that easy enough for individuals with their own domain to become their own identity providers? I don't have the headspace to tackle this right now, but I'd absolutely love it if someone (@binki, et al.) began exploring in this direction. It can be cleanly added to our list of auth strategies in the future, so it's not a blocker for v1.0, but we will need to solve this problem before we can claim to have lived up to our goal of empowering people to self-certify. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
djc
Aug 4, 2016
Member
So dynamic registration is one thing, but IIRC we wanted to try and keep the daemon stateless, right? And I assume most OIDC providers would not work well with trying to register the same callback URL a second time...
|
So dynamic registration is one thing, but IIRC we wanted to try and keep the daemon stateless, right? And I assume most OIDC providers would not work well with trying to register the same callback URL a second time... |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
callahad
Aug 4, 2016
Member
IIRC we wanted to try and keep the daemon stateless, right?
Right. This is somewhere we likely need to develop a custom protocol, taking inspiration from Persona and OIDC Dynamic Registration and maintaining as much of OIDC as makes sense, without requiring true registration or long-term statefulness.
Right. This is somewhere we likely need to develop a custom protocol, taking inspiration from Persona and OIDC Dynamic Registration and maintaining as much of OIDC as makes sense, without requiring true registration or long-term statefulness. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
binki
Aug 4, 2016
Right now I’m slowly working through an implementation of the idP side of the specs as I have time. Hopefully the specs have some allowance for registration-free authentication, I think someone in that ML thread mentioned that implicit flow might allow that, but I haven’t gotten that far yet myself. Avoiding registration would also make the idP itself simpler.
One thing I did want to note here is a decision I’ve made about the WebFinger lookup itself. The OpenID Connect Discovery 1.0 says:
To find the Issuer for the given user input in the form of an e-mail address joe@example.com
in this case, the acct: scheme [I‑D.ietf‑appsawg‑acct‑uri] is prepended to the Identifier.
However, the acct: spec and WebFinger spec describe acct: as intended for looking up non-email accounts. My interpretation of WebFinger’s spec is that: if you want to look up general accounts that might not have emails associated with them, use acct: (and you can end up with something unassociated with an email, like acct:ohnobinki@twitter.com). But if you want to, you can use WebFinger to resolve an email address to an account by just using mailto:email@example.org. It is up to the WebFinger implementation whether or not it supports resolving mailto: and that would just be one of many requirements Portier would have for services to implement OPTIONAL features from the specs to support Portier ;-). I.e., Portier should do the idP lookup using mailto: rather than acct: to properly respect the specs.
I’ve implemented an example of that at https://client.webfinger.net/lookup?resource=mailto%3Aohnobinki%40turbo.coffee where mailto:ohnobinki@turbo.coffee resolves to acct:ohnobinki@turbo.coffee. Yay a tiny bit of progress? I have a long way to go… xD
binki
commented
Aug 4, 2016
|
Right now I’m slowly working through an implementation of the idP side of the specs as I have time. Hopefully the specs have some allowance for registration-free authentication, I think someone in that ML thread mentioned that implicit flow might allow that, but I haven’t gotten that far yet myself. Avoiding registration would also make the idP itself simpler. One thing I did want to note here is a decision I’ve made about the WebFinger lookup itself. The OpenID Connect Discovery 1.0 says:
However, the I’ve implemented an example of that at https://client.webfinger.net/lookup?resource=mailto%3Aohnobinki%40turbo.coffee where |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
rfk
Aug 4, 2016
Hopefully the specs have some allowance for registration-free authentication, I think
someone in that ML thread mentioned that implicit flow might allow that
Sadly, I'm pretty sure the existing implicit flow does not allow this, mostly because it would be a security problem - you need some way to tell what redirect_uri values are legit for each client.
I think we could invent a protocol that securely replaces "client registration" with "client discovery" along the lines of [1], but I'm not aware of any existing spec that avoids pre-registration of client credentials.
we wanted to try and keep the daemon stateless, right? And I assume most
OIDC providers would not work well with trying to register the same callback URL a second time
If you're happy to keep a bit of state in a cache to reduce overall server load, you might actually get away with this. IIUC the dynamic registration spec is fine with you registering the same client details multiple times, and re-registering is the recommended way to e.g. replace your client secret in the event of a data breach.
[1] https://groups.google.com/d/msg/portier/kOc_SMY_9lI/DIuoD2HUBwAJ
rfk
commented
Aug 4, 2016
Sadly, I'm pretty sure the existing implicit flow does not allow this, mostly because it would be a security problem - you need some way to tell what redirect_uri values are legit for each client. I think we could invent a protocol that securely replaces "client registration" with "client discovery" along the lines of [1], but I'm not aware of any existing spec that avoids pre-registration of client credentials.
If you're happy to keep a bit of state in a cache to reduce overall server load, you might actually get away with this. IIUC the dynamic registration spec is fine with you registering the same client details multiple times, and re-registering is the recommended way to e.g. replace your client secret in the event of a data breach. [1] https://groups.google.com/d/msg/portier/kOc_SMY_9lI/DIuoD2HUBwAJ |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
binki
Aug 4, 2016
Even for the email link login to work you need state, right? Since it sounds like reregistering shouldn't be too big of a deal, caching the registration token for a few minutes at a time for the sake of staying with existing standards sounds like the way to go.
binki
commented
Aug 4, 2016
|
Even for the email link login to work you need state, right? Since it sounds like reregistering shouldn't be too big of a deal, caching the registration token for a few minutes at a time for the sake of staying with existing standards sounds like the way to go. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
rfk
Aug 4, 2016
Although TBH I'm not aware of any major OIDC IdP that actually implements the dynamic registration spec, so it may be a moot point.
rfk
commented
Aug 4, 2016
|
Although TBH I'm not aware of any major OIDC IdP that actually implements the dynamic registration spec, so it may be a moot point. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
skorokithakis
Aug 4, 2016
Member
@binki You don't need state for the email login link, you can sign it using a secret so you just validate the signature when it comes back.
|
@binki You don't need state for the email login link, you can sign it using a secret so you just validate the signature when it comes back. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
onli
Aug 5, 2016
Member
The ladaemon however uses redis to store some state: https://github.com/portier/ladaemon/blob/master/src/store.rs. I think that's okay and would also be okay here. There is a difference between having some internal state used for making the authentication work and having state in the sense of users storing accounts and profil information. The line is where one ladeamon instance can't be swapped out with another without loosing stuff.
|
The ladaemon however uses redis to store some state: https://github.com/portier/ladaemon/blob/master/src/store.rs. I think that's okay and would also be okay here. There is a difference between having some internal state used for making the authentication work and having state in the sense of users storing accounts and profil information. The line is where one ladeamon instance can't be swapped out with another without loosing stuff. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
djc
Aug 5, 2016
Member
Yeah, ladaemon has some state, but it's all short-lived. So if the database breaks down or whatever (or, if you want to setup your own instance), nothing is lost other than some limited performance penalty due to having to fetch more data in order to do the job.
|
Yeah, ladaemon has some state, but it's all short-lived. So if the database breaks down or whatever (or, if you want to setup your own instance), nothing is lost other than some limited performance penalty due to having to fetch more data in order to do the job. |
binki commentedAug 1, 2016
The concept of idPs resolved via email addresses (instead of OpenID discovery URIs) is my favorite feature of Persona. It made Persona much easier to use than traditional OpenID where a website either only permits the user to select from a list of trusted OpenID providers or the user has to paste in a “discovery URI”. Persona used the authority information inherent in the user’s identity (email), the domain name, as the starting point for idP discovery. Analogous to how an MTA looks up
MXrecords, Persona checked for well-known DNS records to see if the mail provider defined an idP. If the mail provider did provide an idP, the user would get a much nicer login experience.Based on how letsauth is right now implementing OpenID Connect and how it seems like a standard which will get wide adoption, perhaps letsauth could set a goal to define an idP lookup mechanism similar to Persona. Or maybe OpenID Connect already defines a way to do this…
At http://openid.net/connect/ , I see Discovery and Dynamic Registration. So perhaps Discovery defines a way to find what OpenID Connect provider should be used for an email address. Right in the spec is a description of how to form a WebFinger lookup for a typed email address. Given email
user@example.org, you would send a request tohttps://example.org/.well-known/webfinger?resource=acct%3auser%40example.org&rel=http%3A%2F%2Fopenid.net%2Fspecs%2Fconnect%2F1.0%2Fissuer. If the idP implements this optional endpoint, the request should yield enough information to find the OpenID Connect idP for the user.Of course, this is only the first step of a many step process and there are other points where failure could happen. I think maybe letsauth would have to use Dynamic Client Registration and keep track of its registrations with providers, etc. But at a glance it appears that decentralized idP lookup based on email address is already defined by a well-accepted standard and the standard which letsauth is using as a basis for its own protocol, nonetheless.
Of course, such a mechanism can’t replace letsauth. For email addresses for which OpenID Connect providers cannot be discovered, the email hash login would provide a baseline login experience. And a letsauth relier can be kept clean and simple if it can always delegate to letsauth rather than implementing the discovery itself.