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

Add userinfo_endpoint #1454

Closed
wants to merge 4 commits into from
Closed

Conversation

mdbraber
Copy link
Contributor

Supersedes #1453

This was referenced May 27, 2019
@mdbraber
Copy link
Contributor Author

@srenatus would be great if you could take a look at this (build checks out)!

@mdbraber mdbraber changed the title Add user endpoint Add userinfo_endpoint May 27, 2019
@srenatus
Copy link
Contributor

I'll try to get this in this week 🤞

@srenatus
Copy link
Contributor

srenatus commented Jun 3, 2019

Sorry about that. This week it is, then. 😅

Copy link
Contributor

@srenatus srenatus left a comment

Choose a reason for hiding this comment

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

This is looking good so far -- thank you!

Besides my inline commits, a few points of note:

Thanks again! 😃

@@ -265,6 +265,11 @@ type federatedIDClaims struct {
UserID string `json:"user_id,omitempty"`
}

func (s *Server) newAccessToken(clientID string, claims storage.Claims, scopes []string, nonce, connID string) (accessToken string, err error) {
idToken, _, err := s.newIDToken(clientID, claims, scopes, nonce, storage.NewID(), connID)
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm! So we'll be using a JWT for access_token... but it's a different one; we don't hand out the same we give as id_token. 💭

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe @jackielii can answer this one?

Copy link
Contributor

Choose a reason for hiding this comment

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

Like in my original PR comment: "this is a stop gap solution". In my understanding, access_token is a "key" that should be saved away and later used to retrieve "user_info". Here I'm abusing the ID token signature verification: Use an ID token as the access token, and use signature verification to verify the JWT and just return the claims as the user_info response.

Because the access_token is opaque to the user, so this change is forward compatible with the "proper solution". I even created this function to later swap out for the proper "save to db" solution.

Copy link
Contributor

Choose a reason for hiding this comment

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

@srenatus sorry forgot to answer your original question. Within one auth request, the id_token won't be exactly the same as the access_token, albeit access_token looks and "can" behave like a jwt id_token. We're just abusing the fact that access_token is just a "random string".

Copy link
Contributor

Choose a reason for hiding this comment

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

Quite clever! And thanks for considering "forward compat with a proper solution" 😄

return nil, fmt.Errorf("unable to parse signed message")
}

// Parse the message to check expiry, as it jose doesn't distinguish expiry error from others
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand how the comment relates to the code below. 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This might be me - doing some too agressive butchering of the code. Sorry.

// Parse the message to check expiry, as it jose doesn't distinguish expiry error from others
parts := strings.Split(token, ".")
if len(parts) != 3 {
return nil, fmt.Errorf("square/go-jose: compact JWS format must have three parts")
Copy link
Contributor

Choose a reason for hiding this comment

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

Also, we should probably not claim we're square/go-jose. We aren't 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well that seems an easy one to fix

@mdbraber
Copy link
Contributor Author

mdbraber commented Jun 5, 2019

This is looking good so far -- thank you!

Thanks for taking the time to review!

  • Would you mind throwing in a test or three for the new HTTP handler, please?

I'm not proficient in writing any sort of tests so that'll take me a lot of figuring out, I'm happy to try if someone might have some pointers how to do this.

Well I think @jackielii did most of the work as it's their patch. I only butchered the patch to make it fit the current code base :-) Happy to add a Co-authored line on the relevant commit. Massaging the history seems more work so I'll just do the first.

So it seems, so more hat tips for everyone :-) 🎩

@jackielii
Copy link
Contributor

@mdbraber & @srenatus absolutely. Feel free to use my name or otherwise, no probs for me. I was lazy and looking for a solution hastily, and just figured this trick should be the easiest one without changing too much. It utilises existing id_token signature verification mechanism to implement the access_token + user_info verification. It has been in semi-production in our internal system for since I submitted the other PR over a year ago.

BTW, I realised on that my PR wasn't similar to the original #1133 . That one I still couldn't fully understand, and mine definitely took a different approach. But it helped to understand the code base a bit better.

Thanks & Regards,

return nil, err
}

// TODO: check other claims
Copy link
Contributor

Choose a reason for hiding this comment

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

This could be a "big" TODO. I realised later on that the jose or any other JWT token lib should do all the checks, but I'm not sure they do all the needed. Or maybe they do, and I'm just being over paranoid here to check again. Need a JWT expert or jose expert here to answer the question.

mdbraber and others added 4 commits June 5, 2019 22:11
@mdbraber mdbraber force-pushed the add-user-endpoint branch from e6f4c27 to 3dd1bac Compare June 5, 2019 20:15
@mdbraber
Copy link
Contributor Author

mdbraber commented Jun 5, 2019

Added the right attribution: added Co-authored-by to @jackielii and @fjbsantiago acknowledging their work.

@srenatus
Copy link
Contributor

srenatus commented Jun 8, 2019

I'm not proficient in writing any sort of tests so that'll take me a lot of figuring out, I'm happy to try if someone might have some pointers how to do this.

https://github.com/dexidp/dex/blob/master/server/server_test.go has some tests that could be added to or expanded, I suppose. LMK if you need help. 😃

@alindeman
Copy link
Contributor

How's this coming along? Is there anything I can do to help? I'd like to see this land in Dex so I can better integrate it with services like AWS ALBs that require userinfo endpoints.

@srenatus
Copy link
Contributor

@alindeman This needs tests. If you'd like to contribute, you could PR against mdbraber:add-user-endpoint or a open a new one against dexidp/dex with these commits included. (We can then merge this PR first and rebase the other one then.)

@alindeman
Copy link
Contributor

@alindeman This needs tests. If you'd like to contribute, you could PR against mdbraber:add-user-endpoint or a open a new one against dexidp/dex with these commits included. (We can then merge this PR first and rebase the other one then.)

Sounds good. I will plan to tackle adding some tests tomorrow.

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.

4 participants