-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Consider exposing Bedrock's "Connection Features" on HttpContext #9213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What does it mean for HTTP/2 connections? In that scenario if you set a connection level feature during a request it can interfere with other requests on that same connection (since they overlap in execution). |
@davidfowl good point. Windows/Kerberos auth isn't supported on HTTP/2 for similar reasons. We could skip HTTP/2 connections for the time being. Or you have to make that feature collection concurrent. |
Yep, this is a good point.
For NTLM, this is sufficient, since as @Tratcher says, you can't do NTLM over HTTP/2. |
Btw, the alternative feature (one of the two options is basically required for NTLM) is something like this: public interface IHttpConnectionLifetimeFeature
{
CancellationToken ConnectionTerminated { get; }
} That would allow the auth handler to empty it's stored context (I want to avoid using "cache" since it's not an optimization, it's mandatory). |
You can already get connection-level features, just not set them. As a temporary hack, you could have a mutable INtlmConnectionStateFeature pre-set by the server. Or less hacky, we could have a the server add a non-mutable IHttpConnectionLifetimeFeature. |
Additional requirement: Dispose a given object when cleaning up a connection. This is the connection equivalent of HttpResponse.OnCompleted/RegisterForDispose. Kerberos/NTLM auth on windows produces a WindowsIdentity that holds an OS handle. The finalizer will take care of it eventually, but in a high churn situation you could exhaust OS handles before the finalizer kicks in. The NTAuth connection state will also need to be disposed. |
I was able to implement this using three existing features:
IConnectionLifetimeFeature isn't ideal because it could fire mid-request. We'll want to replace it with the a connection level equivalent of RegisterForDispose. |
This would be very useful for some of our own downstream request context objects too, which are currently pooled via ObjectPool. EDIT: For HTTP/2 we wouldn't indeed be able to have a single cached reference but a super small pool on a connection to very naturally segment, otherwise global, contention. |
Kestrel currently does push Connection Features through to Request Features (you can't add new ones, but you can access any existing connection features), so we're good for 3.0. Moving to the backlog. |
@Tratcher we exactly need this feature, currently two users get the same windows identity (the one from the user who logged in first), could you provide some help how this can be solved? Do you have a code sample? br |
That sounds like a client bug, two users should never attempt to use the same connection with NTLM/Kerb and UnsafeNTLMConnectionSharing. Consider disabling NegotiateOptions.PersistNTLM/KerberosCredentials. |
@Tratcher FYI: It's not happening always, but we found out (with the logs of YARP and the logs of our server application) that once userA is authenticated and then right after that userB tries to authenticate via NTLM using asp.net mvc (.net 4.7.2) hosted in IIS the windows identity of userA is used instead of userBs, it's only happening when using YARP |
NTLM must not be used with TLS terminating proxies like YARP since external connections from different users can share the same connection to the backend. |
@Tratcher thx for the clarification 👍 Br |
I'm filing this to track some ideas that came up while @Tratcher was looking at Kerberos/NTLM auth. The exact requirements are still coming but I wanted to file this to start some parallel discussion on things that may help make the implementation smooth.
NTLM requires mandatory
cachingstorage of security context information between requests occurring on the same connection. So, given a connectionC
and NTLM-authenticated requestsR1
andR2
(withR2
following afterR1
), it is not possible to authenticateR2
without usingcachedstored data from the authentication process inR1
.Using current features, it is relatively simple to implement this by caching this data keyed off the Connection ID. However this has a few problems:
cachedictionary when there is generally a connection state object in the serverexpire this cacheclean-up unnecessary contexts unless the server exposes a "Connection Ended" event of some kind.The auth middleware can implement this feature entirely, however, it needs to be able to store it somewhere that is guaranteed to live across the entire connection. Bedrock's "Connection Features" is a perfect place for this, however it is not exposed up through the stack.
If we had a way to Get/Set connection-level features, we could implement this in the auth handler with pseudo-code like this:
My proposal is this:
IHttpConnectionFeaturesFeature
(name can be bikeshed later)Add read-only
Features
property toConnectionInfo
which returnsnull
if there is noIHttpConnectionFeaturesFeature
present.Implement
IHttpConnectionFeaturesFeature
in Kestrel to expose the underlying Connection's feature collection.The NTLM authentication logic will require this feature be present in order to function, and will throw a useful exception if it isn't present. This way, servers which do not support this feature are not "broken", but they can't be used with NTLM auth. Since even the "custom dictionary" method requires a server change in order to detect the end of the connection, this seems like a reasonable requirement to make.
We can consider implementing the feature in IIS and HttpSysServer as well, though since they have integrated Windows Auth, it may not be as necessary at the moment.
Let the discussion begin! @davidfowl @halter73
The text was updated successfully, but these errors were encountered: