Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e89d615
[ADD] auth_jwt
sbidoul Apr 28, 2021
ee28d5b
auth_jwt: use PyJWT instead of python-jose
sbidoul Apr 28, 2021
45d557b
auth_jwt: add signature algorithms
sbidoul Apr 28, 2021
251fdf1
auth_jwt: support multiple audiences
sbidoul Apr 28, 2021
5500ce4
auth_jwt: add nbf validation test
sbidoul Apr 28, 2021
e53bbbd
auth_jwt: docs clarification and fixes
sbidoul Apr 29, 2021
ea72ddf
auth_jwt: fix jwks URI support
sbidoul Jun 25, 2021
a4ae6d2
auth_jwt: mock instead of committing in tests
sbidoul Jul 25, 2021
f80b225
auth_jwt: more precise precondition check
sbidoul Jul 26, 2021
e6502a4
Rename auth_jwt_test to auth_jwt_demo
sbidoul Jul 26, 2021
d04c6e2
[MIG] auth_jwt
sbidoul Jun 27, 2021
4a4a7c7
[UPD] Update auth_jwt.pot
oca-travis Jul 28, 2021
fac791f
[UPD] README.rst
OCA-git-bot Jul 28, 2021
d5857c1
auth_jwt 14.0.1.0.1
OCA-git-bot Jul 28, 2021
1c07dc7
[IMP] auth_jwt: add public_or_jwt auth method
sbidoul Oct 5, 2021
16aa844
[UPD] README.rst
OCA-git-bot Oct 6, 2021
2b51cf6
auth_jwt 14.0.1.1.0
OCA-git-bot Oct 6, 2021
00c25eb
auth_jwt: Relicence under LGPL
yankinmax Dec 29, 2021
41d46ae
auth_jwt 14.0.1.2.0
OCA-git-bot Dec 29, 2021
916f0f0
[IMP] auth_jwt: Add validator.next_validator_id to allow validator ch…
paradoxxxzero Feb 17, 2022
20e7f81
[UPD] Update auth_jwt.pot
Jun 14, 2022
f8ef47f
auth_jwt 14.0.2.0.0
OCA-git-bot Jun 14, 2022
8ca423c
Rename auth_jwt_test to auth_jwt_demo
sbidoul Jul 26, 2021
793049f
[MIG] auth_jwt
sbidoul Jun 27, 2021
d7992de
[UPD] Update auth_jwt_demo.pot
oca-travis Jul 28, 2021
0322b72
[UPD] README.rst
OCA-git-bot Jul 28, 2021
88f6df5
auth_jwt_demo 14.0.1.0.1
OCA-git-bot Jul 28, 2021
3651c75
[IMP] auth_jwt: add public_or_jwt auth method
sbidoul Oct 5, 2021
5eed01a
auth_jwt_demo 14.0.1.1.0
OCA-git-bot Oct 6, 2021
af19735
auth_jwt_demo: Relicence under LGPL
yankinmax Dec 29, 2021
7529708
auth_jwt_demo 14.0.1.2.0
OCA-git-bot Dec 29, 2021
c2d4b4e
[MIG] auth_jwt from 14 to 16
sbidoul Jun 6, 2023
845ffac
[MIG] auth_jwt_demo from 14 to 16
sbidoul Jun 6, 2023
35f4fd6
[MIG] auth_jwt: convert unit tests to integration tests
sbidoul Jun 6, 2023
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: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# ignore demo js code
auth_jwt_demo/tests/spa/js/*.js
145 changes: 145 additions & 0 deletions auth_jwt/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
========
Auth JWT
========

.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github
:target: https://github.com/OCA/server-auth/tree/14.0/auth_jwt
:alt: OCA/server-auth
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-auth-14-0/server-auth-14-0-auth_jwt
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/251/14.0
:alt: Try me on Runbot

|badge1| |badge2| |badge3| |badge4| |badge5|

JWT bearer token authentication.

**Table of contents**

.. contents::
:local:

Installation
============

This module requires the ``pyjwt`` library to be installed.

Usage
=====

This module lets developpers add a new ``jwt`` authentication method on Odoo
controller routes.

To use it, you must:

* Create an ``auth.jwt.validator`` record to configure how the JWT token will
be validated.
* Add an ``auth="jwt_{validator-name}"`` or ``auth="public_or_jwt_{validator-name}"``
attribute to the routes you want to protect where ``{validator-name}`` corresponds to
the name attribute of the JWT validator record.

The ``auth_jwt_demo`` module provides examples.

The JWT validator can be configured with the following properties:

* ``name``: the validator name, to match the ``auth="jwt_{validator-name}"``
route property.
* ``audience``: a comma-separated list of allowed audiences, used to validate
the ``aud`` claim.
* ``issuer``: used to validate the ``iss`` claim.
* Signature type (secret or public key), algorithm, secret and JWK URI
are used to validate the token signature.

In addition, the ``exp`` claim is validated to reject expired tokens.

If the ``Authorization`` HTTP header is missing, malformed, or contains
an invalid token, the request is rejected with a 401 (Unauthorized) code.

If the token is valid, the request executes with the configured user id. By
default the user id selection strategy is ``static`` (i.e. the same for all
requests) and the selected user is configured on the JWT validator. Additional
strategies can be provided by overriding the ``_get_uid()`` method and
extending the ``user_id_strategy`` selection field.

The selected user is *not* stored in the session. It is only available in
``request.uid`` (and thus it is the one used in ``request.env``). To avoid any
confusion and mismatches between the bearer token and the session, this module
rejects requests made with an authenticated user session.

Additionally, if a ``partner_id_strategy`` is configured, a partner is searched
and if found, its id is stored in the ``request.jwt_partner_id`` attribute. If
``partner_id_required`` is set, a 401 (Unauthorized) is returned if no partner
was found. Otherwise ``request.jwt_partner_id`` is left falsy. Additional
strategies can be provided by overriding the ``_get_partner_id()`` method
and extending the ``partner_id_strategy`` selection field.

The decoded JWT payload is stored in ``request.jwt_payload``.

The ``public_auth_jwt`` method delegates authentication to the standard Odoo ``public``
method when the Authorization header is not set. If it is set, the regular JWT
authentication is performed as described above. This method is useful for public
endpoints that need to work for anonymous users, but can be enhanced when an
authenticated user is know. A typical use case is a "add to cart" endpoint that can work
for anonymous users, but can be enhanced by binding the cart to a known customer when
the authenticated user is known.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-auth/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/server-auth/issues/new?body=module:%20auth_jwt%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* ACSONE SA/NV

Contributors
~~~~~~~~~~~~

* Stéphane Bidoul <stephane.bidoul@acsone.eu>

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-sbidoul| image:: https://github.com/sbidoul.png?size=40px
:target: https://github.com/sbidoul
:alt: sbidoul

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-sbidoul|

This module is part of the `OCA/server-auth <https://github.com/OCA/server-auth/tree/14.0/auth_jwt>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions auth_jwt/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
17 changes: 17 additions & 0 deletions auth_jwt/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2021 ACSONE SA/NV
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

{
"name": "Auth JWT",
"summary": """
JWT bearer token authentication.""",
"version": "16.0.1.0.0",
"license": "LGPL-3",
"author": "ACSONE SA/NV,Odoo Community Association (OCA)",
"maintainers": ["sbidoul"],
"website": "https://github.com/OCA/server-auth",
"depends": [],
"external_dependencies": {"python": ["pyjwt", "cryptography"]},
"data": ["security/ir.model.access.csv", "views/auth_jwt_validator_views.xml"],
"demo": [],
}
46 changes: 46 additions & 0 deletions auth_jwt/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2021 ACSONE SA/NV
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl)

from werkzeug.exceptions import InternalServerError, Unauthorized


class UnauthorizedMissingAuthorizationHeader(Unauthorized):
pass


class UnauthorizedMalformedAuthorizationHeader(Unauthorized):
pass


class UnauthorizedSessionMismatch(Unauthorized):
pass


class AmbiguousJwtValidator(InternalServerError):
pass


class JwtValidatorNotFound(InternalServerError):
pass


class UnauthorizedInvalidToken(Unauthorized):
pass


class UnauthorizedPartnerNotFound(Unauthorized):
pass


class CompositeJwtError(Unauthorized):
"""Indicate that multiple errors occurred during JWT chain validation."""

def __init__(self, errors):
self.errors = errors
super().__init__(
"Multiple errors occurred during JWT chain validation:\n"
+ "\n".join(
"{}: {}".format(validator_name, error)
for validator_name, error in self.errors.items()
)
)
Loading