-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
feat: OAuth 2.0 Device Authorization Grant #2416 #3252
base: master
Are you sure you want to change the base?
Conversation
BREAKING CHANGE: SDK object `PatchDocument` was renamed to `JsonPatchDocument`.
Co-authored-by: Andreas Krause <a.krause@celonis.com>
@aeneasr I have some more time personally to look at this again. Is their anything external contributors can do to get this MR into a state thats safe and mergable ? |
# Conflicts: # consent/handler.go # consent/manager.go # consent/strategy.go # consent/strategy_default.go # persistence/sql/persister_consent.go # persistence/sql/persister_oauth2.go
@aeneasr by the way of introduction I am the cloud native product manager at Canonical (the publisher of Ubuntu) |
If their is a chance to get this merged I can put some time into cleaning up my original implementation, up to now I think @supercairos has been keeping the MR alive as they are using this feature now. I can also run you or other devs through the implementation |
Just a quick update: this is still on our plate and we want to move this forward. Since we’ll own the code after it’s merged, we must allocate resources to really make sure we’re completely confident in how the feature integrates in hydra. I’d expect some movement here soon. Thanks massively again for the contribution and your patience! |
@alnr just to reinforce the point above, i'm the lead engineer of the aforementioned IAM team at canonical, we are more than happy to divert some resources and help on the effort
@BuzzBumbleBee yes please, that would be great, feel free to get in touch, here's my email alessandro.cabbia@canonical.com and we can take it from there |
Hi all, would love to see this merged! |
Feel free to check the sister PR also @Fosite: |
this code is missing quite a few tests but I can definitly work on this if it helps having this PR merged :) |
@supercairos happy to contribute if help is needed, just need a bit of direction on how and where |
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.
Thank you very much for all the hard work! I finally managed to do a pass over the Hydra and Fosite PRs. I have left some comments, questions and ideas to improve this. Thank you for looking into this!
@@ -1178,3 +1214,136 @@ func (s *DefaultStrategy) loginSessionFromCookie(r *http.Request) *flow.LoginSes | |||
|
|||
return ls | |||
} | |||
|
|||
func (s *DefaultStrategy) requestDevice(ctx context.Context, w http.ResponseWriter, r *http.Request, req fosite.Requester) error { |
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.
Confusing name. Are we requesting a device?
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 guess it makes sense now, we ask the user to either enter the user_code
or confirm the code sent in the query param.
@@ -59,6 +61,9 @@ const ( | |||
IntrospectPath = "/oauth2/introspect" | |||
RevocationPath = "/oauth2/revoke" | |||
DeleteTokensPath = "/oauth2/tokens" // #nosec G101 | |||
|
|||
// Device Grant Handler | |||
DeviceAuthPath = "/oauth2/device/auth" |
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.
Should we have two different paths, one for the user and one for the device?
E.g., /oauth/device/auth for the POST from the device, and /oauth/device/verify for the user to verify the device?
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.
Additionally, I think it might be useful to handle user POST against the verification_url
(https://datatracker.ietf.org/doc/html/rfc8628#section-3.3) so that a UI can render a simple form that will submit the user_code
against the same endpoint.
Additionally, I think it might be useful to be able to configure a shorter version of this URL. /oauth2/device/auth
is already quite long if you have to type it on a mobile, plus some origin. How about /device
(as in the spec), or just /dev
, or /oauth2/dev
if you want to stick with the namespacing? But really, it should be configurable IMHO.
WDYT?
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.
Yes, that's one of the missing feature of this PR.
It shoudn't be hard to implemenent but I had to revert this particular feature because it was not working after the 2.1.1 merge.
We (at shadow) use a UI trick on the TV side to render a shorter URL (using a minified URL) but yes it should be configurable 👍
I can work on that after having fixed all the other PR reviews :)
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.
Additionally, I think it might be useful to handle user POST against the verification_url (https://datatracker.ietf.org/doc/html/rfc8628#section-3.3) so that a UI can render a simple form that will submit the user_code against the same endpoint.
Please ignore this remark, I now understand your approach with the device verifier, which is using a POST to the UI and then an admin API to bind the device to the flow.
} | ||
|
||
// FIXME: Add Doc | ||
func (h *Handler) performOAuth2DeviceAuthorizationFlow(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { |
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.
Tests?
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.
Sure it's missing quite a lots of tests :)
I'll add them asap :)
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.
Thank you!
// Responses: | ||
// 200: deviceAuthorization | ||
// default: errorOAuth2 | ||
func (h *Handler) performOAuth2DeviceFlow(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { |
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.
Tests?
@@ -217,6 +217,60 @@ func (p *Persister) GetConsentRequest(ctx context.Context, challenge string) (*f | |||
return f.GetConsentRequest(), nil | |||
} | |||
|
|||
func (p *Persister) CreateDeviceGrantRequest(ctx context.Context, req *flow.DeviceGrantRequest) error { |
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.
Remove these if you agree we can use user_code
.
Otherwise, we'll need tests ;).
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.
OK, now I know we need this.
/* #nosec G201 table is static */ | ||
return sqlcon.HandleError( | ||
p.QueryWithNetwork(ctx).Where("client_id=?", clientID).Delete(&OAuth2RequestSQL{Table: sqlTableAccess}), | ||
) | ||
} | ||
|
||
func (p *Persister) CreateDeviceCodeSession(ctx context.Context, signature string, requester fosite.Requester) (err error) { |
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.
Tests for all new methods in this file please.
sqlTableRefresh tableName = "refresh" | ||
sqlTableCode tableName = "code" | ||
sqlTablePKCE tableName = "pkce" | ||
sqlTableDeviceCode tableName = "device_code" |
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.
Please check if we really need two tables 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.
In fact, the best would be to use the flow
table as it can be seen as part of a login flow but since this MR was done before the 2.x we never took the time to update the database scheme.
But yes i believe there can be only one DB for both device_code
and user_code
as they are tied together
Here are some tools help develop this feature:
|
Looking forward to this being out! Can't find any other open source provider supporting this. |
22a2817
to
b8c598a
Compare
Hey folks 👋. Any plans to get it moving? Do you need any help? |
This PR adds the Device Auth Grant to Ory/Hydra
RFC: https://www.rfc-editor.org/rfc/rfc8628
Related issue(s)
This PR is related to #2416
See also fosite PR:
https://github.com/ory/fosite/pull/701/files
Checklist
introduces a new feature.
contributing code guidelines.
vulnerability. If this pull request addresses a security. vulnerability, I
confirm that I got green light (please contact
security@ory.sh) from the maintainers to push
the changes.
works.