Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion auth_oidc/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

{
"name": "Authentication OpenID Connect",
"version": "12.0.1.1.0",
"version": "12.0.1.2.0",
"license": "AGPL-3",
"author": (
"ICTSTUDIO, André Schenkels, "
Expand Down
44 changes: 29 additions & 15 deletions auth_oidc/models/auth_oauth_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

try:
from jose import jwt
from jose.exceptions import JWTError, JWSError
except ImportError:
logging.getLogger(__name__).debug("jose library not installed")

Expand Down Expand Up @@ -51,14 +52,15 @@ class AuthOauthProvider(models.Model):
)

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

def _map_token_values(self, res):
if self.token_map:
Expand All @@ -72,19 +74,31 @@ def _parse_id_token(self, id_token, access_token):
self.ensure_one()
res = {}
header = jwt.get_unverified_header(id_token)
res.update(
jwt.decode(
id_token,
self._get_key(header.get("kid")),
algorithms=["RS256"],
audience=self.client_id,
access_token=access_token,
)
)

res.update(self._decode_id_token(access_token, id_token, header.get("kid")))
res.update(self._map_token_values(res))
return res

def _decode_id_token(self, access_token, id_token, kid):
keys = self._get_keys(kid)
if len(keys) > 1 and kid is None:
# https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.10.1
# If there are multiple keys in the referenced JWK Set document, a kid
# value MUST be provided in the JOSE Header.
raise JWTError("OpenID Connect requires kid to be set if there is more"
" than one key in the JWKS")
error = None
# we accept multiple keys with the same kid in case a key gets rotated.
for key in keys:
Comment thread
ap-wtioit marked this conversation as resolved.
try:
values = jwt.decode(id_token, key, algorithms=["RS256"],
audience=self.client_id, access_token=access_token)
return values
except (JWTError, JWSError) as e:
error = e
if error:
raise error
return {}


class AuthOauthProviderGroupLine(models.Model):
_name = 'auth.oauth.provider.group_line'
Expand Down
7 changes: 6 additions & 1 deletion auth_oidc/models/res_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ def auth_oauth(self, provider, params):
).json()
validation.update(data)
# required check
if not validation.get("user_id"):
if "sub" in validation and "user_id" not in validation:
# set user_id for auth_oauth, user_id is not an OpenID Connect standard
# claim:
# https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
validation["user_id"] = validation["sub"]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a useful improvement, thanks.

elif not validation.get("user_id"):
_logger.error("user_id claim not found in id_token (after mapping).")
raise AccessDenied()
# retrieve and sign in user
Expand Down
1 change: 1 addition & 0 deletions auth_oidc/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
* Alexandre Fayolle <alexandre.fayolle@camptocamp.com>
* Stéphane Bidoul <stephane.bidoul@acsone.eu>
* Andreas Perhab <andreas.perhab@wt-io-it.at>
21 changes: 21 additions & 0 deletions auth_oidc/readme/HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
12.0.1.2.0 2022-11-22
~~~~~~~~~~~~~~~~~~~~~

* Fix handling OpenID Connect responses without custom mapping by using the ``sub`` claim as user id
* Fix handling OpenID Connect ID Tokens without Key ID (``kid``)

12.0.1.1.0 2022-11-22
~~~~~~~~~~~~~~~~~~~~~

* Enable allowing assigning groups from token claims

12.0.1.0.1 2022-02-28
~~~~~~~~~~~~~~~~~~~~~

* Updated readme and pot

12.0.1.0.0 2022-02-12
~~~~~~~~~~~~~~~~~~~~~

* Backport to Odoo 12

13.0.1.0.0 2020-04-10
~~~~~~~~~~~~~~~~~~~~~

Expand Down
Loading