Exemplo n.º 1
0
def verify_jwt(access_token, refresh_token, jwk_url, alg, aud, iss):
    jwks_client = PyJWKClient(jwk_url)
    access_key = jwks_client.get_signing_key_from_jwt(access_token)
    refresh_key = jwks_client.get_signing_key_from_jwt(refresh_token)

    try:
        jwt.decode(access_token, access_key.key, algorithms=alg, audience=aud, issuer=iss)
        jwt.decode(refresh_token, refresh_key.key, algorithms=alg, issuer=iss)
    except jwt.PyJWTError:
        return False

    return True
Exemplo n.º 2
0
def verify_token(token):
    url = "https://everymovecounts.b2clogin.com/everymovecounts.onmicrosoft.com/discovery/v2.0/keys?p=b2c_1_emcsignin"
    jwks_client = PyJWKClient(url)
    decoded_token = ''
    retdict = {}
    try:
        signing_key = jwks_client.get_signing_key_from_jwt(token)
        data = jwt.decode(token,
                          signing_key.key,
                          algorithms=["RS256"],
                          audience="08ebc94f-55a7-45bf-9586-56f69290af27",
                          options={
                              "verify_exp": True,
                              "require": ["exp", "iss", "sub"]
                          })
        decoded_token = data
    except Exception as e:
        retdict['error'] = 'Error in validating token :' + ' ' + str(e)
    else:
        retdict = {}
        #print (decoded_token)
        retdict['emails'] = decoded_token.pop('emails')
        retdict['sub'] = decoded_token.pop('sub')
        retdict['given_name'] = decoded_token.pop('given_name')
        retdict['extension_StravaID'] = decoded_token.pop('extension_StravaID')
    return retdict
def verify_id_token(id_token: str, bundle_id=None) -> dict:

    if bundle_id is None:
        bundle_id = APPLE_SIGN_IN_AUD[0]
    if bundle_id not in APPLE_SIGN_IN_AUD:
        raise falcon.HTTPForbidden(description="Not allow bundle id.")

    jwt_header = jwt.get_unverified_header(id_token)

    # get kid to select public key
    kid = jwt_header.get("kid", None)
    if kid is None:
        raise falcon.HTTPUnauthorized(
            description=
            "Not found kid from your id_token, check your token is by apple sign in."
        )

    jwks_client = PyJWKClient(APPLE_AUTH_KEYS_URL)
    signing_key = jwks_client.get_signing_key_from_jwt(id_token)

    jwt_decode = jwt.decode(
        id_token,
        signing_key.key,
        algorithms=["RS256"],
        audience=bundle_id,
        options={"verify_exp": False},
    )
    return jwt_decode
Exemplo n.º 4
0
    def test_get_signing_key_from_jwt(self, mocked_response):
        token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik5FRTFRVVJCT1RNNE16STVSa0ZETlRZeE9UVTFNRGcyT0Rnd1EwVXpNVGsxUWpZeVJrUkZRdyJ9.eyJpc3MiOiJodHRwczovL2Rldi04N2V2eDlydS5hdXRoMC5jb20vIiwic3ViIjoiYVc0Q2NhNzl4UmVMV1V6MGFFMkg2a0QwTzNjWEJWdENAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vZXhwZW5zZXMtYXBpIiwiaWF0IjoxNTcyMDA2OTU0LCJleHAiOjE1NzIwMDY5NjQsImF6cCI6ImFXNENjYTc5eFJlTFdVejBhRTJINmtEME8zY1hCVnRDIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.PUxE7xn52aTCohGiWoSdMBZGiYAHwE5FYie0Y1qUT68IHSTXwXVd6hn02HTah6epvHHVKA2FqcFZ4GGv5VTHEvYpeggiiZMgbxFrmTEY0csL6VNkX1eaJGcuehwQCRBKRLL3zKmA5IKGy5GeUnIbpPHLHDxr-GXvgFzsdsyWlVQvPX2xjeaQ217r2PtxDeqjlf66UYl6oY6AqNS8DH3iryCvIfCcybRZkc_hdy-6ZMoKT6Piijvk_aXdm7-QQqKJFHLuEqrVSOuBqqiNfVrG27QzAPuPOxvfXTVLXL2jek5meH6n-VWgrBdoMFH93QEszEDowDAEhQPHVs0xj7SIzA"
        url = "https://dev-87evx9ru.auth0.com/.well-known/jwks.json"

        with mocked_response(RESPONSE_DATA):
            jwks_client = PyJWKClient(url)
            signing_key = jwks_client.get_signing_key_from_jwt(token)

        data = jwt.decode(
            token,
            signing_key.key,
            algorithms=["RS256"],
            audience="https://expenses-api",
            options={"verify_exp": False},
        )

        assert data == {
            "iss": "https://dev-87evx9ru.auth0.com/",
            "sub": "aW4Cca79xReLWUz0aE2H6kD0O3cXBVtC@clients",
            "aud": "https://expenses-api",
            "iat": 1572006954,
            "exp": 1572006964,
            "azp": "aW4Cca79xReLWUz0aE2H6kD0O3cXBVtC",
            "gty": "client-credentials",
        }
def validated_token(token, verify=True):
    """Validate a token and return decoded token."""
    url = (
        requests.get(
            config.oauth.google_openid_config_uri(default=DEFAULT_GOOGLE_OPENID_CFG_URI)
        )
        .json()
        .get(
            config.oauth.google_openid_jkws_key(
                default=DEFAULT_GOOGLE_OPENID_CFG_JWKS_KEY
            )
        )
    )
    logger.info("JWK url is %s", url)
    jwks_client = PyJWKClient(url)
    signing_key = jwks_client.get_signing_key_from_jwt(token)

    data = jwt.decode(
        token,
        signing_key.key,
        algorithms=["RS256"],
        audience=config.oauth.audience(default=DEFAULT_AUDIENCE, cast=split_list),
        options={"verify_signature": verify},
    )

    return data
Exemplo n.º 6
0
def get_credentials():
    expected_errors = {
        KeyError: WRONG_PAYLOAD_STRUCTURE,
        AssertionError: JWKS_HOST_MISSING,
        InvalidSignatureError: WRONG_KEY,
        DecodeError: WRONG_JWT_STRUCTURE,
        MissingRequiredClaimError: WRONG_PAYLOAD_STRUCTURE,
        InvalidAudienceError: WRONG_AUDIENCE,
        PyJWKClientError: KID_NOT_FOUND,
        URLError: WRONG_JWKS_HOST,
        HTTPError: WRONG_JWKS_HOST
    }

    try:
        token = get_auth_token()
        jwks_host = jwt.decode(token, options={
            'verify_signature': False
        }).get('jwks_host')
        assert jwks_host

        jwks_client = PyJWKClient(f'https://{jwks_host}/.well-known/jwks')
        signing_key = jwks_client.get_signing_key_from_jwt(token)

        aud = request.url_root
        payload = jwt.decode(token,
                             signing_key.key,
                             algorithms=['RS256'],
                             audience=[aud.rstrip('/')])
        current_app.config['SERVER_IP'] = payload['SERVER_IP']

        set_ctr_entities_limit(payload)
        return payload['user'], payload['pass']
    except tuple(expected_errors) as error:
        raise AuthorizationError(expected_errors[error.__class__])
Exemplo n.º 7
0
    async def test_full_flow(self) -> None:
        key = await random_key()
        uuid_identifier = uuid4()

        # Register a new key
        # This is done using direct json since KeyRequest.dump doesn't dump key (on purpose)
        request = RegisterKeyRequest(key, uuid4())
        response = await self.client.post(
            "/register_key",
            json=self.register_key_request_schema.dump(request))
        assert response.status == HTTPStatus.CREATED

        # Check that the key was registered
        request2 = KeyRequest(key)
        response = await self.client.post(
            "/is_key_registered", json=self.key_request_schema.dump(request2))
        assert response.status == HTTPStatus.OK

        # Authenticate and get access + refres tokens
        request = self.auth_request_schema.dump(
            AuthRequest(key=key, identifier=uuid_identifier))
        response = await self.client.post("/authenticate", json=request)
        assert response.status == HTTPStatus.OK
        response_json = await response.json()

        # Check access token is valid
        request = self.jwt_validate_request_schema.dump(
            JWTValidateRequest(jwt=response_json["jwt"]))
        response = await self.client.post("/validate", json=request)
        assert response.status == HTTPStatus.OK

        # Use refresh token to create a new access token
        request = self.refresh_request_schema.dump(
            RefreshRequest(refresh_token=response_json["refresh_token"],
                           identifier=uuid_identifier))
        response = await self.client.post("/refresh", json=request)
        assert response.status == HTTPStatus.OK
        response_json = await response.json()

        # Check that new access token is also valid
        token = response_json["jwt"]
        request = self.jwt_validate_request_schema.dump(
            JWTValidateRequest(jwt=token))
        response = await self.client.post("/validate", json=request)
        assert response.status == HTTPStatus.OK

        # Test JWKS
        response = await self.client.get("/jwks")
        assert response.status == HTTPStatus.OK
        response_json = await response.json()
        jwks_client = PyJWKClient("")
        jwks_client.fetch_data = MagicMock(
            return_value=response_json)  # type: ignore
        assert jwks_client.get_signing_key_from_jwt(token)
Exemplo n.º 8
0
 def _get_public_key(self):
     if self.header["alg"][:2] == "RS":
         try:
             wk_res = requests.get(self.payload["iss"] +
                                   "/.well-known/openid-configuration",
                                   verify=False)
             jwks_uri = wk_res.json()["jwks_uri"]
             jwks_client = PyJWKClient(jwks_uri)
             return jwks_client.get_signing_key_from_jwt(
                 self.encoded).key.public_bytes(
                     encoding=serialization.Encoding.PEM,
                     format=serialization.PublicFormat.SubjectPublicKeyInfo)
         except Exception as ex:
             self.errors.append("Error getting public Key: {0}".format(
                 str(ex)))
     return None
Exemplo n.º 9
0
                        async def query_jwks():
                            #dump('NO CACHE, TRY CONSUMER: ' + consumer_name)

                            # Get default or overridden jwks_url
                            jwks_url = consumer.jwks_url or default_jwks_url
                            self.log.debug(
                                'Verifying JWT via JWKS URL {}'.format(
                                    jwks_url))

                            # Get signing_key from jwks
                            jwks_client = PyJWKClient(jwks_url)
                            signing_key = jwks_client.get_signing_key_from_jwt(
                                token)
                            return Dict(
                                decode(jwt=token,
                                       key=signing_key.key,
                                       audience=consumer.aud,
                                       algorithms=consumer.algorithms))
Exemplo n.º 10
0
def validate_id_token(identity_token):
    identity_token = base64.b64decode(identity_token)
    jwk_client = PyJWKClient('https://appleid.apple.com/auth/keys')
    signing_key = jwk_client.get_signing_key_from_jwt(identity_token)

    try:
        data = jwt.decode(identity_token,
                          signing_key.key,
                          algorithms=['RS256'],
                          audience=os.environ['BUNDLE_ID'],
                          issuer='https://appleid.apple.com',
                          options={
                              'verify_aud': True,
                              'verify_exp': True,
                              'verify_iss': True
                          })
    except exceptions.InvalidTokenError as error:
        return False

    return True
Exemplo n.º 11
0
 def get_current_user_info(jwt_assertion: str):
     if os.getenv("TEST_USER", False):
         return {
             "aud": [],
             "email": "*****@*****.**",
             "exp": 1548134702,
             "iat": 1548134702,
             "iss": "localhost.com",
             "nbf": 1548134702,
             "sub": "localhost/testuser",
         }
     url = os.environ["JWK_ENDPOINT"]
     jwks_client = PyJWKClient(url)
     signing_key = jwks_client.get_signing_key_from_jwt(jwt_assertion)
     return jwt.decode(
         jwt_assertion,
         signing_key.key,
         algorithms=["ES256"],
         options={
             "verify_aud": False,
         },
     )
Exemplo n.º 12
0
class TokenBackend:
    def __init__(
        self,
        algorithm,
        signing_key=None,
        verifying_key=None,
        audience=None,
        issuer=None,
        jwk_url: str = None,
        leeway=0,
    ):
        self._validate_algorithm(algorithm)

        self.algorithm = algorithm
        self.signing_key = signing_key
        self.audience = audience
        self.issuer = issuer

        self.jwks_client = PyJWKClient(jwk_url) if jwk_url else None
        self.leeway = leeway

        if algorithm.startswith("HS"):
            self.verifying_key = signing_key
        else:
            self.verifying_key = verifying_key

    def _validate_algorithm(self, algorithm):
        """
        Ensure that the nominated algorithm is recognized, and that cryptography is installed for those
        algorithms that require it
        """
        if algorithm not in ALLOWED_ALGORITHMS:
            raise TokenBackendError(
                format_lazy(_("Unrecognized algorithm type '{}'"), algorithm))

        if algorithm in algorithms.requires_cryptography and not algorithms.has_crypto:
            raise TokenBackendError(
                format_lazy(
                    _("You must have cryptography installed to use {}."),
                    algorithm))

    def get_verifying_key(self, token):
        if self.algorithm.startswith("HS"):
            return self.signing_key

        if self.jwks_client:
            return self.jwks_client.get_signing_key_from_jwt(token).key

        return self.verifying_key

    def encode(self, payload):
        """
        Returns an encoded token for the given payload dictionary.
        """
        jwt_payload = payload.copy()
        if self.audience is not None:
            jwt_payload['aud'] = self.audience
        if self.issuer is not None:
            jwt_payload['iss'] = self.issuer

        token = jwt.encode(jwt_payload,
                           self.signing_key,
                           algorithm=self.algorithm)
        if isinstance(token, bytes):
            # For PyJWT <= 1.7.1
            return token.decode('utf-8')
        # For PyJWT >= 2.0.0a1
        return token

    def decode(self, token, verify=True):
        """
        Performs a validation of the given token and returns its payload
        dictionary.

        Raises a `TokenBackendError` if the token is malformed, if its
        signature check fails, or if its 'exp' claim indicates it has expired.
        """
        try:
            return jwt.decode(
                token,
                self.get_verifying_key(token),
                algorithms=[self.algorithm],
                audience=self.audience,
                issuer=self.issuer,
                leeway=self.leeway,
                options={
                    'verify_aud': self.audience is not None,
                    'verify_signature': verify,
                },
            )
        except InvalidAlgorithmError as ex:
            raise TokenBackendError(_('Invalid algorithm specified')) from ex
        except InvalidTokenError:
            raise TokenBackendError(_('Token is invalid or expired'))
