Exemplo n.º 1
0
def genkeys(ctx, path):
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives.asymmetric import rsa

    from authlib.jose import jwk

    if path is None:
        context = ctx.obj['context']
        config = context.get('config')
        path = config.config_path / 'keys'
        path.mkdir(exist_ok=True)
    else:
        path = pathlib.Path(path)

    private_file = path / 'private.json'
    public_file = path / 'public.json'

    if private_file.exists():
        raise click.Abort(f"{private_file} file already exists.")

    if public_file.exists():
        raise click.Abort(f"{public_file} file already exists.")

    key = rsa.generate_private_key(public_exponent=65537,
                                   key_size=2048,
                                   backend=default_backend())

    with private_file.open('w') as f:
        json.dump(jwk.dumps(key), f, indent=4, ensure_ascii=False)
        click.echo(f"Private key saved to {private_file}.")

    with public_file.open('w') as f:
        json.dump(jwk.dumps(key.public_key()), f, indent=4, ensure_ascii=False)
        click.echo(f"Public key saved to {public_file}.")
Exemplo n.º 2
0
    def test_runtime_error_fetch_jwks_uri(self):
        key = jwk.dumps('secret', 'oct', kid='f')
        token = get_bearer_token()
        id_token = generate_id_token(
            token, {'sub': '123'}, key,
            alg='HS256', iss='https://i.b',
            aud='dev', exp=3600, nonce='n',
        )

        app = Flask(__name__)
        app.secret_key = '!'
        oauth = OAuth(app)
        client = oauth.register(
            'dev',
            client_id='dev',
            client_secret='dev',
            fetch_token=get_bearer_token,
            jwks={'keys': [jwk.dumps('secret', 'oct', kid='b')]},
            issuer='https://i.b',
            id_token_signing_alg_values_supported=['HS256'],
        )
        with app.test_request_context():
            session['_dev_authlib_nonce_'] = 'n'
            token['id_token'] = id_token
            self.assertRaises(RuntimeError, client.parse_id_token, token)
Exemplo n.º 3
0
    def test_dumps_okp_public_key(self):
        key = read_file_path('ed25519-ssh.pub')
        self.assertRaises(ValueError, jwk.dumps, key)

        obj = jwk.dumps(key, 'OKP')
        self.assertEqual(obj['kty'], 'OKP')
        self.assertEqual(obj['crv'], 'Ed25519')

        key = read_file_path('ed25519-pub.pem')
        obj = jwk.dumps(key, 'OKP')
        self.assertEqual(obj['kty'], 'OKP')
        self.assertEqual(obj['crv'], 'Ed25519')
Exemplo n.º 4
0
    def test_parse_id_token_nonce_supported(self):
        key = jwk.dumps('secret', 'oct', kid='f')
        token = get_bearer_token()
        id_token = generate_id_token(
            token, {'sub': '123', 'nonce_supported': False}, key,
            alg='HS256', iss='https://i.b',
            aud='dev', exp=3600,
        )

        app = Flask(__name__)
        app.secret_key = '!'
        oauth = OAuth(app)
        client = oauth.register(
            'dev',
            client_id='dev',
            client_secret='dev',
            fetch_token=get_bearer_token,
            jwks={'keys': [key]},
            issuer='https://i.b',
            id_token_signing_alg_values_supported=['HS256', 'RS256'],
        )
        with app.test_request_context():
            session['_dev_authlib_nonce_'] = 'n'
            token['id_token'] = id_token
            user = client.parse_id_token(token)
            self.assertEqual(user.sub, '123')
Exemplo n.º 5
0
    def test_mac_computation(self):
        # https://tools.ietf.org/html/rfc7520#section-3.5
        obj = {
            "kty": "oct",
            "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037",
            "use": "sig",
            "alg": "HS256",
            "k": "hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg"
        }
        key = jwk.loads(obj)
        new_obj = jwk.dumps(key)
        self.assertEqual(obj['k'], new_obj['k'])
        self.assertNotIn('use', new_obj)

        new_obj = jwk.dumps(key, use='sig')
        self.assertEqual(new_obj['use'], 'sig')
