Skip to content

Commit 092473a

Browse files
authored
Merge pull request OCA#436 from ap-wtioit/12.0-auth_oidc_fixes
[12.0] auth_oidc: fixes
2 parents ff1978e + 00dc648 commit 092473a

File tree

6 files changed

+283
-37
lines changed

6 files changed

+283
-37
lines changed

auth_oidc/__manifest__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
{
66
"name": "Authentication OpenID Connect",
7-
"version": "12.0.1.1.0",
7+
"version": "12.0.1.2.0",
88
"license": "AGPL-3",
99
"author": (
1010
"ICTSTUDIO, André Schenkels, "

auth_oidc/models/auth_oauth_provider.py

+29-15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
try:
1414
from jose import jwt
15+
from jose.exceptions import JWTError, JWSError
1516
except ImportError:
1617
logging.getLogger(__name__).debug("jose library not installed")
1718

@@ -51,14 +52,15 @@ class AuthOauthProvider(models.Model):
5152
)
5253

5354
@tools.ormcache("self.jwks_uri", "kid")
54-
def _get_key(self, kid):
55+
def _get_keys(self, kid):
5556
r = requests.get(self.jwks_uri)
5657
r.raise_for_status()
5758
response = r.json()
58-
for key in response["keys"]:
59-
if key["kid"] == kid:
60-
return key
61-
return {}
59+
# the keys returned here should follow
60+
# JWS Notes on Key Selection
61+
# https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-signature#appendix-D
62+
return [key for key in response["keys"]
63+
if kid is None or key.get("kid", None) == kid]
6264

6365
def _map_token_values(self, res):
6466
if self.token_map:
@@ -72,19 +74,31 @@ def _parse_id_token(self, id_token, access_token):
7274
self.ensure_one()
7375
res = {}
7476
header = jwt.get_unverified_header(id_token)
75-
res.update(
76-
jwt.decode(
77-
id_token,
78-
self._get_key(header.get("kid")),
79-
algorithms=["RS256"],
80-
audience=self.client_id,
81-
access_token=access_token,
82-
)
83-
)
84-
77+
res.update(self._decode_id_token(access_token, id_token, header.get("kid")))
8578
res.update(self._map_token_values(res))
8679
return res
8780

81+
def _decode_id_token(self, access_token, id_token, kid):
82+
keys = self._get_keys(kid)
83+
if len(keys) > 1 and kid is None:
84+
# https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.10.1
85+
# If there are multiple keys in the referenced JWK Set document, a kid
86+
# value MUST be provided in the JOSE Header.
87+
raise JWTError("OpenID Connect requires kid to be set if there is more"
88+
" than one key in the JWKS")
89+
error = None
90+
# we accept multiple keys with the same kid in case a key gets rotated.
91+
for key in keys:
92+
try:
93+
values = jwt.decode(id_token, key, algorithms=["RS256"],
94+
audience=self.client_id, access_token=access_token)
95+
return values
96+
except (JWTError, JWSError) as e:
97+
error = e
98+
if error:
99+
raise error
100+
return {}
101+
88102

89103
class AuthOauthProviderGroupLine(models.Model):
90104
_name = 'auth.oauth.provider.group_line'

auth_oidc/models/res_users.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@ def auth_oauth(self, provider, params):
7070
).json()
7171
validation.update(data)
7272
# required check
73-
if not validation.get("user_id"):
73+
if "sub" in validation and "user_id" not in validation:
74+
# set user_id for auth_oauth, user_id is not an OpenID Connect standard
75+
# claim:
76+
# https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
77+
validation["user_id"] = validation["sub"]
78+
elif not validation.get("user_id"):
7479
_logger.error("user_id claim not found in id_token (after mapping).")
7580
raise AccessDenied()
7681
# retrieve and sign in user

auth_oidc/readme/CONTRIBUTORS.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
* Alexandre Fayolle <alexandre.fayolle@camptocamp.com>
22
* Stéphane Bidoul <stephane.bidoul@acsone.eu>
3+
* Andreas Perhab <andreas.perhab@wt-io-it.at>

auth_oidc/readme/HISTORY.rst

+21
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
12.0.1.2.0 2022-11-22
2+
~~~~~~~~~~~~~~~~~~~~~
3+
4+
* Fix handling OpenID Connect responses without custom mapping by using the ``sub`` claim as user id
5+
* Fix handling OpenID Connect ID Tokens without Key ID (``kid``)
6+
7+
12.0.1.1.0 2022-11-22
8+
~~~~~~~~~~~~~~~~~~~~~
9+
10+
* Enable allowing assigning groups from token claims
11+
12+
12.0.1.0.1 2022-02-28
13+
~~~~~~~~~~~~~~~~~~~~~
14+
15+
* Updated readme and pot
16+
17+
12.0.1.0.0 2022-02-12
18+
~~~~~~~~~~~~~~~~~~~~~
19+
20+
* Backport to Odoo 12
21+
122
13.0.1.0.0 2020-04-10
223
~~~~~~~~~~~~~~~~~~~~~
324

0 commit comments

Comments
 (0)