Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Commit 999ec0e

Browse files
committed
The stricter crypto alg control has some effects.
1 parent 6b8ca57 commit 999ec0e

8 files changed

Lines changed: 463 additions & 163 deletions

File tree

chrp/config.py

Lines changed: 76 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
KEYDEFS = [
1818
{"type": "RSA", "key": '', "use": ["sig"]},
1919
{"type": "EC", "crv": "P-256", "use": ["sig"]}
20-
]
20+
]
2121

2222
PRIVATE_JWKS_PATH = "jwks_dir/jwks.json"
2323
PUBLIC_JWKS_PATH = 'static/jwks.json'
@@ -35,7 +35,7 @@
3535
"scope": ["openid", "profile", "email", "address", "phone"],
3636
"token_endpoint_auth_method": ["client_secret_basic", 'client_secret_post'],
3737
'services': SERVICES
38-
}
38+
}
3939

4040
# The keys in this dictionary are the OPs short user friendly name
4141
# not the issuer (iss) name.
@@ -55,8 +55,8 @@
5555
'AccessToken': {},
5656
'RefreshAccessToken': {},
5757
'UserInfo': {}
58-
}
59-
},
58+
}
59+
},
6060
# Supports OP information lookup but not client registration
6161
"google": {
6262
"issuer": "https://accounts.google.com/",
@@ -68,19 +68,19 @@
6868
"scope": ["openid", "profile", "email"],
6969
"token_endpoint_auth_method": ["client_secret_basic",
7070
'client_secret_post']
71-
},
71+
},
7272
"allow": {
7373
"issuer_mismatch": True
74-
},
74+
},
7575
# "userinfo_request_method": "GET",
7676
"services": {
7777
'ProviderInfoDiscovery': {},
7878
'Authorization': {},
7979
'AccessToken': {},
8080
'RefreshAccessToken': {},
8181
'UserInfo': {}
82-
}
83-
},
82+
}
83+
},
8484
"linkedin": {
8585
"issuer": "https://www.linkedin.com/oauth/v2/",
8686
"client_id": "xxxxxxx",
@@ -90,27 +90,27 @@
9090
"response_types": ["code"],
9191
"scope": ["r_basicprofile", "r_emailaddress"],
9292
"token_endpoint_auth_method": ['client_secret_post']
93-
},
93+
},
9494
"provider_info": {
9595
"authorization_endpoint":
9696
"https://www.linkedin.com/oauth/v2/authorization",
9797
"token_endpoint": "https://www.linkedin.com/oauth/v2/accessToken",
9898
"userinfo_endpoint":
9999
"https://api.linkedin.com/v1/people/~?format=json"
100-
},
100+
},
101101
'services': {
102102
'Authorization': {},
103103
'linkedin.AccessToken': {},
104104
'linkedin.UserInfo': {}
105-
}
106-
},
105+
}
106+
},
107107
"facebook": {
108108
"issuer": "https://www.facebook.com/v2.11/dialog/oauth",
109109
"behaviour": {
110110
"response_types": ["code"],
111111
"scope": ["email", "public_profile"],
112112
"token_endpoint_auth_method": ['']
113-
},
113+
},
114114
"redirect_uris": ["{}/authz_cb/facebook".format(BASEURL)],
115115
"provider_info": {
116116
"authorization_endpoint":
@@ -119,13 +119,13 @@
119119
"https://graph.facebook.com/v2.11/oauth/access_token",
120120
"userinfo_endpoint":
121121
"https://graph.facebook.com/me"
122-
},
122+
},
123123
'services': {
124124
'Authorization': {},
125125
'AccessToken': {'default_authn_method': ''},
126-
'UserInfo': {'default_authn_method':''}
127-
}
128-
},
126+
'UserInfo': {'default_authn_method': ''}
127+
}
128+
},
129129
'github': {
130130
"issuer": "https://github.com/login/oauth/authorize",
131131
'client_id': 'eeeeeeeee',
@@ -135,21 +135,21 @@
135135
"response_types": ["code"],
136136
"scope": ["user", "public_repo"],
137137
"token_endpoint_auth_method": ['']
138-
},
138+
},
139139
"provider_info": {
140140
"authorization_endpoint":
141141
"https://github.com/login/oauth/authorize",
142142
"token_endpoint":
143143
"https://github.com/login/oauth/access_token",
144144
"userinfo_endpoint":
145145
"https://api.github.com/user"
146-
},
146+
},
147147
'services': {
148148
'Authorization': {},
149149
'AccessToken': {},
150150
'UserInfo': {'default_authn_method': ''}
151-
}
152-
},
151+
}
152+
},
153153
"salesforce": {
154154
"issuer": "https://login.salesforce.com",
155155
"client_id": "xxxxxxxxx.yyy",
@@ -160,7 +160,7 @@
160160
"scope": ["openid", "profile", "email"],
161161
"token_endpoint_auth_method": ["client_secret_basic",
162162
'client_secret_post']
163-
},
163+
},
164164
# "allow": {
165165
# "issuer_mismatch": True
166166
# },
@@ -171,9 +171,9 @@
171171
'AccessToken': {},
172172
'RefreshAccessToken': {},
173173
'UserInfo': {}
174-
},
174+
},
175175
"keys": {'file': {"https://login.salesforce.com": 'salesforce.jwks'}}
176-
},
176+
},
177177
"okta": {
178178
"issuer": "https://dev-968755.oktapreview.com/",
179179
"client_id": "123456789",
@@ -184,7 +184,7 @@
184184
"scope": ["openid", "profile", "email"],
185185
"token_endpoint_auth_method": ["client_secret_basic",
186186
'client_secret_post']
187-
},
187+
},
188188
"provider_info": {
189189
"authorization_endpoint":
190190
"https://dev-968755.oktapreview.com/oauth2/default/v1"
@@ -193,15 +193,64 @@
193193
"https://dev-968755.oktapreview.com/oauth2/default/v1/token",
194194
"userinfo_endpoint":
195195
"https://dev-968755.oktapreview.com/oauth2/v1/userinfo"
196-
},
196+
},
197197
# "userinfo_request_method": "GET",
198198
"services": {
199199
'Authorization': {},
200200
'AccessToken': {},
201201
'UserInfo': {}
202+
}
203+
},
204+
'microsoft': {
205+
'issuer': 'https://login.microsoftonline.com/<UUID>>/v2.0',
206+
'client_id': '1234567890',
207+
'client_secret': 'abcdefghijklmnop',
208+
"redirect_uris": ["{}/authz_cb/microsoft".format(BASEURL)],
209+
"client_preferences": {
210+
"response_types": ["id_token"],
211+
"scope": ["openid"],
212+
"token_endpoint_auth_method": ["private_key_jwt",
213+
'client_secret_post'],
214+
"response_mode": 'form_post'
215+
},
216+
"allow": {
217+
"issuer_mismatch": True
218+
},
219+
"services": {
220+
'ProviderInfoDiscovery',
221+
'Authorization'
222+
}
223+
},
224+
"aws": {
225+
"issuer": "https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1",
226+
'client_id': '1234567890',
227+
'client_secret': 'abcdefghijklmnop',
228+
"redirect_uris": ["{}/authz_cb/aws".format(BASEURL)],
229+
"behaviour": {
230+
"response_types": ["code"],
231+
"scope": ["email", "openid"],
232+
"token_endpoint_auth_method": ['']
233+
},
234+
"provider_info": {
235+
"authorization_endpoint":
236+
"https://catalogix.auth.eu-central-1.amazoncognito.com/oauth2"
237+
"/authorize",
238+
"token_endpoint":
239+
"https://catalogix.auth.eu-central-1.amazoncognito.com/oauth2"
240+
"/token"
241+
},
242+
'services': {
243+
'Authorization': {},
244+
'AccessToken': {}
245+
},
246+
'keys': {
247+
'url': {
248+
'https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1':
249+
'https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1/.well-known/jwks.json'
250+
}
251+
}
202252
}
203253
}
204-
}
205254

