Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Validate Azure JWTs using authlib #2112

Merged

Conversation

wolfdn
Copy link
Contributor

@wolfdn wolfdn commented Sep 1, 2023

Description

This PR introduces authlib to decode and validate JWTs from Azure.
Note: I tried to use joserfc instead of authlib - as recommended in the authlib docs - but then realized that joserfc is only compatible with Python >= 3.8. To keep compatibility with Python 3.7 we should use authlib.

Until now we were using a custom implementation to parse Azure JWTs. Only the content of JWTs was evaluated, but it was not checked if the signature of the JWT is even valid.

By using authlib we can get rid of the custom parsing implementation for Azure JWTs in manager.py and it also allows us to validate the claims of the JWT.
The public keys from Microsoft are automatically fetched and used to decode the JWT.
Some basic claims of the JWT are also validated (issued at, not before and expiry).

ADDITIONAL INFORMATION

  • Has associated issue:
  • Is CRUD MVC related.
  • Is Auth, RBAC security related.
  • Changes the security db schema.
  • Introduces new feature
  • Removes existing feature

@wolfdn wolfdn changed the title feat: Use joserfc to decode Azure jwt feat: Use authlib to decode Azure jwt Sep 1, 2023
@wolfdn wolfdn changed the title feat: Use authlib to decode Azure jwt fix: Validate Azure JWTs using authlib Sep 1, 2023
Copy link
Owner

@dpgaspar dpgaspar left a comment

Choose a reason for hiding this comment

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

Looks good and simple, can you add tests please?

flask_appbuilder/security/manager.py Outdated Show resolved Hide resolved
flask_appbuilder/security/manager.py Outdated Show resolved Hide resolved
setup.py Outdated Show resolved Hide resolved
@codecov
Copy link

codecov bot commented Oct 4, 2023

Codecov Report

Merging #2112 (ec14163) into master (e4d613a) will increase coverage by 0.19%.
The diff coverage is 75.00%.

@@            Coverage Diff             @@
##           master    #2112      +/-   ##
==========================================
+ Coverage   78.29%   78.49%   +0.19%     
==========================================
  Files          72       72              
  Lines        8699     8685      -14     
==========================================
+ Hits         6811     6817       +6     
+ Misses       1888     1868      -20     
Flag Coverage Δ
python 78.49% <75.00%> (+0.19%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
flask_appbuilder/const.py 100.00% <100.00%> (ø)
flask_appbuilder/security/manager.py 77.89% <72.72%> (+1.72%) ⬆️

@wolfdn
Copy link
Contributor Author

wolfdn commented Oct 4, 2023

Looks good and simple, can you add tests please?

I just added a unittest for the new _decode_and_validate_azure_jwt method.
Since this method is relying on authlib for JWT decoding and validation, this test is just making sure that the validate function of the JWT claims is actually called.

Is this sufficient as a unit test?

Copy link
Owner

@dpgaspar dpgaspar left a comment

Choose a reason for hiding this comment

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

Looking good one last comment

requirements.txt Outdated
@@ -6,6 +6,8 @@
#
apispec[yaml]==6.3.0
# via Flask-AppBuilder (setup.py)
authlib==1.2.1
Copy link
Owner

Choose a reason for hiding this comment

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

can you move this to requirements extra?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I noticed that authlib is already in requirements-extra.txt - now I just upgraded the version there from 0.15.4 to the latest version 1.2.1

@dpgaspar
Copy link
Owner

dpgaspar commented Oct 4, 2023

Looks good and simple, can you add tests please?

I just added a unittest for the new _decode_and_validate_azure_jwt method. Since this method is relying on authlib for JWT decoding and validation, this test is just making sure that the validate function of the JWT claims is actually called.

Is this sufficient as a unit test?

It's ok, I'm going to revisit the Azure and claims mapping also, I'll add more tests


jwt_decoded_payload = json.loads(decoded_payload.decode("utf-8"))
def _decode_and_validate_azure_jwt(self, id_token):
keyset = JsonWebKey.import_key_set(requests.get(MICROSOFT_KEY_SET_URL).json())
Copy link
Owner

Choose a reason for hiding this comment

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

this should be cached or set at boot time

@dpgaspar dpgaspar merged commit 57f4400 into dpgaspar:master Oct 6, 2023
11 of 12 checks passed
@dpgaspar
Copy link
Owner

dpgaspar commented Oct 6, 2023

Thank you @wolfdn !

@potiuk
Copy link
Contributor

potiuk commented Oct 6, 2023

Cool!

potiuk added a commit to potiuk/airflow that referenced this pull request Oct 20, 2023
This PR brings all the necessary changes to upgrade to FAB 4.3.9 from
4.3.6.

It incorporates those changes:

* dpgaspar/Flask-AppBuilder#2112
* dpgaspar/Flask-AppBuilder#2121

It also removes the limitation of the WTForms after compatibility has
been implemented:

* dpgaspar/Flask-AppBuilder#2138
potiuk added a commit to apache/airflow that referenced this pull request Oct 21, 2023
This PR brings all the necessary changes to upgrade to FAB 4.3.9 from
4.3.6.

It incorporates those changes:

* dpgaspar/Flask-AppBuilder#2112
* dpgaspar/Flask-AppBuilder#2121

It also removes the limitation of the WTForms after compatibility has
been implemented:

* dpgaspar/Flask-AppBuilder#2138
kosteev pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Jul 18, 2024
This PR brings all the necessary changes to upgrade to FAB 4.3.9 from
4.3.6.

It incorporates those changes:

* dpgaspar/Flask-AppBuilder#2112
* dpgaspar/Flask-AppBuilder#2121

It also removes the limitation of the WTForms after compatibility has
been implemented:

* dpgaspar/Flask-AppBuilder#2138

GitOrigin-RevId: 4198146f49b72d051d82fbd821c7105cf2f4a8bd
kosteev pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Sep 20, 2024
This PR brings all the necessary changes to upgrade to FAB 4.3.9 from
4.3.6.

It incorporates those changes:

* dpgaspar/Flask-AppBuilder#2112
* dpgaspar/Flask-AppBuilder#2121

It also removes the limitation of the WTForms after compatibility has
been implemented:

* dpgaspar/Flask-AppBuilder#2138

GitOrigin-RevId: 4198146f49b72d051d82fbd821c7105cf2f4a8bd
kosteev pushed a commit to GoogleCloudPlatform/composer-airflow that referenced this pull request Nov 8, 2024
This PR brings all the necessary changes to upgrade to FAB 4.3.9 from
4.3.6.

It incorporates those changes:

* dpgaspar/Flask-AppBuilder#2112
* dpgaspar/Flask-AppBuilder#2121

It also removes the limitation of the WTForms after compatibility has
been implemented:

* dpgaspar/Flask-AppBuilder#2138

GitOrigin-RevId: 4198146f49b72d051d82fbd821c7105cf2f4a8bd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants