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 support for multiple Apple public keys #321

Merged

Conversation

dstapleton92
Copy link
Contributor

This Sign In With Apple (SIWA) implementation has been failing intermittently. After some investigation, I have determined the cause of the intermittent failure. Before, Apple only provided a single public key in the array hosted at this url: https://appleid.apple.com/auth/keys.

The original author of this apple provider assumed (wish Apple had better docs!) there would only ever be one key, so always used keys[0]. Now, Apple has added 2 more keys (making 3 total). The correct procedure is to retrieve the key id (kid) from the header of the Apple JWT and then use the corresponding key from the keys array to verify the JWT.

I also removed a comment mentioning the need to fetch the keys from Apple less frequently by respecting the cache headers. The headers Apple sets on that response indicate that it should not be cached.

@dstapleton92
Copy link
Contributor Author

@mca312 In case you've been pulling your hair out over this like me...

@@ -100,12 +101,18 @@ func (s *Session) Authorize(provider goth.Provider, params goth.Params) (string,
}

// get the public key for verifying the identity token signature
// todo: respect Cache-Control header and retrieve this less frequently
set, err := jwk.FetchHTTP(idTokenVerificationKeyEndpoint, jwk.WithHTTPClient(p.httpClient))
set, err := jwk.FetchHTTP(idTokenVerificationKeyEndpoint, jwk.WithHTTPClient(p.Client()))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Switching this to use p.Client() so that the fallback client will be retrieved if one was not set during Apple controller initialization. This wasn't contributing to the problem but I do think it's a good change to make.

Copy link
Collaborator

@bentranter bentranter left a comment

Choose a reason for hiding this comment

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

Looks great to me – thanks for your hard work @dstapleton92!

@bentranter bentranter merged commit 7e4de08 into markbates:master Mar 5, 2020
@bentranter
Copy link
Collaborator

@mca312
Copy link

mca312 commented Mar 5, 2020

@dstapleton92 Thanks. I did something similar when verifying the JWT. But I'm doing this right before the session.Authorize

kid := t.Header["kid"]
jwk := set.LookupKeyID(kid.(string))
pubKeyIface, _ := jwk[0].Materialize()

@dstapleton92 dstapleton92 deleted the support-multiple-apple-keys branch March 5, 2020 17:40
@dstapleton92
Copy link
Contributor Author

Dang. Didn't know about set.LookupKeyID(...). Oh well. What I did is pretty similar to their implementation.

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

3 participants