class TokenBackend:
    def __init__(
        self,
        algorithm,
        signing_key=None,
        verifying_key="",
        audience=None,
        issuer=None,
        jwk_url: str = None,
        leeway: Union[float, int, timedelta] = None,
    ):
        self._validate_algorithm(algorithm)

        self.algorithm = algorithm
        self.signing_key = signing_key
        self.verifying_key = verifying_key
        self.audience = audience
        self.issuer = issuer

        if JWK_CLIENT_AVAILABLE:
            self.jwks_client = PyJWKClient(jwk_url) if jwk_url else None
        else:
            self.jwks_client = None

        self.leeway = leeway

    def _validate_algorithm(self, algorithm):
        """
        Ensure that the nominated algorithm is recognized, and that cryptography is installed for those
        algorithms that require it
        """
        if algorithm not in ALLOWED_ALGORITHMS:
            raise TokenBackendError(
                format_lazy(_("Unrecognized algorithm type '{}'"), algorithm))

        if algorithm in algorithms.requires_cryptography and not algorithms.has_crypto:
            raise TokenBackendError(
                format_lazy(
                    _("You must have cryptography installed to use {}."),
                    algorithm))

    def get_leeway(self) -> timedelta:
        if self.leeway is None:
            return timedelta(seconds=0)
        elif isinstance(self.leeway, (int, float)):
            return timedelta(seconds=self.leeway)
        elif isinstance(self.leeway, timedelta):
            return self.leeway
        else:
            raise TokenBackendError(
                format_lazy(
                    _("Unrecognized type '{}', 'leeway' must be of type int, float or timedelta."
                      ),
                    type(self.leeway),
                ))

    def get_verifying_key(self, token):
        if self.algorithm.startswith("HS"):
            return self.signing_key

        if self.jwks_client:
            return self.jwks_client.get_signing_key_from_jwt(token).key

        return self.verifying_key

    def encode(self, payload):
        """
        Returns an encoded token for the given payload dictionary.
        """
        jwt_payload = payload.copy()
        if self.audience is not None:
            jwt_payload["aud"] = self.audience
        if self.issuer is not None:
            jwt_payload["iss"] = self.issuer

        token = jwt.encode(jwt_payload,
                           self.signing_key,
                           algorithm=self.algorithm)
        if isinstance(token, bytes):
            # For PyJWT <= 1.7.1
            return token.decode("utf-8")
        # For PyJWT >= 2.0.0a1
        return token

    def decode(self, token, verify=True):
        """
        Performs a validation of the given token and returns its payload
        dictionary.

        Raises a `TokenBackendError` if the token is malformed, if its
        signature check fails, or if its 'exp' claim indicates it has expired.
        """
        try:
            return jwt.decode(
                token,
                self.get_verifying_key(token),
                algorithms=[self.algorithm],
                audience=self.audience,
                issuer=self.issuer,
                leeway=self.get_leeway(),
                options={
                    "verify_aud": self.audience is not None,
                    "verify_signature": verify,
                },
            )
        except InvalidAlgorithmError as ex:
            raise TokenBackendError(_("Invalid algorithm specified")) from ex
        except InvalidTokenError:
            raise TokenBackendError(_("Token is invalid or expired"))
    def verify_jwt_using_jwks(self, token, jwks_url, audience):
        jwks_client = PyJWKClient(jwks_url)
        signing_key = jwks_client.get_signing_key_from_jwt(token)
        secret = signing_key.key

        return self.verify_jwt_using_secret(token, secret, audience)