Dávid Paksy created PHOENIX-8033:
------------------------------------
Summary: phoenixdb: use native Windows SSPI for SPNEGO instead of
requiring MIT Kerberos
Key: PHOENIX-8033
URL: https://issues.apache.org/jira/browse/PHOENIX-8033
Project: Phoenix
Issue Type: Task
Reporter: Dávid Paksy
h3. Problem
On Windows, phoenixdb requires MIT Kerberos for Windows (KfW), even though
Windows has Kerberos built in (LSA/SSPI):
* {{requests-gssapi}} (which pulls in {{{}gssapi{}}}) is an unconditional
install requirement.
* {{phoenixdb/__init__.py}} imports {{gssapi}} and {{requests_gssapi}} at
module level, so {{import phoenixdb}} fails without a working GSSAPI library,
even for BASIC/DIGEST/no authentication.
h3. Changes
* {{{}phoenixdb/__init__.py{}}}: the {{gssapi}} / {{requests_gssapi}} imports
move into {{{}_get_SPNEGOAuth(){}}}, which only runs for
{{{}authentication='SPNEGO'{}}}. On {{win32}} it returns the new SSPI auth
class; elsewhere (or if {{pyspnego}} is not available) it builds
{{HTTPSPNEGOAuth(opportunistic_auth=True, mech=SPNEGO)}} exactly as before.
* {{phoenixdb/sspi_auth.py}} (new): {{{}HTTPSPNEGOAuthSSPI{}}}, a small
{{requests}} auth class on top of
[pyspnego|https://github.com/jborean93/pyspnego], which uses native SSPI on
Windows and so the logged-on user's tickets (no KfW, no {{{}kinit{}}}). It
mirrors the current behaviour: an opportunistic {{Negotiate}} token for
{{{}HTTP/<host>{}}}, mutual auth disabled. A 401 carrying a server token is
answered once on the same connection (multi-leg, e.g. NTLM fallback); a 401
without one is returned as is.
** It uses {{protocol="negotiate"}} (the SPNEGO mechanism), keeping the
mechanism choice from PHOENIX-6414 / PHOENIX-6781. {{requests-kerberos}} was
not used because it hard-codes the raw Kerberos mechanism.
** A {{gssapi}} package installed without KfW raises {{OSError}} on import,
and pyspnego only catches {{ImportError}} around its optional gssapi import
(reported as [import spnego fails on Windows when python-gssapi is installed
without MIT KfW (OSError not caught)
jborean93/pyspnego#117|https://github.com/jborean93/pyspnego/issues/117]), so
{{import spnego}} fails. That case now raises a {{RuntimeError}} naming the
cause and the fix ({{{}pip uninstall gssapi requests-gssapi{}}}).
* {{{}setup.py{}}}, {{{}requirements.txt{}}}: platform markers;
{{requests-gssapi}} on non-Windows, {{pyspnego}} on Windows (Python >= 3.8).
Python < 3.8 is unchanged.
Linux/macOS behaviour and the public API ({{{}connect(...,
authentication='SPNEGO'){}}}, {{user}} as {{{}doAs{}}}) are unchanged.
h3. Testing
* Windows 11 (domain-joined, no KfW, no {{{}kinit{}}}), Python 3.12 x64,
against a Kerberized Phoenix Query Server: {{SELECT 1}} and table queries
succeed with {{{}authentication='SPNEGO'{}}}; {{klist}} shows the
{{HTTP/<fqdn>}} service ticket obtained through SSPI.
* Multi-leg path: loopback test with a real SSPI acceptor
({{{}spnego.server{}}}), NTLM fallback: 401 + challenge, then 200 on the same
connection; a 401 without a token is returned after a single request.
* macOS: {{import phoenixdb}} works without {{gssapi}} installed; the existing
unit tests that do not need a live Query Server pass.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)