Esempio n. 1
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')
Esempio n. 2
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)
Esempio n. 3
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)
Esempio n. 4
0
async def test_force_fetch_jwks_uri():
    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 = AsyncPathMapDispatch({
        '/jwks': {'body': read_file_path('jwks_public.json')}
    })

    oauth = OAuth()
    client = oauth.register(
        'dev',
        client_id='dev',
        client_secret='dev',
        fetch_token=get_bearer_token,
        jwks_uri='https://i.b/jwks',
        issuer='https://i.b',
        client_kwargs={
            'app': app,
        }
    )

    req_scope = {'type': 'http', 'session': {'_dev_authlib_nonce_': 'n'}}
    req = Request(req_scope)
    token['id_token'] = id_token
    user = await client.parse_id_token(req, token)
    assert user.sub == '123'
Esempio n. 5
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'
Esempio n. 6
0
    def __call__(self, client: Client, grant_type: str, user: UserWithRoles,
                 scope: str):
        jwt_config = self.get_jwt_config()
        jwt_config['aud'] = [client.get_client_id()]
        jwt_config['auth_time'] = int(time.time())

        user_info = {'sub': user.user.id, 'roles': user.roles}
        if 'groups' in scope_to_list(scope):
            user_info['groups'] = user.user.groups
        return generate_id_token({},
                                 user_info,
                                 code=generate_token(
                                     config.oauth2.access_token_length),
                                 **jwt_config)
Esempio n. 7
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)
Esempio n. 8
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')
Esempio n. 9
0
def _gen_token(nonce, domain):
    token = {"token_type": "Bearer", "access_token": "at", "expires_in": 3600}
    token["id_token"] = generate_id_token(
        token,
        {
            "email": f"matthew@{domain}",
            "name": "Matthew Smith",
            "given_name": "Matthew",
            "family_name": "Smith",
            "sub": "123",
            "hd": domain,
        },
        key,
        alg="HS256",
        iss="iss",
        aud="cid",
        nonce=nonce,
    )
    return token
Esempio n. 10
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)
Esempio n. 11
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')
Esempio n. 12
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)