206255
# Whether an attempt to fetch the userinfo should be made
207256
USERINFO = True

chrp/utils.py

Whitespace-only changes.

src/oidcrp/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,10 @@ def do_client_registration(self, client=None, iss_id='', state=''):
284284
client.service_context.post_logout_redirect_uris
285285
except AttributeError:
286286
client.service_context.post_logout_redirect_uris = [self.base_url]
287+
else:
288+
if not client.service_context.post_logout_redirect_uris:
289+
client.service_context.post_logout_redirect_uris = [
290+
self.base_url]
287291

288292
if not client.service_context.client_id:
289293
load_registration_response(client)

src/oidcrp/http.py

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,30 @@ def _cookies(self):
7575

7676
return cookie_dict
7777

78+
def add_cookies(self, kwargs):
79+
if self.cookiejar:
80+
kwargs["cookies"] = self._cookies()
81+
logger.debug("SENT {} COOKIES".format(len(kwargs["cookies"])))
82+
return kwargs
83+
84+
def run_req_callback(self, url, method, kwargs):
85+
if self.req_callback is not None:
86+
kwargs = self.req_callback(method, url, **kwargs)
87+
return kwargs
88+
89+
def set_cookie(self, response):
90+
try:
91+
_cookie = response.headers["set-cookie"]
92+
logger.debug("RECEIVED COOKIE")
93+
try:
94+
# add received cookies to the cookie jar
95+
set_cookie(self.cookiejar, SimpleCookie(_cookie))
96+
except CookieError as err:
97+
logger.error(err)
98+
raise NonFatalException(response, "{}".format(err))
99+
except (AttributeError, KeyError) as err:
100+
pass
101+
78102
def __call__(self, url, method="GET", **kwargs):
79103
"""
80104
Send a HTTP request to a URL using a specified method
@@ -91,14 +115,11 @@ def __call__(self, url, method="GET", **kwargs):
91115
_kwargs.update(kwargs)
92116

93117
# If I have cookies add them all to the request
94-
if self.cookiejar:
95-
_kwargs["cookies"] = self._cookies()
96-
logger.debug("SENT {} COOKIES".format(len(_kwargs["cookies"])))
118+
self.add_cookies(kwargs)
97119

98120
# If I want to modify the request arguments based on URL, method
99121
# and current arguments I can use this call back function.
100-
if self.req_callback is not None:
101-
_kwargs = self.req_callback(method, url, **_kwargs)
122+
self.run_req_callback(url, method, kwargs)
102123

103124
try:
104125
# Do the request
@@ -112,17 +133,7 @@ def __call__(self, url, method="GET", **kwargs):
112133
if self.events is not None:
113134
self.events.store('HTTP response', r, ref=url)
114135

115-
try:
116-
_cookie = r.headers["set-cookie"]
117-
logger.debug("RECEIVED COOKIE")
118-
try:
119-
# add received cookies to the cookie jar
120-
set_cookie(self.cookiejar, SimpleCookie(_cookie))
121-
except CookieError as err:
122-
logger.error(err)
123-
raise NonFatalException(r, "{}".format(err))
124-
except (AttributeError, KeyError) as err:
125-
pass
136+
self.set_cookie(r)
126137

127138
# return the response
128139
return r

tests/test_04_http.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import os
2+
from http.cookies import SimpleCookie
3+
4+
import pytest
5+
6+
from oidcrp.cookie import CookieDealer
7+
from oidcrp.http import HTTPLib
8+
from oidcrp.util import set_cookie
9+
10+
_dirname = os.path.dirname(os.path.abspath(__file__))
11+
12+
CLIENT_CERT = open(os.path.join(_dirname, "data", "keys",'cert.key')).read()
13+
CA_CERT = open(os.path.join(_dirname, "data", "keys",'cacert.pem')).read()
14+
15+
16+
@pytest.fixture
17+
def cookie_dealer():
18+
class DummyServer():
19+
def __init__(self):
20+
self.symkey = b"0123456789012345"
21+
22+
return CookieDealer(DummyServer())
23+
24+
25+
def test_ca_cert():
26+
with pytest.raises(ValueError):
27+
HTTPLib(CA_CERT, False, CLIENT_CERT)
28+
29+
_h = HTTPLib(CA_CERT, True, CLIENT_CERT)
30+
assert _h.request_args["verify"] == CA_CERT
31+
32+
33+
def test_cookie(cookie_dealer):
34+
cookie_value = "Something to pass along"
35+
cookie_typ = "sso"
36+
cookie_name = "Foobar"
37+
38+
kaka = cookie_dealer.create_cookie(cookie_value, cookie_typ,
39+
cookie_name)
40+
_h = HTTPLib()
41+
set_cookie(_h.cookiejar, SimpleCookie(kaka[1]))
42+
43+
res = _h._cookies()
44+
assert set(res.keys()) == {'Foobar'}
45+
46+
kwargs = _h.add_cookies({})
47+
assert 'cookies' in kwargs
48+
assert set(kwargs['cookies'].keys()) == {'Foobar'}
49+
50+
51+
class DummyResponse(object):
52+
def __init__(self, status_code, data, headers):
53+
self.status_code = status_code
54+
self.data = data
55+
self.headers = headers
56+
57+
58+
def test_set_cookie(cookie_dealer):
59+
cookie_value = "Something to pass along"
60+
cookie_typ = "sso"
61+
cookie_name = "Foobar"
62+
63+
kaka = cookie_dealer.create_cookie(cookie_value, cookie_typ,
64+
cookie_name)
65+
66+
_h = HTTPLib()
67+
response = DummyResponse(200, 'OK', {"set-cookie": kaka[1]})
68+
_h.set_cookie(response)
69+
70+
res = _h._cookies()
71+
assert set(res.keys()) == {'Foobar'}

0 commit comments

Comments
 (0)