Exemplo n.º 6
0
async def test_runtime_error_fetch_jwks_uri():
    key = jwk.dumps('secret', 'oct', kid='f')
    token = get_bearer_token()
    id_token = generate_id_token(
        token,
        {'sub': '123'},
        key,
        alg='HS256',
        iss='https://i.b',
        aud='dev',
        exp=3600,
        nonce='n',
    )

    oauth = OAuth()
    client = oauth.register(
        'dev',
        client_id='dev',
        client_secret='dev',
        fetch_token=get_bearer_token,
        issuer='https://i.b',
        id_token_signing_alg_values_supported=['HS256'],
    )
    req_scope = {'type': 'http', 'session': {'_dev_authlib_nonce_': 'n'}}
    req = Request(req_scope)
    token['id_token'] = id_token
    with pytest.raises(RuntimeError):
        await client.parse_id_token(req, token)
Exemplo n.º 7
0
 def test_rsa_public_key(self):
     # https://tools.ietf.org/html/rfc7520#section-3.3
     obj = read_file_path('jwk_public.json')
     key = jwk.loads(obj)
     new_obj = jwk.dumps(key)
     self.assertBase64IntEqual(new_obj['n'], obj['n'])
     self.assertBase64IntEqual(new_obj['e'], obj['e'])
Exemplo n.º 8
0
def make_jwk(key: str, ident: str):
    '''convert tempfile to jwk'''
    with open(key, 'rb') as fin:
        json_key = jwk.dumps(fin.read(), kty='RSA')
    json_key['alg'] = 'RS256'
    json_key['kid'] = ident
    return json_key
Exemplo n.º 9
0
    def encode_jwk(*, key_file_name: str, kid: str,
                   alg: str) -> Tuple[ValidateCode, Union[Exception, dict]]:
        """
        Encode JWK from a PEM file
        :param key_file_name Key File Name
        :param kid kid to be added to the JWK
        :param alg algorithm to be added

        :return ValidateCode or None, exception or None, JWK or None:
        """
        pem_data = None
        try:
            with open(key_file_name) as public_key_fh:
                pem_data = public_key_fh.read()
                public_key_fh.close()
        except Exception as e:
            return ValidateCode.UNABLE_TO_LOAD_KEYS, e

        try:
            result = jwk.dumps(pem_data, kty='RSA')
            result["kid"] = kid
            result["alg"] = alg
            result["use"] = "sig"
            return ValidateCode.VALID, result
        except Exception as e:
            return ValidateCode.INVALID, e
Exemplo n.º 10
0
def create_account(username: str, password: str):
    secret_key = key_utils.generate_secret_key(username)
    master_unlock_salt = key_utils.generate_salt()
    authentication_salt = key_utils.generate_salt()

    # Generate key to decrypt
    master_unlock_key = key_utils.derive_key_from_master_password_and_secret_key(
        username=username,
        master_password=password,
        secret_key=secret_key,
        salt=master_unlock_salt,
    )

    # Generate x for SRP
    srp_x = key_utils.derive_key_from_master_password_and_secret_key(
        username=username,
        master_password=password,
        secret_key=secret_key,
        salt=authentication_salt,
    )

    # Create account's keypair
    key_id = uuid.uuid1()
    key_pair = key_utils.generate_asymmetric_key_pair()
    # TODO: design flexible way to specify kty, if switching between EC and RSA, for example

    print(
        jwk.dumps(key_pair.private_key, kty="RSA", kid="priv"),
        jwk.dumps(key_pair.public_key, kty="RSA"),
    )

    from passman.srp_example import create_v

    verifier = create_v(srp_x)

    # Attempt to create an account
    url = "http://localhost:443/create_account"
    data = {
        "username": username,
        "display_name": "Person",
        "auth_salt_hex": authentication_salt.hex(),
        "muk_salt_hex": master_unlock_salt.hex(),
        "auth_verifier_hex": verifier.hex(),
    }
    x = requests.post(url, json=data)

    print(x.text)
Exemplo n.º 11
0
 def test_dumps_okp_private_key(self):
     key = read_file_path('ed25519-pkcs8.pem')
     jwk = JsonWebKey(RFC8037_ALGORITHMS)
     self.assertRaises(ValueError, jwk.dumps, key)
     obj = jwk.dumps(key, 'OKP')
     self.assertEqual(obj['kty'], 'OKP')
     self.assertEqual(obj['crv'], 'Ed25519')
     self.assertIn('d', obj)
Exemplo n.º 12
0
 def test_ec_private_key(self):
     # https://tools.ietf.org/html/rfc7520#section-3.2
     obj = read_file_path('ec_private.json')
     key = jwk.loads(obj)
     new_obj = jwk.dumps(key, 'EC')
     self.assertEqual(new_obj['crv'], obj['crv'])
     self.assertBase64IntEqual(new_obj['x'], obj['x'])
     self.assertBase64IntEqual(new_obj['y'], obj['y'])
     self.assertBase64IntEqual(new_obj['d'], obj['d'])
Exemplo n.º 13
0
def generate_token() -> Tuple:
    """Generate RSA Key pair to be used to sign token and the JWT Token itself."""
    private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend())
    public_key = private_key.public_key().public_bytes(
        encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo
    )
    pem = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption(),
    )
    # we set no `exp` and other claims as they are optional in a real scenario these should bde set
    # See available claims here: https://www.iana.org/assignments/jwt/jwt.xhtml
    # the important claim is the "authorities"
    public_jwk = jwk.dumps(public_key, kty="RSA")
    private_jwk = jwk.dumps(pem, kty="RSA")

    return (public_jwk, private_jwk)
Exemplo n.º 14
0
 def test_loads_okp_public_key(self):
     obj = {
         "x": "AD9E0JYnpV-OxZbd8aN1t4z71Vtf6JcJC7TYHT0HDbg",
         "crv": "Ed25519",
         "kty": "OKP"
     }
     key = jwk.loads(obj)
     new_obj = jwk.dumps(key)
     self.assertEqual(obj['x'], new_obj['x'])
Exemplo n.º 15
0
 def test_ec_public_key(self):
     # https://tools.ietf.org/html/rfc7520#section-3.1
     obj = read_file_path('ec_public.json')
     key = jwk.loads(obj)
     new_obj = jwk.dumps(key)
     self.assertEqual(new_obj['crv'], obj['crv'])
     self.assertBase64IntEqual(new_obj['x'], obj['x'])
     self.assertBase64IntEqual(new_obj['y'], obj['y'])
     self.assertEqual(key.as_json()[0], '{')
Exemplo n.º 16
0
Arquivo: mfa.py Projeto: SURFscz/SBS
def _get_public_key():
    global public_key_json
    if public_key_json is None:
        public_key = read_file(current_app.app_config.oidc.public_rsa_signing_key_path)
        jwks = jwk.dumps(public_key, kty='RSA')
        jwks["alg"] = "RS256"
        jwks["kid"] = "sbs"
        jwks["use"] = "sig"
        public_key_json = {"keys": [jwks]}
    return public_key_json
Exemplo n.º 17
0
 def test_loads_okp_private_key(self):
     obj = {
         'x': '11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo',
         'd': 'nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A',
         'crv': 'Ed25519',
         'kty': 'OKP'
     }
     key = jwk.loads(obj)
     new_obj = jwk.dumps(key)
     self.assertEqual(obj['d'], new_obj['d'])
Exemplo n.º 18
0
def get_public_key(private_key):
    return jwk.dumps(
        jwk.loads(private_key).public_key().public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo,
        ).decode(),
        kty=JWT_KEY_ALGORITHM,
        use="sig",
        kid=JWT_KEY_ID,
        alg=JWT_ALGORITHM,
    )
Exemplo n.º 19
0
def generate_jwks() -> Tuple[dict, dict]:
    """Generate JWK set."""
    # Generate keys
    print("Generating keys.")
    private_key = rsa.generate_private_key(public_exponent=65537,
                                           key_size=2048,
                                           backend=default_backend())
    public_key = private_key.public_key().public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo)
    pem = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption(),
    )
    # Public data to public_key.json
    public_data = {"keys": [jwk.dumps(public_key, kty="RSA")]}
    public_data["keys"][0].update({"kid": secrets.token_hex(4)})
    public_data["keys"][0].update({"alg": "RS256"})
    # Private data to private_key.json
    return public_data, jwk.dumps(pem, kty="RSA")
Exemplo n.º 20
0
 def test_rsa_private_key(self):
     # https://tools.ietf.org/html/rfc7520#section-3.4
     obj = RSA_PRIVATE_KEY
     key = jwk.loads(obj)
     new_obj = jwk.dumps(key, 'RSA')
     self.assertBase64IntEqual(new_obj['n'], obj['n'])
     self.assertBase64IntEqual(new_obj['e'], obj['e'])
     self.assertBase64IntEqual(new_obj['d'], obj['d'])
     self.assertBase64IntEqual(new_obj['p'], obj['p'])
     self.assertBase64IntEqual(new_obj['q'], obj['q'])
     self.assertBase64IntEqual(new_obj['dp'], obj['dp'])
     self.assertBase64IntEqual(new_obj['dq'], obj['dq'])
     self.assertBase64IntEqual(new_obj['qi'], obj['qi'])
Exemplo n.º 21
0
    def test_error_upon_invalid_jwt(self, load_config_mock):
        load_config_mock.return_value = load_test_env_vars(
            OIDC_DISCOVERY_URI=
            'http://test.token.com/.well-known/oidc-configuration',
            SELF_DOMAIN='test.com',
        )

        event = {
            'queryStringParameters': {
                'state': 'abc123',
                'code': 'def987',
            },
            'headers': {
                'Cookie': f'{main.USER_STATE_COOKIE_KEY}=abc123',
            },
        }

        discovery_doc = {
            'authorization_endpoint': 'http://test.token.com/token',
            'jwks_uri': 'http://test.token.com/jwks',
            'token_endpoint': 'http://test.token.com/token',
        }

        key_data = jwk.dumps(TEST_RSA_KEY, kty='RSA')

        test_jwt = jwt.encode(
            {
                'alg': 'RS256'
            },
            {
                'username': '******'
            },
            key_data,
        ).decode('utf-8')

        with requests_mock.Mocker() as mock:
            mock.get(os.environ['OIDC_DISCOVERY_URI'], json=discovery_doc)
            mock.get(discovery_doc['jwks_uri'], json={
                'keys': [
                    key_data,
                ],
            })
            mock.post(discovery_doc['token_endpoint'],
                      json={
                          'id_token': 'testtoken',
                      })

            response = main.callback(event, None)

        assert response['statusCode'] == 400
        assert 'Set-Cookie' not in response['headers']
Exemplo n.º 22
0
    def test_openid_authorize(self):
        request = testing.DummyRequest(path="/login")
        key = jwk.dumps('secret', 'oct', kid='f')

        oauth = OAuth()
        client = oauth.register(
            'dev',
            client_id='dev',
            jwks={'keys': [key]},
            api_base_url='https://i.b/api',
            access_token_url='https://i.b/token',
            authorize_url='https://i.b/authorize',
            client_kwargs={'scope': 'openid profile'},
        )

        resp = client.authorize_redirect(request, 'https://b.com/bar')
        assert resp.status_code == 302
        url = resp.headers.get('location')
        assert 'nonce=' in url

        query_data = dict(url_decode(urlparse.urlparse(url).query))
        token = get_bearer_token()
        token['id_token'] = generate_id_token(
            token, {'sub': '123'}, key,
            alg='HS256', iss='https://i.b',
            aud='dev', exp=3600, nonce=query_data['nonce'],
        )
        state = query_data['state']
        metadata = {
            "issuer": "https://i.b",
            "id_token_signing_alg_values_supported": ["HS256", "RS256"],
            'jwks': {'keys': [{'k': 'c2VjcmV0', 'kid': 'f', 'kty': 'oct'}]}
        }

        with (
            mock.patch('requests.sessions.Session.send') as send,
            mock.patch.object(client, "load_server_metadata") as load_server_metadata
        ):
            send.return_value = mock_send_value(token)
            load_server_metadata.return_value = metadata

            request2 = testing.DummyRequest(
                path='/authorize',
                params={"state": state, "code": 'foo'},
            )
            request2.session = request.session

            token = client.authorize_access_token(request2)
            assert token['access_token'] == 'a'
            assert 'userinfo' in token
            assert token['userinfo']['sub'] == '123'
Exemplo n.º 23
0
def jwks():
    with open(current_app.config["JWT"]["PUBLIC_KEY"]) as fd:
        pubkey = fd.read()

    obj = jwk.dumps(pubkey,
                    current_app.config["JWT"].get("KTY", DEFAULT_JWT_KTY))
    return jsonify({
        "keys": [{
            "kid": None,
            "use": "sig",
            "alg": current_app.config["JWT"].get("ALG", DEFAULT_JWT_ALG),
            **obj,
        }]
    })
Exemplo n.º 24
0
    def test_openid_authorize(self):
        app = Flask(__name__)
        app.secret_key = '!'
        oauth = OAuth(app)
        key = jwk.dumps('secret', 'oct', kid='f')

        client = oauth.register(
            'dev',
            client_id='dev',
            api_base_url='https://i.b/api',
            access_token_url='https://i.b/token',
            authorize_url='https://i.b/authorize',
            client_kwargs={'scope': 'openid profile'},
            jwks={'keys': [key]},
        )

        with app.test_request_context():
            resp = client.authorize_redirect('https://b.com/bar')
            self.assertEqual(resp.status_code, 302)

            url = resp.headers['Location']
            query_data = dict(url_decode(urlparse.urlparse(url).query))

            state = query_data['state']
            self.assertIsNotNone(state)
            session_data = session[f'_state_dev_{state}']
            nonce = session_data['data']['nonce']
            self.assertIsNotNone(nonce)
            self.assertEqual(nonce, query_data['nonce'])

        token = get_bearer_token()
        token['id_token'] = generate_id_token(
            token,
            {'sub': '123'},
            key,
            alg='HS256',
            iss='https://i.b',
            aud='dev',
            exp=3600,
            nonce=query_data['nonce'],
        )
        path = '/?code=a&state={}'.format(state)
        with app.test_request_context(path=path):
            session[f'_state_dev_{state}'] = session_data
            with mock.patch('requests.sessions.Session.send') as send:
                send.return_value = mock_send_value(token)
                token = client.authorize_access_token()
                self.assertEqual(token['access_token'], 'a')
                self.assertIn('userinfo', token)
