Skip to content

NTLM Authentication via Browser Fails through Kong Ingress – Any Way to Handle This with a Plugin? #7658

@aleksander20021221

Description

@aleksander20021221

Hello,

I’m working on a task that requires proxying a legacy NTLM-authenticated web application (ASP.NET) through Kong Gateway deployed in Kubernetes. The backend service is exposed via a Kubernetes ExternalName service, and the requirement is that the traffic must go through Kong.

Architecture
Kong Gateway (v3.8) deployed in Kubernetes as an Ingress Controller

Backend: legacy application requiring full NTLM handshake

Clients: modern browsers (Chrome, Edge) in a corporate environment, using NTLM authentication

Kong configuration:

preserve-host: true

strip-path: false

upstream keepalive enabled

Single Kong pod (replica count = 1)

sessionAffinity: ClientIP on the relevant Kubernetes Service

Traffic flow:
Browser → Kong (Ingress) → ExternalName service → NTLM backend

Problem
NTLM authentication fails when accessed via a browser.

Modern browsers, after the initial request, send multiple parallel HTTP requests for additional resources (JavaScript, CSS, images), each including an Authorization: NTLM header. However, NTLM requires the complete handshake to occur over a single TCP connection. Since Kong is a Layer 7 proxy based on nginx, each request is proxied over separate connections, which breaks the NTLM handshake. As a result:

The backend returns 401 Unauthorized for each resource

The browser repeatedly prompts for authentication or enters a failure loop

When bypassing Kong and using HAProxy directly (with option http-keep-alive and session stickiness), NTLM works correctly.

Goal
We would like to retain Kong for routing, plugin support, and integration capabilities. Ideally, Kong would allow NTLM authentication to work by handling it once and reusing the authentication state.

Question
Is it technically possible to implement a custom Kong plugin that:

Parses and handles the NTLM Authorization header

Performs the necessary handshake steps

Caches the session (based on client IP or another identifier)

Allows subsequent requests to be forwarded without repeating the handshake

Or is this fundamentally impossible because of Kong’s architecture and the nginx proxy model, which does not maintain a persistent TCP connection across multiple HTTP requests from the same client?

Any advice, guidance, or workarounds would be greatly appreciated. Thank you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions