Skip to content
This repository has been archived by the owner on Nov 1, 2018. It is now read-only.

Work around UnauthorizedAccessException for WindowsIdentity.get_AuthenticationType on IIS #231

Closed
c-s-n opened this issue Jul 13, 2016 · 5 comments
Assignees
Milestone

Comments

@c-s-n
Copy link

c-s-n commented Jul 13, 2016

Title

A System.UnauthorizedAccessException occurs when accessing System.Security.Principal.WindowsIdentity.WindowsIdentity.AuthenticationType getter on IIS, breaking the Windows Authentication of IISIntegration.

Functional impact

When using Windows Authentication, any time the Microsoft.AspNetCore.Server.IISIntegration.AuthenticationHandler.AuthenticateAsync method is called, which accesses the AuthenticationType getter, the following exception is thrown:

System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.
   at System.Security.Principal.WindowsIdentity.get_AuthenticationType()

This renders the Windows Authentication unusable on our IIS deployment server.

Minimal repro steps

  • We use a combination of Windows Authentication with IISOptions AutomaticAuthentication and ForwardWindowsAuthentication set to true, and Cookies authentication via UseCookieAuthentication(). Having Windows Authentication alone should however be sufficient to reproduce.
  • Annotate some controller with an authorization policy that specifies
policy.RequireAuthenticatedUser();
policy.AddAuthenticationSchemes("NTLM");
  • Deploy to an IIS (at least with specs mentioned below) with an application pool running under the default "ApplicationPoolIdentity"
  • Access the annotated controller

Expected result

Browser's Windows Authentication popup due to HTTP 401 response that gets the WWW-Authenticate header field with "NTLM" injected by IIS.

Actual result

We get an unhandled exception as response, with the above mentioned exception details and causes.

Further technical details

Deployment server:

  • IIS 7.5
  • Windows Server 2008 R2 x64
  • .NET Framework 4.5.2
  • ASP.NET Core 1.0.0
  • HTTP Platform Handler 1.2

Details
Accessing the AuthenticationType getter works when running on IIS Express on our development machines. It also works when changing the IIS application pool identity to "LocalSystem". It also works when currently not being logged in or logged in via Cookies authentication.
This stackoverflow report describes the problem in detail. There it is suggested to use another WindowsIdentity constructor with the AuthenticationType parameter, which should solve the problem.

Solution suggestions
Maybe you could change the AuthenticationHandler to catch this exception and if it occurs assume Windows Authentication.
Maybe use the other WindowsIdentity constructor in IISMiddleware.
(if that does not disregard the AuthenticationDescriptions option)

Notes
The exception was also mentioned in issue 75, although in a different context.

@Tratcher
Copy link
Member

Alternative solutions:

@Tratcher Tratcher added the bug label Jul 19, 2016
@muratg muratg added this to the 1.1.0 milestone Jul 25, 2016
@Tratcher
Copy link
Member

Note WebListener probably has the same issue.

@ph1ll
Copy link

ph1ll commented Sep 20, 2016

For the record, the underlying issue is the fact that WindowsIdentity.AuthenticationType makes a win32 call to LsaGetLogonSessionData

http://referencesource.microsoft.com/#mscorlib/system/security/principal/windowsidentity.cs,19b8c53c3eacbf53

MSDN page for LsaGetLogonSessionData states "To retrieve information about a logon session, the caller must be the owner of the session or a local system administrator."

https://msdn.microsoft.com/en-us/library/windows/desktop/aa378290(v=vs.85).aspx

So this issue is likely to affect all production applications that calls this code. (Any application using a policy with AuthenticationScheme of "Automatic", "Negotiate", or "NTLM").

@Tratcher
Copy link
Member

@pakrym can you check WebListener as well?

@mxa0079
Copy link

mxa0079 commented Aug 17, 2017

This is also happening with EF based identity, when calling SignInManager.IsSignedIn(ClaimsPrincipal) specifically whithin the following call:

return principal?.Identities != null &&
                principal.Identities.Any(i => i.AuthenticationType == IdentityConstants.ApplicationScheme);

Notice the call to i.AuthenticationType, which is the same root cause as the issue originally reported here.

You can see the full source code here: https://github.com/aspnet/Identity/blob/eb3ff7fc32dbfff65a1ba6dfdca16487e0f6fc41/src/Microsoft.AspNetCore.Identity/SignInManager.cs

The PR in this issue does not resolves this problem.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants