|
3 | 3 |
|
4 | 4 | import json
|
5 | 5 | try:
|
6 |
| - from urllib.parse import urlencode, parse_qs |
| 6 | + from urllib.parse import urlencode, parse_qs, quote_plus |
7 | 7 | except ImportError:
|
8 | 8 | from urlparse import parse_qs
|
9 |
| - from urllib import urlencode |
| 9 | + from urllib import urlencode, quote_plus |
10 | 10 | import logging
|
11 | 11 | import warnings
|
12 | 12 | import time
|
@@ -181,9 +181,14 @@ def _obtain_token( # The verb "obtain" is influenced by OAUTH2 RFC 6749
|
181 | 181 | # client credentials in the request-body using the following
|
182 | 182 | # parameters: client_id, client_secret.
|
183 | 183 | if self.client_secret and self.client_id:
|
184 |
| - _headers["Authorization"] = "Basic " + base64.b64encode( |
185 |
| - "{}:{}".format(self.client_id, self.client_secret) |
186 |
| - .encode("ascii")).decode("ascii") |
| 184 | + _headers["Authorization"] = "Basic " + base64.b64encode("{}:{}".format( |
| 185 | + # Per https://tools.ietf.org/html/rfc6749#section-2.3.1 |
| 186 | + # client_id and client_secret needs to be encoded by |
| 187 | + # "application/x-www-form-urlencoded" |
| 188 | + # https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1 |
| 189 | + # BEFORE they are fed into HTTP Basic Authentication |
| 190 | + quote_plus(self.client_id), quote_plus(self.client_secret) |
| 191 | + ).encode("ascii")).decode("ascii") |
187 | 192 |
|
188 | 193 | if "token_endpoint" not in self.configuration:
|
189 | 194 | raise ValueError("token_endpoint not found in configuration")
|
|
0 commit comments