Exemplo n.º 25
0
    def encrypt(self, data, type='AES', Key=None, dump=True):
        """
        Encrypt data using RSA , AES

        param: type= type of key used in encryption: 'AES' or 'RSA'
        param: key= use your own key for RSA encryption
        param: dump= dumps the data if neccessary
        """

        if dump == True:
            payload = str(json.dumps(data)).encode()
        else:
            payload = str(data).encode()

        if type == 'RSA':
            key = RSA.generate(2048)
            key = key.exportKey('PEM')
            key = jwk.dumps(key, kty='RSA')

            if Key:
                key = Key

            protected = {'alg': 'RSA-OAEP', 'enc': 'A256GCM'}
            jwe = JsonWebEncryption()
            token = jwe.serialize_compact(protected, payload, key)
            token = token.decode()
        else:
            key = secrets.token_urlsafe(32)
            token = SJCL().encrypt(payload, key, "ccm", 1000, 32)
            token['salt'] = str(token['salt']).replace("b'",
                                                       "").replace("'", "")
            token['ct'] = str(token['ct']).replace("b'", "").replace("'", "")
            token['iv'] = str(token['iv']).replace("b'", "").replace("'", "")
            dic = {}
            dic['iv'] = token['iv']
            dic['v'] = token['v']
            dic['iter'] = token['iter']
            dic['ks'] = token['ks']
            dic['ts'] = token['ts']
            dic['mode'] = token['mode']
            dic['adata'] = token['adata']
            dic['cipher'] = token['cipher']
            dic['salt'] = token['salt']
            dic['ct'] = token['ct']
            token = dic
        return {'token': token, 'key': key}
Exemplo n.º 26
0
    def test_openid_authorize(self):
        request = self.factory.get('/login')
        request.session = self.factory.session
        key = jwk.dumps('secret', 'oct', kid='f')

        oauth = OAuth()
        client = oauth.register(
            'dev',
            client_id='dev',
            jwks={'keys': [key]},
            api_base_url='https://i.b/api',
            access_token_url='https://i.b/token',
            authorize_url='https://i.b/authorize',
            client_kwargs={'scope': 'openid profile'},
        )

        resp = client.authorize_redirect(request, 'https://b.com/bar')
        self.assertEqual(resp.status_code, 302)
        url = resp.get('Location')
        self.assertIn('nonce=', url)
        query_data = dict(url_decode(urlparse.urlparse(url).query))

        token = get_bearer_token()
        token['id_token'] = generate_id_token(
            token,
            {'sub': '123'},
            key,
            alg='HS256',
            iss='https://i.b',
            aud='dev',
            exp=3600,
            nonce=query_data['nonce'],
        )
        state = query_data['state']
        with mock.patch('requests.sessions.Session.send') as send:
            send.return_value = mock_send_value(token)

            request2 = self.factory.get(
                '/authorize?state={}&code=foo'.format(state))
            request2.session = request.session

            token = client.authorize_access_token(request2)
            self.assertEqual(token['access_token'], 'a')
            self.assertIn('userinfo', token)
            self.assertEqual(token['userinfo']['sub'], '123')
Exemplo n.º 27
0
 def test_rsa_private_key2(self):
     obj = {
         "kty": "RSA",
         "kid": "*****@*****.**",
         "use": "sig",
         "n": RSA_PRIVATE_KEY['n'],
         'd': RSA_PRIVATE_KEY['d'],
         "e": "AQAB"
     }
     key = jwk.loads(obj)
     new_obj = jwk.dumps(key, 'RSA')
     self.assertBase64IntEqual(new_obj['n'], obj['n'])
     self.assertBase64IntEqual(new_obj['e'], obj['e'])
     self.assertBase64IntEqual(new_obj['d'], obj['d'])
     self.assertBase64IntEqual(new_obj['p'], RSA_PRIVATE_KEY['p'])
     self.assertBase64IntEqual(new_obj['q'], RSA_PRIVATE_KEY['q'])
     self.assertBase64IntEqual(new_obj['dp'], RSA_PRIVATE_KEY['dp'])
     self.assertBase64IntEqual(new_obj['dq'], RSA_PRIVATE_KEY['dq'])
     self.assertBase64IntEqual(new_obj['qi'], RSA_PRIVATE_KEY['qi'])
