Skip to content

Commit 15d8212

Browse files
author
Rebecka Gulliksson
committed
Improve finding access token in userinfo request.
If the token is contained in the request body, and the Authorization header is present but empty, the token could not be discovered. This simplification of extract_bearer_token_from_http_request(), ensures easier detection of this case.
1 parent 9a14c63 commit 15d8212

File tree

3 files changed

+16
-19
lines changed

3 files changed

+16
-19
lines changed

src/pyop/access_token.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,22 @@ def __init__(self, value, expires_in, typ=BEARER_TOKEN_TYPE):
1818
self.type = typ
1919

2020

21-
def extract_bearer_token_from_http_request(request=None, http_headers=None):
22-
# type (Optional[str], Optional[Mapping[str, str]] -> str
21+
def extract_bearer_token_from_http_request(parsed_request=None, authz_header=None):
22+
# type (Optional[Mapping[str, str]], Optional[str] -> str
2323
"""
2424
Extracts a Bearer token from an http request
25-
:param request: form-encoded request (URL query part of request body)
26-
:param http_headers: http request headers
25+
:param parsed_request: parsed request (URL query part of request body)
26+
:param authz_header: HTTP Authorization header
2727
:return: Bearer access token, if found
2828
:raise BearerTokenError: if no Bearer token could be extracted from the request
2929
"""
30-
if http_headers and 'Authorization' in http_headers:
30+
if authz_header:
3131
# Authorization Request Header Field: https://tools.ietf.org/html/rfc6750#section-2.1
32-
authz_header = http_headers['Authorization']
3332
if authz_header.startswith(AccessToken.BEARER_TOKEN_TYPE):
3433
access_token = authz_header[len(AccessToken.BEARER_TOKEN_TYPE) + 1:]
3534
logger.debug('found access token %s in authz header', access_token)
3635
return access_token
37-
elif request:
38-
parsed_request = dict(parse_qsl(request))
36+
elif parsed_request:
3937
if 'access_token' in parsed_request:
4038
"""
4139
Form-Encoded Body Parameter: https://tools.ietf.org/html/rfc6750#section-2.2, and

src/pyop/provider.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,10 @@ def handle_userinfo_request(self, request=None, http_headers=None):
407407
:param request: urlencoded request (either query string or POST body)
408408
:param http_headers: http headers
409409
"""
410-
bearer_token = extract_bearer_token_from_http_request(request, http_headers)
410+
if http_headers is None:
411+
http_headers = {}
412+
userinfo_request = dict(parse_qsl(request))
413+
bearer_token = extract_bearer_token_from_http_request(userinfo_request, http_headers.get('Authorization'))
411414

412415
introspection = self.authz_state.introspect_access_token(bearer_token)
413416
if not introspection['active']:

tests/pyop/test_access_token.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from urllib.parse import urlencode
2-
31
import pytest
42

53
from pyop.access_token import extract_bearer_token_from_http_request, BearerTokenError
@@ -9,24 +7,22 @@
97

108
class TestExtractBearerTokenFromHttpRequest(object):
119
def test_authorization_header(self):
12-
http_headers = {'Authorization': 'Bearer {}'.format(ACCESS_TOKEN)}
13-
assert extract_bearer_token_from_http_request(http_headers=http_headers) == ACCESS_TOKEN
10+
assert extract_bearer_token_from_http_request(authz_header='Bearer {}'.format(ACCESS_TOKEN)) == ACCESS_TOKEN
1411

1512
def test_non_bearer_authorization_header(self):
16-
http_headers = {'Authorization': 'Basic {}'.format(ACCESS_TOKEN)}
1713
with pytest.raises(BearerTokenError):
18-
extract_bearer_token_from_http_request(http_headers=http_headers)
14+
extract_bearer_token_from_http_request(authz_header='Basic {}'.format(ACCESS_TOKEN))
1915

20-
def test_access_token_in_urlencoded_request(self):
16+
def test_access_token_in_request(self):
2117
data = {
2218
'foo': 'bar',
2319
'access_token': ACCESS_TOKEN
2420
}
25-
assert extract_bearer_token_from_http_request(request=urlencode(data)) == ACCESS_TOKEN
21+
assert extract_bearer_token_from_http_request(data) == ACCESS_TOKEN
2622

27-
def test_urlencoded_request_without_access_token(self):
23+
def test_request_without_access_token(self):
2824
data = {
2925
'foo': 'bar',
3026
}
3127
with pytest.raises(BearerTokenError):
32-
extract_bearer_token_from_http_request(request=urlencode(data))
28+
extract_bearer_token_from_http_request(data)

0 commit comments

Comments
 (0)