-
Notifications
You must be signed in to change notification settings - Fork 4.6k
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
SafeHandle has been closed when using WindowsIdentity.RunImpersonated #26446
Comments
@kouvel, do you think this could be caused by https://github.com/dotnet/coreclr/issues/17758? |
The context changed handler does not dispose the handle passed in, so I don't think dotnet/coreclr#17758 would affect it. I suspect some async callback is trying to impersonate again using the access handle, but after it has been disposed elsewhere. Netfx gets around this by duplicating the access token, that may be missing in Core. |
Repro: Task task = null;
using (var token = WindowsIdentity.GetCurrent().AccessToken)
{
WindowsIdentity.RunImpersonated(token, () =>
task = Task.Run(async () =>
await Task.Delay(1000).ConfigureAwait(false)));
}
task.Wait(); |
Workaround for now: private static void Main()
{
Task task = null;
using (var token = WindowsIdentity.GetCurrent().AccessToken)
{
WindowsIdentity.RunImpersonated(DuplicateAccessToken(token), () =>
task = Task.Run(async () =>
await Task.Delay(1000).ConfigureAwait(false)));
}
task.Wait();
}
private static SafeAccessTokenHandle DuplicateAccessToken(SafeAccessTokenHandle accessToken)
{
if (accessToken.IsInvalid)
{
return accessToken;
}
SafeAccessTokenHandle duplicateAccessToken = SafeAccessTokenHandle.InvalidHandle;
IntPtr currentProcessHandle = GetCurrentProcess();
if (!DuplicateHandle(
currentProcessHandle,
accessToken,
currentProcessHandle,
ref duplicateAccessToken,
0,
true,
DUPLICATE_SAME_ACCESS))
{
throw new SecurityException(new Win32Exception().Message);
}
return duplicateAccessToken;
}
[DllImport("kernel32.dll")]
private static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool DuplicateHandle(
IntPtr hSourceProcessHandle,
SafeAccessTokenHandle hSourceHandle,
IntPtr hTargetProcessHandle,
ref SafeAccessTokenHandle lpTargetHandle,
uint dwDesiredAccess,
bool bInheritHandle,
uint dwOptions);
private const uint DUPLICATE_SAME_ACCESS = 0x00000002; @ge0rgi, could you please try something like this as a workaround for now and let me know if that resolves the issue? Meanwhile, I've marked this issue for 2.1 servicing. |
So that callbacks for async work initiated while impersonated may continue to impersonate even after the original access token had been disposed. Fix for https://github.com/dotnet/corefx/issues/30275
@kouvel I can confirm your workaround resolves the issue. |
Thanks @ge0rgi, I have updated the workaround code inline above based on feedback in the PR |
…30346) * Duplicate the access token passed to WindowsIdentity.RunImpersonated So that callbacks for async work initiated while impersonated may continue to impersonate even after the original access token had been disposed. Fix for https://github.com/dotnet/corefx/issues/30275 * Small fix * Address feedback * Change to use ref counting, remove assert (no null check on access token parameter) * Manual add/release
…otnet#30346) * Duplicate the access token passed to WindowsIdentity.RunImpersonated So that callbacks for async work initiated while impersonated may continue to impersonate even after the original access token had been disposed. Fix for https://github.com/dotnet/corefx/issues/30275 * Small fix * Address feedback * Change to use ref counting, remove assert (no null check on access token parameter) * Manual add/release
…otnet#30346) * Duplicate the access token passed to WindowsIdentity.RunImpersonated So that callbacks for async work initiated while impersonated may continue to impersonate even after the original access token had been disposed. Fix for https://github.com/dotnet/corefx/issues/30275 * Small fix * Address feedback * Change to use ref counting, remove assert (no null check on access token parameter) * Manual add/release
…otnet#30346) So that callbacks for async work initiated while impersonated may continue to impersonate even after the original access token had been disposed. Port of dotnet#30346 to release/2.1 Fixes https://github.com/dotnet/corefx/issues/30275 * Small fix * Address feedback * Change to use ref counting, remove assert (no null check on access token parameter) * Manual add/release
…otnet#30346) So that callbacks for async work initiated while impersonated may continue to impersonate even after the original access token had been disposed. Port of dotnet#30346 to release/2.1 Fixes https://github.com/dotnet/corefx/issues/30275 * Small fix * Address feedback * Change to use ref counting, remove assert (no null check on access token parameter) * Manual add/release
…otnet#30346) So that callbacks for async work initiated while impersonated may continue to impersonate even after the original access token had been disposed. Port of dotnet#30346 and dotnet#30377 to release/2.1 Fixes https://github.com/dotnet/corefx/issues/30275 * Small fix * Address feedback * Change to use ref counting, remove assert (no null check on access token parameter) * Manual add/release
…nImpersonated (#30346) (#30379) * Duplicate the access token passed to WindowsIdentity.RunImpersonated (#30346) So that callbacks for async work initiated while impersonated may continue to impersonate even after the original access token had been disposed. Port of #30346 and #30377 to release/2.1 Fixes https://github.com/dotnet/corefx/issues/30275 * Small fix * Address feedback * Change to use ref counting, remove assert (no null check on access token parameter) * Manual add/release * Add test * Change test
Fixed in 2.1 servicing in PR dotnet/corefx#30379. Closing. |
I upgraded to 2.1.3 , the bug is still there |
@kouvel ? |
@LeroyPakade, based on dotnet/corefx#30379 (comment) it does not sound like the error is related to impersonation. Since the error mentions something about host name resolution not working, does it work if the IP address is used directly? |
I doesn't work even if i try use the IP , it works for some users but fail for others, if i change the user's context to WindowsIdentity.GetCurrent().AccessToken than it works but i want to use ((WindowsIdentity)this.User.Identity).AccessToken , Because i want to impersonate the logged in user and not the IIS user |
Do you get the same error when using IP? |
Yes ,only thing i was wondering was this windows policy , impersonate a client after authentication |
are you getting similar error like me? 37120 |
As mentioned in dotnet/corefx#37120, RunAsImpersonated is a synchronous call. So, are you able to reproduce your error if don't use async calls? |
i turned SocketsHttpHandler off still had the issue for some users only when i change HttpClientHandler to WinHttpHandler it works but than i need to supply ServerCredentials which i dont have as previously i used , UseDefaultCredentials = true |
@LeroyPakade If you're still seeing this problem in .NET Core 3.0, please open a new issue. Thx. You can try out .NET Core 3.0 Preview 4: |
Its working now with WinHttpHandler |
@davidsh SocketHttpHandler works If I use ip. But with localhost or any other hostname it gives me "This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server" error. If i use WinHttpHandler then everything works. |
dotnet/corefx#37120 is already discussing this error. Let's keep the conversation about this error on that open issue only. |
Hello everyone.
I am having trouble using Impersonation in asp.net core. I have an .NET core web API and .NET web application both running .NET core 2.1 and using Windows Authentication.
I am trying to access the web service from the web application like this:
I am getting the following Error on the production server and occasionally on my local machine
Full stack trace:
Am I misusing the the access token somehow and how do I prevent the handle from being disposed. I tried wrapping my code inside a using block, however this did not help.
PS Probably related to #24233 I had the same issues when attempting to create a middleware calling
WindowsIdentity.RunImpersonated
The text was updated successfully, but these errors were encountered: