Example #1
0
 def testNoExpiredWrongAudience(self):
     """ validate signature, ignore expiration, check audience (fail) """
     self.validator = JWTValidator(url=self.url,
                                   refresh_period=self.period,
                                   audience=self.wrong_audience)
     vc, e = self.validator.validate_jwt(token=self.testToken2)
     assert vc is ValidateCode.INVALID and str(e) == "Invalid audience"
Example #2
0
 def testNoExpiredRightAudience(self):
     """ validate signature, ignore expiration, check audience (succeed) """
     self.validator = JWTValidator(url=self.url,
                                   refresh_period=self.period,
                                   audience=self.right_audience)
     vc, e = self.validator.validate_jwt(token=self.testToken2)
     assert vc is ValidateCode.VALID
 def load_jwt_validator(self):
     oauth_config = self.config.get_oauth_config()
     CREDMGR_CERTS = oauth_config.get(
         Constants.PROPERTY_CONF_O_AUTH_JWKS_URL, None)
     CREDMGR_KEY_REFRESH = oauth_config.get(
         Constants.PROPERTY_CONF_O_AUTH_KEY_REFRESH, None)
     self.log.info(
         f'Initializing JWT Validator to use {CREDMGR_CERTS} endpoint, '
         f'refreshing keys every {CREDMGR_KEY_REFRESH} HH:MM:SS')
     t = datetime.strptime(CREDMGR_KEY_REFRESH, "%H:%M:%S")
     self.jwt_validator = JWTValidator(url=CREDMGR_CERTS,
                                       refresh_period=timedelta(
                                           hours=t.hour,
                                           minutes=t.minute,
                                           seconds=t.second))
Example #4
0
received_counter = prometheus_client.Counter('Requests_Received',
                                             'HTTP Requests',
                                             ['method', 'endpoint'])
success_counter = prometheus_client.Counter('Requests_Success', 'HTTP Success',
                                            ['method', 'endpoint'])
failure_counter = prometheus_client.Counter('Requests_Failed', 'HTTP Failures',
                                            ['method', 'endpoint'])

# initialize CI Logon Token Validation
CILOGON_CERTS = CONFIG_OBJ.get_oauth_jwks_url()
CILOGON_KEY_REFRESH = CONFIG_OBJ.get_oauth_key_refresh()
LOG.info(f'Initializing JWT Validator to use {CILOGON_CERTS} endpoint, '
         f'refreshing keys every {CILOGON_KEY_REFRESH} HH:MM:SS')
jwt_validator = JWTValidator(url=CILOGON_CERTS,
                             refresh_period=timedelta(
                                 hours=CILOGON_KEY_REFRESH.hour,
                                 minutes=CILOGON_KEY_REFRESH.minute,
                                 seconds=CILOGON_KEY_REFRESH.second),
                             audience=CONFIG_OBJ.get_oauth_client_id())

kid = CONFIG_OBJ.get_jwt_public_key_kid()
public_key = CONFIG_OBJ.get_jwt_public_key()
code, jwk_public_key_rsa = JWTManager.encode_jwk(key_file_name=public_key,
                                                 kid=kid,
                                                 alg="RS256")
if code != ValidateCode.VALID:
    LOG.error("Failed to encode JWK")
    raise jwk_public_key_rsa

fabric_jwks = {"keys": [jwk_public_key_rsa]}
Example #5
0
class JWTTester(unittest.TestCase):
    def setUp(self):
        self.url = "https://cilogon.org/oauth2/certs"
        self.right_audience = "cilogon:/client_id/73bb503829ff96ad948f41b1d8e2a2a5"
        self.wrong_audience = "cilogon:/client_id/1234567890"
        self.period = datetime.timedelta(seconds=10)
        self.default_validator = JWTValidator(url=self.url,
                                              refresh_period=self.period)
        self.validator = None
        self.testToken = {
            "email":
            "*****@*****.**",
            "given_name":
            "Some",
            "family_name":
            "One",
            "name":
            "Some One",
            "iss":
            "https://cilogon.org",
            "aud":
            "cilogon:foo",
            "sub":
            "https://cilogon.org/serverT/users/241998",
            "token_id":
            "https://cilogon.org/oauth2/idToken/1234567898",
            "auth_time":
            "1607382404",
            "iat":
            1607382405,
            "roles": [
                "CO:members:all", "CO:members:active", "CO:admins",
                "CO:COU:project-leads:members:active",
                "CO:COU:project-leads:members:all",
                "CO:COU:abf0014e-72f5-44ab-ac63-5ec5a5debbb8-pm:members:active",
                "CO:COU:abf0014e-72f5-44ab-ac63-5ec5a5debbb8-pm:members:all"
            ],
            'exp':
            int(time.time()) + 1000
        }
        self.testToken2 = "eyJ0eXAiOiJKV1QiLCJraWQiOiIyNDRCMjM1RjZCMjhFMzQxMDhEMTAxRUFDNzM2MkM0RSIsImFsZyI6IlJTMjU2I" \
                          "n0.eyJlbWFpbCI6ImliYWxkaW5AcmVuY2kub3JnIiwiZ2l2ZW5fbmFtZSI6IklseWEiLCJmYW1pbHlfbmFtZSI6Ik" \
                          "JhbGRpbiIsIm5hbWUiOiJJbHlhIEJhbGRpbiIsImlzcyI6Imh0dHBzOi8vY2lsb2dvbi5vcmciLCJzdWIiOiJodHR" \
                          "wOi8vY2lsb2dvbi5vcmcvc2VydmVyVC91c2Vycy8yNDE5OTgiLCJhdWQiOiJjaWxvZ29uOi9jbGllbnRfaWQvNzNi" \
                          "YjUwMzgyOWZmOTZhZDk0OGY0MWIxZDhlMmEyYTUiLCJ0b2tlbl9pZCI6Imh0dHBzOi8vY2lsb2dvbi5vcmcvb2F1d" \
                          "GgyL2lkVG9rZW4vMTk0ZGFiMDUzMzcxMGY0ZjM0YTEzNjYxNzQyMDQ1NTIvMTYwNzk3ODE1NDk5MyIsImF1dGhfdG" \
                          "ltZSI6IjE2MDc5NzgxNTMiLCJleHAiOjE2MDc5NzkwNTQsImlhdCI6MTYwNzk3ODE1NCwicm9sZXMiOlsiQ086bWV" \
                          "tYmVyczphbGwiLCJDTzptZW1iZXJzOmFjdGl2ZSIsIkNPOmFkbWlucyIsIkNPOkNPVTpwcm9qZWN0LWxlYWRzOm1l" \
                          "bWJlcnM6YWN0aXZlIiwiQ086Q09VOnByb2plY3QtbGVhZHM6bWVtYmVyczphbGwiLCJDTzpDT1U6YWJmMDAxNGUtN" \
                          "zJmNS00NGFiLWFjNjMtNWVjNWE1ZGViYmI4LXBtOm1lbWJlcnM6YWN0aXZlIiwiQ086Q09VOmFiZjAwMTRlLTcyZj" \
                          "UtNDRhYi1hYzYzLTVlYzVhNWRlYmJiOC1wbTptZW1iZXJzOmFsbCJdfQ.Uats19baYgA8mOllbPIDN_cpbXnPLPHu" \
                          "_QE5cBjlgu4KH7DSv0_15d-wjY59gJQUPq42Dg4cbgEzsfrNh_I7GldYCbopCWSv5S7rudJKbiz-gInPmDITGuOFH" \
                          "luOXYkEzJNJ1uxlUOvvQtyrvsCM2DuvSrd2FeBIY0MRHI92UEuvpjiCKn5JD-PhcFv8CUixityBXwewICvFo9k7YV" \
                          "70PvaL0SFzKskaofrdL8HialvWgWO26qEXsF2_CSUkgmTI_GikuVamUU3eP8jP7TntsqD_TBXKIKis2y8Kg9ao5N9" \
                          "OPu8sZ3Y9DTtqLeJKp7tsLsdGe6F_m58ozRck61_trA"

        self.testToken3 = "eyJ0eXAiOiJKV1QiLCJraWQiOiIyNDRCMjM1RjZCMjhFMzQxMDhEMTAxRUFDNzM2MkM0RSIsImFsZyI6IlJTMjU2I" \
                          "n0.eyJlbWFpbCI6ImliYWxkaW5AcmVuY2kub3JnIiwiZ2l2ZW5fbmFtZSI6IklseWEiLCJmYW1pbHlfbmFtZSI6Ik" \
                          "JhbGRpbiIsIm5hbWUiOiJJbHlhIEJhbGRpbiIsImlzcyI6Imh0dHBzOi8vY2lsb2dvbi5vcmciLCJzdWIiOiJodHR" \
                          "wOi8vY2lsb2dvbi5vcmcvc2VydmVyVC91c2Vycy8yNDE5OTgiLCJhdWQiOiJjaWxvZ29uOi9jbGllbnRfaWQvNzNi" \
                          "YjUwMzgyOWZmOTZhZDk0OGY0MWIxZDhlMmEyYTUiLCJ0b2tlbl9pZCI6Imh0dHBzOi8vY2lsb2dvbi5vcmcvb2F1d" \
                          "GgyL2lkVG9rZW4vMTk0ZGFiMDUzMzcxMGY0ZjM0YTEzNjYxNzQyMDQ1NTIvMTYwNzk3ODE1NDk5MyIsImF1dGhfdG" \
                          "ltZSI6IjE2MDc5NzgxNTMiLCJleHAiOjE2MDc5NzkwNTQsImlhdCI6MTYwNzk3ODE1NCwicm9sZXMiOlsiQ086bWV" \
                          "tYmVyczphbGwiLCJDTzptZW1iZXJzOmFjkNPOmFkbWlucyIsIkNPOkNPVTpwcm9qZWN0LWxlYWRzOm1l" \
                          "bWJlcnM6YWN0aXZlIiwiQ086Q09VOnByb2plY3QtbGVhZHM6bWVtYmVyczphbGwiLCJDTzpDT1U6YWJmMDAxNGUtN" \
                          "zJmNS00NGFiLWFjNjMtNWVjNWE1ZGViYmI4LXBtOm1lbWJlcnM6YWN0aXZlIiwiQ086Q09VOmFiZjAwMTRlLTcyZj" \
                          "UtNDRhYi1hYzYzLTVlYzVhNWRlYmJiOC1wbTptZW1iZXJzOmFsbCJdfQ.Uats19baYgA8mOllbPIDN_cpbXnPLPHu" \
                          "_QE5cBjlgu4KH7DSv0_15d-wjY59gJQUPq42Dg4cbgEzsfrNh_I7GldYCbopCWSv5S7rudJKbiz-gInPmDITGuOFH" \
                          "luOXYkEzJNJ1uxlUOvvQtyrvsCM2DuvSrd2FeBIY0MRHI92UEuvpjiCKn5JD-PhcFv8CUixityBXwewICvFo9k7YV" \
                          "70PvaL0SFzKskaofrdL8HialvWgWO26qEXsF2_CSUkgmTI_GikuVamUU3eP8jP7TntsqD_TBXKIKis2y8Kg9ao5N9" \
                          "OPu8sZ3Y9DTtqLeJKp7tsLsdGe6F_m58ozRck61_trA"

    def testFetchKeys(self):
        """ test fetching keys from a real endpoint (succeed) """
        self.validator = JWTValidator(url=self.url, refresh_period=self.period)
        vc, e = self.validator.fetch_pub_keys()
        assert vc is None and e is None

    def testEncodeDecode(self):
        """ test simple symmetric encoding/decoding (succeed) """
        encoded_token = jwt.encode(self.testToken,
                                   key='secret',
                                   algorithm='HS256')
        jwt.decode(encoded_token,
                   key='secret',
                   algorithms=['HS256'],
                   options={
                       "verify_exp": True,
                       "verify_aud": True
                   },
                   audience='cilogon:foo')

    def testNoExpiredNoAudience(self):
        """ validate signature, ignore expiration and audience (succeed) """
        # audience is set to None in this case
        vc, e = self.default_validator.validate_jwt(token=self.testToken2)
        assert vc is ValidateCode.VALID

    def testNoExpiredRightAudience(self):
        """ validate signature, ignore expiration, check audience (succeed) """
        self.validator = JWTValidator(url=self.url,
                                      refresh_period=self.period,
                                      audience=self.right_audience)
        vc, e = self.validator.validate_jwt(token=self.testToken2)
        assert vc is ValidateCode.VALID

    def testNoExpiredWrongAudience(self):
        """ validate signature, ignore expiration, check audience (fail) """
        self.validator = JWTValidator(url=self.url,
                                      refresh_period=self.period,
                                      audience=self.wrong_audience)
        vc, e = self.validator.validate_jwt(token=self.testToken2)
        assert vc is ValidateCode.INVALID and str(e) == "Invalid audience"

    def testStrictExpired(self):
        """ test for expiration (fail) """
        # audience is set to None in this case
        vc, e = self.default_validator.validate_jwt(token=self.testToken2,
                                                    verify_exp=True)
        assert vc is ValidateCode.INVALID and str(e) == "Signature has expired"

    def testBadToken(self):
        """ test an unparsable token (fail) """
        vc, e = self.default_validator.validate_jwt(token=self.testToken3)
        assert vc is ValidateCode.UNPARSABLE_TOKEN

    def testKeyRefetch(self):
        """ test key refetch from JWK endpoint """
        vc, e = self.default_validator.validate_jwt(token=self.testToken2)
        assert vc is ValidateCode.VALID
        print("Sleeping for 5 seconds")
        time.sleep(5)
        vc, e = self.default_validator.validate_jwt(token=self.testToken2)
        assert vc is ValidateCode.VALID
        print("Sleeping for 6 seconds")
        time.sleep(6)
        vc, e = self.default_validator.validate_jwt(token=self.testToken2)
        assert vc is ValidateCode.VALID