Exemplo n.º 28
0
    def test_parse_id_token(self):
        key = jwk.dumps('secret', 'oct', kid='f')
        token = get_bearer_token()
        id_token = generate_id_token(
            token,
            {'sub': '123'},
            key,
            alg='HS256',
            iss='https://i.b',
            aud='dev',
            exp=3600,
            nonce='n',
        )

        app = Flask(__name__)
        app.secret_key = '!'
        oauth = OAuth(app)
        client = oauth.register(
            'dev',
            client_id='dev',
            client_secret='dev',
            fetch_token=get_bearer_token,
            jwks={'keys': [key]},
            issuer='https://i.b',
            id_token_signing_alg_values_supported=['HS256', 'RS256'],
        )
        with app.test_request_context():
            self.assertIsNone(client.parse_id_token(token, nonce='n'))

            token['id_token'] = id_token
            user = client.parse_id_token(token, nonce='n')
            self.assertEqual(user.sub, '123')

            claims_options = {'iss': {'value': 'https://i.b'}}
            user = client.parse_id_token(token,
                                         nonce='n',
                                         claims_options=claims_options)
            self.assertEqual(user.sub, '123')

            claims_options = {'iss': {'value': 'https://i.c'}}
            self.assertRaises(InvalidClaimError, client.parse_id_token, token,
                              'n', claims_options)
Exemplo n.º 29
0
async def test_parse_id_token():
    key = jwk.dumps('secret', 'oct', kid='f')
    token = get_bearer_token()
    id_token = generate_id_token(
        token,
        {'sub': '123'},
        key,
        alg='HS256',
        iss='https://i.b',
        aud='dev',
        exp=3600,
        nonce='n',
    )

    oauth = OAuth()
    client = oauth.register(
        'dev',
        client_id='dev',
        client_secret='dev',
        fetch_token=get_bearer_token,
        jwks={'keys': [key]},
        issuer='https://i.b',
        id_token_signing_alg_values_supported=['HS256', 'RS256'],
    )
    req_scope = {'type': 'http', 'session': {'_dev_authlib_nonce_': 'n'}}
    req = Request(req_scope)

    user = await client.parse_id_token(req, token)
    assert user is None

    token['id_token'] = id_token
    user = await client.parse_id_token(req, token)
    assert user.sub == '123'

    claims_options = {'iss': {'value': 'https://i.b'}}
    user = await client.parse_id_token(req, token, claims_options)
    assert user.sub == '123'

    with pytest.raises(InvalidClaimError):
        claims_options = {'iss': {'value': 'https://i.c'}}
        await client.parse_id_token(req, token, claims_options)
Exemplo n.º 30
0
    def test_force_fetch_jwks_uri(self):
        secret_keys = read_file_path('jwks_private.json')
        token = get_bearer_token()
        id_token = generate_id_token(
            token,
            {'sub': '123'},
            secret_keys,
            alg='RS256',
            iss='https://i.b',
            aud='dev',
            exp=3600,
            nonce='n',
        )

        app = Flask(__name__)
        app.secret_key = '!'
        oauth = OAuth(app)
        client = oauth.register(
            'dev',
            client_id='dev',
            client_secret='dev',
            fetch_token=get_bearer_token,
            jwks={'keys': [jwk.dumps('secret', 'oct', kid='f')]},
            jwks_uri='https://i.b/jwks',
            issuer='https://i.b',
        )

        def fake_send(sess, req, **kwargs):
            resp = mock.MagicMock()
            resp.json = lambda: read_file_path('jwks_public.json')
            resp.status_code = 200
            return resp

        with app.test_request_context():
            session['_dev_authlib_nonce_'] = 'n'
            self.assertIsNone(client.parse_id_token(token))

            with mock.patch('requests.sessions.Session.send', fake_send):
                token['id_token'] = id_token
                user = client.parse_id_token(token)
                self.assertEqual(user.sub, '123')