-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Get rid of TimedJSONWebSignatureSerializer
The TimedJSONWebSignatureSerializer has been deprecated from the itsdangerous library and they recommended to use dedicated libraries for it. pallets/itsdangerous#129 Since we are going to move to FAB 4+ with #22397 where newer version of itsdangerous is used, we need to switch to another library. We are already using PyJWT so the choice is obvious. Additionally to switching, the following improvements were done: * the use of JWT claims has been fixed to follow JWT standard. We were using "iat" header wrongly. The specification of JWT only expects the header to be there and be valid UTC timestamp, but the claim does not impact maturity of the signature - the signature is valid if iat is in the future. Instead "nbf" - "not before" claim should be used to verify if the request is not coming from the future. We now require all claims to be present in the request. * rather than using salt/signing_context we switched to standard JWT "audience" claim (same end result) * we have now much better diagnostics on the server side of the reason why request is forbidden - explicit error messages are printed in server logs and details of the exception. This is secure, we do not spill the information about the reason to the client, it's only available in server logs, so there is no risk attacker could use it. * the JWTSigner is "use-agnostic". We should be able to use the same class for any other signatures (Internal API from AIP-44) with just different audience * Short, 5 seconds default clock skew is allowed, to account for systems that have "almost" synchronized time * more tests addded with proper time freezing testing both expiry and immaturity of the request This change is not a breaking one because the JWT authentication details are not "public API" - but in case someone reverse engineered our claims and implemented their own log file retrieval, we should add a change in our changelog - therefore newsfragment is added.
- Loading branch information
Showing
5 changed files
with
272 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
# Licensed to the Apache Software Foundation (ASF) under one | ||
# or more contributor license agreements. See the NOTICE file | ||
# distributed with this work for additional information | ||
# regarding copyright ownership. The ASF licenses this file | ||
# to you under the Apache License, Version 2.0 (the | ||
# "License"); you may not use this file except in compliance | ||
# with the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, | ||
# software distributed under the License is distributed on an | ||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
# KIND, either express or implied. See the License for the | ||
# specific language governing permissions and limitations | ||
# under the License. | ||
from datetime import datetime, timedelta | ||
from typing import Any, Dict | ||
|
||
import jwt | ||
|
||
|
||
class JWTSigner: | ||
""" | ||
Signs and verifies JWT Token. Used to authorise and verify requests. | ||
:param secret_key: key used to sign the request | ||
:param expiration_time_in_seconds: time after which the token becomes invalid (in seconds) | ||
:param audience: audience that the request is expected to have | ||
:param leeway_in_seconds: leeway that allows for a small clock skew between the two parties | ||
:param algorithm: algorithm used for signing | ||
""" | ||
|
||
def __init__( | ||
self, | ||
secret_key: str, | ||
expiration_time_in_seconds: int, | ||
audience: str, | ||
leeway_in_seconds: int = 5, | ||
algorithm: str = "HS512", | ||
): | ||
self._secret_key = secret_key | ||
self._expiration_time_in_seconds = expiration_time_in_seconds | ||
self._audience = audience | ||
self._leeway_in_seconds = leeway_in_seconds | ||
self._algorithm = algorithm | ||
|
||
def generate_signed_token(self, extra_payload: Dict[str, Any]) -> str: | ||
""" | ||
Generate JWT with extra payload added. | ||
:param extra_payload: extra payload that is added to the signed token | ||
:return: signed token | ||
""" | ||
jwt_dict = { | ||
"aud": self._audience, | ||
"iat": datetime.utcnow(), | ||
"nbf": datetime.utcnow(), | ||
"exp": datetime.utcnow() + timedelta(seconds=self._expiration_time_in_seconds), | ||
} | ||
jwt_dict.update(extra_payload) | ||
token = jwt.encode( | ||
jwt_dict, | ||
self._secret_key, | ||
algorithm=self._algorithm, | ||
) | ||
return token | ||
|
||
def verify_token(self, token: str) -> Dict[str, Any]: | ||
payload = jwt.decode( | ||
token, | ||
self._secret_key, | ||
leeway=timedelta(seconds=self._leeway_in_seconds), | ||
algorithms=[self._algorithm], | ||
options={ | ||
"verify_signature": True, | ||
"require_exp": True, | ||
"require_iat": True, | ||
"require_nbf": True, | ||
}, | ||
audience=self._audience, | ||
) | ||
return payload |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
The JWT claims in the request to retrieve logs have been standardized: we use "nbf" and "aud" claims for maturity and audience of the requests. Also "filename" payload field is used to keep log name. |
Oops, something went wrong.