Example #6
0
 def testFetchKeys(self):
     """ test fetching keys from a real endpoint (succeed) """
     self.validator = JWTValidator(url=self.url, refresh_period=self.period)
     vc, e = self.validator.fetch_pub_keys()
     assert vc is None and e is None
Example #7
0
    def setUp(self):
        self.url = "https://cilogon.org/oauth2/certs"
        self.right_audience = "cilogon:/client_id/73bb503829ff96ad948f41b1d8e2a2a5"
        self.wrong_audience = "cilogon:/client_id/1234567890"
        self.period = datetime.timedelta(seconds=10)
        self.default_validator = JWTValidator(url=self.url,
                                              refresh_period=self.period)
        self.validator = None
        self.testToken = {
            "email":
            "*****@*****.**",
            "given_name":
            "Some",
            "family_name":
            "One",
            "name":
            "Some One",
            "iss":
            "https://cilogon.org",
            "aud":
            "cilogon:foo",
            "sub":
            "https://cilogon.org/serverT/users/241998",
            "token_id":
            "https://cilogon.org/oauth2/idToken/1234567898",
            "auth_time":
            "1607382404",
            "iat":
            1607382405,
            "roles": [
                "CO:members:all", "CO:members:active", "CO:admins",
                "CO:COU:project-leads:members:active",
                "CO:COU:project-leads:members:all",
                "CO:COU:abf0014e-72f5-44ab-ac63-5ec5a5debbb8-pm:members:active",
                "CO:COU:abf0014e-72f5-44ab-ac63-5ec5a5debbb8-pm:members:all"
            ],
            'exp':
            int(time.time()) + 1000
        }
        self.testToken2 = "eyJ0eXAiOiJKV1QiLCJraWQiOiIyNDRCMjM1RjZCMjhFMzQxMDhEMTAxRUFDNzM2MkM0RSIsImFsZyI6IlJTMjU2I" \
                          "n0.eyJlbWFpbCI6ImliYWxkaW5AcmVuY2kub3JnIiwiZ2l2ZW5fbmFtZSI6IklseWEiLCJmYW1pbHlfbmFtZSI6Ik" \
                          "JhbGRpbiIsIm5hbWUiOiJJbHlhIEJhbGRpbiIsImlzcyI6Imh0dHBzOi8vY2lsb2dvbi5vcmciLCJzdWIiOiJodHR" \
                          "wOi8vY2lsb2dvbi5vcmcvc2VydmVyVC91c2Vycy8yNDE5OTgiLCJhdWQiOiJjaWxvZ29uOi9jbGllbnRfaWQvNzNi" \
                          "YjUwMzgyOWZmOTZhZDk0OGY0MWIxZDhlMmEyYTUiLCJ0b2tlbl9pZCI6Imh0dHBzOi8vY2lsb2dvbi5vcmcvb2F1d" \
                          "GgyL2lkVG9rZW4vMTk0ZGFiMDUzMzcxMGY0ZjM0YTEzNjYxNzQyMDQ1NTIvMTYwNzk3ODE1NDk5MyIsImF1dGhfdG" \
                          "ltZSI6IjE2MDc5NzgxNTMiLCJleHAiOjE2MDc5NzkwNTQsImlhdCI6MTYwNzk3ODE1NCwicm9sZXMiOlsiQ086bWV" \
                          "tYmVyczphbGwiLCJDTzptZW1iZXJzOmFjdGl2ZSIsIkNPOmFkbWlucyIsIkNPOkNPVTpwcm9qZWN0LWxlYWRzOm1l" \
                          "bWJlcnM6YWN0aXZlIiwiQ086Q09VOnByb2plY3QtbGVhZHM6bWVtYmVyczphbGwiLCJDTzpDT1U6YWJmMDAxNGUtN" \
                          "zJmNS00NGFiLWFjNjMtNWVjNWE1ZGViYmI4LXBtOm1lbWJlcnM6YWN0aXZlIiwiQ086Q09VOmFiZjAwMTRlLTcyZj" \
                          "UtNDRhYi1hYzYzLTVlYzVhNWRlYmJiOC1wbTptZW1iZXJzOmFsbCJdfQ.Uats19baYgA8mOllbPIDN_cpbXnPLPHu" \
                          "_QE5cBjlgu4KH7DSv0_15d-wjY59gJQUPq42Dg4cbgEzsfrNh_I7GldYCbopCWSv5S7rudJKbiz-gInPmDITGuOFH" \
                          "luOXYkEzJNJ1uxlUOvvQtyrvsCM2DuvSrd2FeBIY0MRHI92UEuvpjiCKn5JD-PhcFv8CUixityBXwewICvFo9k7YV" \
                          "70PvaL0SFzKskaofrdL8HialvWgWO26qEXsF2_CSUkgmTI_GikuVamUU3eP8jP7TntsqD_TBXKIKis2y8Kg9ao5N9" \
                          "OPu8sZ3Y9DTtqLeJKp7tsLsdGe6F_m58ozRck61_trA"

        self.testToken3 = "eyJ0eXAiOiJKV1QiLCJraWQiOiIyNDRCMjM1RjZCMjhFMzQxMDhEMTAxRUFDNzM2MkM0RSIsImFsZyI6IlJTMjU2I" \
                          "n0.eyJlbWFpbCI6ImliYWxkaW5AcmVuY2kub3JnIiwiZ2l2ZW5fbmFtZSI6IklseWEiLCJmYW1pbHlfbmFtZSI6Ik" \
                          "JhbGRpbiIsIm5hbWUiOiJJbHlhIEJhbGRpbiIsImlzcyI6Imh0dHBzOi8vY2lsb2dvbi5vcmciLCJzdWIiOiJodHR" \
                          "wOi8vY2lsb2dvbi5vcmcvc2VydmVyVC91c2Vycy8yNDE5OTgiLCJhdWQiOiJjaWxvZ29uOi9jbGllbnRfaWQvNzNi" \
                          "YjUwMzgyOWZmOTZhZDk0OGY0MWIxZDhlMmEyYTUiLCJ0b2tlbl9pZCI6Imh0dHBzOi8vY2lsb2dvbi5vcmcvb2F1d" \
                          "GgyL2lkVG9rZW4vMTk0ZGFiMDUzMzcxMGY0ZjM0YTEzNjYxNzQyMDQ1NTIvMTYwNzk3ODE1NDk5MyIsImF1dGhfdG" \
                          "ltZSI6IjE2MDc5NzgxNTMiLCJleHAiOjE2MDc5NzkwNTQsImlhdCI6MTYwNzk3ODE1NCwicm9sZXMiOlsiQ086bWV" \
                          "tYmVyczphbGwiLCJDTzptZW1iZXJzOmFjkNPOmFkbWlucyIsIkNPOkNPVTpwcm9qZWN0LWxlYWRzOm1l" \
                          "bWJlcnM6YWN0aXZlIiwiQ086Q09VOnByb2plY3QtbGVhZHM6bWVtYmVyczphbGwiLCJDTzpDT1U6YWJmMDAxNGUtN" \
                          "zJmNS00NGFiLWFjNjMtNWVjNWE1ZGViYmI4LXBtOm1lbWJlcnM6YWN0aXZlIiwiQ086Q09VOmFiZjAwMTRlLTcyZj" \
                          "UtNDRhYi1hYzYzLTVlYzVhNWRlYmJiOC1wbTptZW1iZXJzOmFsbCJdfQ.Uats19baYgA8mOllbPIDN_cpbXnPLPHu" \
                          "_QE5cBjlgu4KH7DSv0_15d-wjY59gJQUPq42Dg4cbgEzsfrNh_I7GldYCbopCWSv5S7rudJKbiz-gInPmDITGuOFH" \
                          "luOXYkEzJNJ1uxlUOvvQtyrvsCM2DuvSrd2FeBIY0MRHI92UEuvpjiCKn5JD-PhcFv8CUixityBXwewICvFo9k7YV" \
                          "70PvaL0SFzKskaofrdL8HialvWgWO26qEXsF2_CSUkgmTI_GikuVamUU3eP8jP7TntsqD_TBXKIKis2y8Kg9ao5N9" \
                          "OPu8sZ3Y9DTtqLeJKp7tsLsdGe6F_m58ozRck61_trA"