-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Title: [OAuth2] Missing "accept" header in access_token request
Description:
The OAuth2 HTTP filter does not set the "Accept" header, but expects the server to return JSON.
This behavior is incompatible with GitHub's implementation of OAuth2: GitHub web application flow. It says:
By default, the response takes the following form:
access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&token_type=bearer
You can also receive the content in different formats depending on the Accept header to
application/json
GitHub will return a form / urlencoded response body that Envoy fails to interpret as JSON.
This traces back the OAuth2 client implementation, which fails to set the Accept header.
envoy/source/extensions/filters/http/oauth2/oauth_client.h
Lines 90 to 94 in dd0befa
| Http::RequestMessagePtr createPostRequest() { | |
| auto request = Http::Utility::prepareHeaders(uri_); | |
| request->headers().setReferenceMethod(Http::Headers::get().MethodValues.Post); | |
| request->headers().setContentType(Http::Headers::get().ContentTypeValues.FormUrlEncoded); | |
| return request; |
Repro steps:
- Set up OAuth2 filter according to docs
- Configure a GitHub OAuth app
Config:
not relevant
Logs:
[2020-12-30 00:10:03.907][122603][debug][upstream] [external/envoy/source/extensions/filters/http/oauth2/oauth_client.cc:43] Dispatching OAuth request for access token.
[2020-12-30 00:10:03.907][122603][debug][router] [external/envoy/source/common/router/router.cc:425] [C0][S5590288971988059178] cluster 'github-oauth' match for URL '/login/oauth/access_token'
[2020-12-30 00:10:03.907][122603][debug][router] [external/envoy/source/common/router/router.cc:582] [C0][S5590288971988059178] router decoding headers:
':path', '/login/oauth/access_token'
':authority', 'github.com'
':method', 'POST'
':scheme', 'https'
'content-type', 'application/x-www-form-urlencoded'
'x-envoy-internal', 'true'
'x-forwarded-for', <redacted>
'x-envoy-expected-rq-timeout-ms', '3000'
...
[2020-12-30 00:10:04.474][122603][debug][client] [external/envoy/source/common/http/codec_client.cc:112] [C1] response complete
[2020-12-30 00:10:04.475][122603][debug][upstream] [external/envoy/source/extensions/filters/http/oauth2/oauth_client.cc:83] Error parsing response body, received exception: Unable to parse JSON as proto (INVALID_ARGUMENT:Unexpected token.
access_token=xxxxx
^): access_token=xxxxxxxxxxxxxxxxxxxxxxx&scope=user&token_type=bearer
[2020-12-30 00:10:04.475][122603][debug][upstream] [external/envoy/source/extensions/filters/http/oauth2/oauth_client.cc:84] Response body: access_token=xxxxxxxxxxxxxxxxxxxxxxx&scope=user&token_type=bearer
On the bright side, Envoy is nearly able to complete an SSO flow with GitHub, it just fails to parse the last response. Incredible job by the devs of this plugin. 🙌🏻