Skip to content

http.sys: Allow configuring HTTP_AUTH_EX_FLAGs as options #51833

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

Merged
merged 7 commits into from
Feb 9, 2024

Conversation

evgenykotkov
Copy link
Contributor

@evgenykotkov evgenykotkov commented Nov 2, 2023

http.sys: Allow configuring HTTP_AUTH_EX_FLAGs as options

Description

The native HTTP.sys API offers two extended authentication flags:

that can be used by users to fine-tune their Windows authentication setups.

For instance, the HTTP_AUTH_EX_FLAG_ENABLE_KERBEROS_CREDENTIAL_CACHING flag can be used to avoid having to authenticate every request and make the authentication session-based, thus reducing the overall number of requests and improving the high-latency scenarios. Enabling it can be used to achieve the same behavior as with the authPersistNonNTLM option in IIS.

Change details:

  • The groundwork change c50346d fixes an existing issue in the definition/layout of the HTTP_SERVER_AUTHENTICATION_INFO interop structure.

  • The core change 7489786 exposes both flags as options in the authentication manager. Because setting the extended flags requires a different property type (HttpServerExtendedAuthenticationProperty), we take additional precaution to only use that property type if we actually have the extended flags to set, and use the original HttpServerAuthenticationProperty otherwise.

Fixes #13634

API proposal: #51990

@ghost ghost added area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions community-contribution Indicates that the PR has been added by a community member labels Nov 2, 2023
@ghost
Copy link

ghost commented Nov 2, 2023

Thanks for your PR, @evgenykotkov. Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@evgenykotkov

This comment was marked as resolved.

@Tratcher
Copy link
Member

Tratcher commented Nov 2, 2023

@Tratcher
Copy link
Member

Tratcher commented Nov 2, 2023

@blowdart

Copy link
Contributor

@blowdart blowdart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cached in the comments is vague.

Cached for how long?

@Tratcher Tratcher added the api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews label Nov 2, 2023
@ghost
Copy link

ghost commented Nov 2, 2023

Thank you for your API proposal. I'm removing the api-ready-for-review label. API Proposals should be submitted for review through Issues based on this template.

@ghost ghost removed the api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews label Nov 2, 2023
@Tratcher
Copy link
Member

Tratcher commented Nov 2, 2023

I think this is the same intent as

/// <summary>
/// Indicates if Kerberos credentials should be persisted and re-used for subsquent anonymous requests.
/// This option must not be used if connections may be shared by requests from different users.
/// </summary>
/// <value>Defaults to <see langword="false"/>.</value>
public bool PersistKerberosCredentials { get; set; }

Copy link
Member

@amcasey amcasey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please have a look at the merge conflicts.

/// or Negotiate authentication. Kerberos or Negotiate authentication must be enabled.
/// The default is false.
/// </summary>
public bool CaptureCredential { get; set; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we're mirroring an underlying API, but it seems like this should be "CaptureCredentials".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CaptureProcessCredentials

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In 39edd84, I went with the CaptureCredentials name for this option. Please let me know if it works for you.

internal bool ReceiveContextHandle;
internal bool DisableNTLMCredentialCaching;
internal ulong ExFlags;
internal byte ReceiveMutualAuth;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to retain at least a comment indicating that it's boolean.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to retain at least a comment indicating that it's boolean.

With 7f18f8f, this change seems to be no longer necessary for main.

However, since c50346d seems to fix a rather significant issue with an invalid structure layout/size, is it something that should be backported to stable branches?

Please let me know if that is the case, and whether you'd want me to handle that with a separate PR or in any other convenient way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you demonstrate any negative effects from the old structure? We've not had any complaints here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you demonstrate any negative effects from the old structure? We've not had any complaints here.

In my x64 environment, the native size of the structure is:

sizeof(HTTP_SERVER_AUTHENTICATION_INFO) == 64

In the same environment, the size of the interop structure before the fix is:

Marshal.SizeOf<HttpApiTypes.HTTP_SERVER_AUTHENTICATION_INFO> == 80

In turn, this means that:

  1. The field layout is wrong after the AuthSchemes field
  2. An invalid (larger) size is passed during the call to HttpSetUrlGroupProperty()

Maybe 1. hasn't been causing any practical issues because the current version of the code didn't change any structure fields after the AuthSchemes. But I would still say that 2. is quite significant just by itself: the behavior when passing an invalid size to the HttpSetUrlGroupProperty() function seems to be unspecified, and could have easily resulted in an error or even a crash.

In my environment the call seems to succeed, so from that perspective this remains a theoretical issue, but, to be precise, there is a chance that this behavior may change in the future or may differ depending on the OS version — I haven't checked that in detail.


For reference, here is the native definition of the related typedefs and the structure itself:

typedef BYTE  BOOLEAN;
typedef unsigned char UCHAR;

typedef struct _HTTP_SERVER_AUTHENTICATION_INFO
{
    HTTP_PROPERTY_FLAGS Flags;

    ULONG AuthSchemes;

    BOOLEAN ReceiveMutualAuth;
    BOOLEAN ReceiveContextHandle;
    BOOLEAN DisableNTLMCredentialCaching;

    UCHAR   ExFlags;

    HTTP_SERVER_AUTHENTICATION_DIGEST_PARAMS DigestParams;
    HTTP_SERVER_AUTHENTICATION_BASIC_PARAMS  BasicParams;

} HTTP_SERVER_AUTHENTICATION_INFO, *PHTTP_SERVER_AUTHENTICATION_INFO;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, we won't consider backporting it without a repro of a functional issue. For now it's enough that the issue is gone in main.

The native HTTP.sys API offers two extended authentication flags:
- `HTTP_AUTH_EX_FLAG_ENABLE_KERBEROS_CREDENTIAL_CACHING` and
- `HTTP_AUTH_EX_FLAG_CAPTURE_CREDENTIAL`
that can be used by users to fine-tune their Windows authentication
setups.

For instance, the `HTTP_AUTH_EX_FLAG_ENABLE_KERBEROS_CREDENTIAL_CACHING`
flag can be used to avoid having to authenticate every request and make
the authentication session-based, thus reducing the overall number of
requests and improving the high-latency scenarios.  Enabling it can be
used to achieve the same behavior as with the `authPersistNonNTLM`
option in IIS.  (See dotnet#13634)

This commit exposes both flags as options in the authentication manager.
Because setting the extended flags requires a different property type
(`HttpServerExtendedAuthenticationProperty`), we take additional precaution
to only use that property type if we actually have the extended flags to
set, and use the original `HttpServerAuthenticationProperty` otherwise.
@evgenykotkov
Copy link
Contributor Author

Please have a look at the merge conflicts.

Done.

(With 7f18f8f, the groundwork change c50346d is no longer required, so I rebased the core change as bf884dc.)

@ghost
Copy link

ghost commented Nov 18, 2023

Looks like this PR hasn't been active for some time and the codebase could have been changed in the meantime.
To make sure no conflicting changes have occurred, please rerun validation before merging. You can do this by leaving an /azp run comment here (requires commit rights), or by simply closing and reopening.

@ghost ghost added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Nov 18, 2023
@amcasey
Copy link
Member

amcasey commented Nov 27, 2023

I think we're just waiting for an API review.

@amcasey
Copy link
Member

amcasey commented Nov 28, 2023

API review asked for a rename. Otherwise, we should be good to go.

@evgenykotkov
Copy link
Contributor Author

evgenykotkov commented Feb 5, 2024

API review asked for a rename. Otherwise, we should be good to go.

Based on the discussion in #51990, I kept the original names and made a couple of tweaks to the docstrings.

@evgenykotkov evgenykotkov requested a review from amcasey February 6, 2024 16:40
@amcasey amcasey enabled auto-merge (squash) February 7, 2024 22:43
@amcasey amcasey merged commit 4deb60b into dotnet:main Feb 9, 2024
@dotnet-policy-service dotnet-policy-service bot added this to the 9.0-preview2 milestone Feb 9, 2024
onurmicoogullari pushed a commit to onurmicoogullari/aspnetcore that referenced this pull request Feb 14, 2024
* http.sys: Allow configuring HTTP_AUTH_EX_FLAGs as options

The native HTTP.sys API offers two extended authentication flags:
- `HTTP_AUTH_EX_FLAG_ENABLE_KERBEROS_CREDENTIAL_CACHING` and
- `HTTP_AUTH_EX_FLAG_CAPTURE_CREDENTIAL`
that can be used by users to fine-tune their Windows authentication
setups.

For instance, the `HTTP_AUTH_EX_FLAG_ENABLE_KERBEROS_CREDENTIAL_CACHING`
flag can be used to avoid having to authenticate every request and make
the authentication session-based, thus reducing the overall number of
requests and improving the high-latency scenarios.  Enabling it can be
used to achieve the same behavior as with the `authPersistNonNTLM`
option in IIS.  (See dotnet#13634)

This commit exposes both flags as options in the authentication manager.
Because setting the extended flags requires a different property type
(`HttpServerExtendedAuthenticationProperty`), we take additional precaution
to only use that property type if we actually have the extended flags to
set, and use the original `HttpServerAuthenticationProperty` otherwise.

* http.sys: Rename: CaptureCredential → CaptureCredentials

* http.sys: Clarify description for `EnableKerberosCredentialCaching`

* http.sys: Further clarify description for `EnableKerberosCredentialCaching`

* http.sys: Further clarify documentation for new options

Based on the discussion in dotnet#51990

* http.sys: Tweak documentation for `CaptureCredentials`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions community-contribution Indicates that the PR has been added by a community member pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Multiple 401 when using Windows authentication on HTTP.sys
5 participants