ASP.NET Impersonation and SQL Server Trusted Connection Calls - asp.net

I am working on an ASP.NET page that we, in code impersonate the requesting user. We are using the following code to start impersonating.
Dim impersonationContext As System.Security.Principal.WindowsImpersonationContext
Dim currentWindowsIdentity As System.Security.Principal.WindowsIdentity
currentWindowsIdentity = CType(User.Identity, System.Security.Principal.WindowsIdentity)
impersonationContext = currentWindowsIdentity.Impersonate()
After this we have validated that the application is running under the proper context by calling:
System.Security.Principal.WindowsIdentity.GetCurrent().Name
This returns the proper identity of the user, and file access and other items appear to be using their account. However when using the Microsoft Application Data Application Block SqlHelper class to call out to a database using a trusted connection authentication fails for the "NT AUTHORITY\ANONYMOUS LOGON" user.
We can re-validate after the failure that the current identity is still our desired account and NOT the ANONYMOUS LOGIN account.
Does anyone have an idea why this is? Or more specifically how we can get around it?
Edit
Some additional information about how the calls from these pages work.
We do the impersonate call from the .aspx page.
After we impersonate we call out to a "business logic" assembly that is referecned.
We know that the context identity is still correct here.
After that, the "business logic" assembly calls another assembly that actually executes the trusted connection call. We cannot modify this "data access" assembly, the authentication exception is reported by this assembly as well.

I think #John Sonmez is right, you're hitting the Double Hop issue. Impersonation is only half of the story, you also need to look at Delegation (assuming your network is using Kerberos authentication). The articles below were the most useful in helping me through the same issue
Impersonation and Delegation
ASP.NET Delegation

I know that I've used impersonation in ASP.NET before (using C# and accessing the filesystem) and I was wondering if you had tried wrapping the logic that includes currentWindowsIdentity.Impersonate() with a 'Using / End Using' (to explicitly define the security context for a block of code).
So, it would look like this:
Using impersonationContext = currentWindowsIdentity.Impersonate()
' Logic here
End Using

Related

Access network file from ASP.NET web handler's process?

I have the following setup:
IIS 8.0
a web handler call it test.ashx
Impersonation & Windows Authentication are both configured. Kerberos is showing as the authentication type.
test.ashx uses the unmanaged API: CreateProcessAsUser() method to run "cmd.exe /c myScript.cmd"
I put statements in myScript.cmd and see that it is running as the requesting user as I need it to. The problem I am experiencing is that the script cannot reference network files (either mapped drives or UNC path)
I need myScript.cmd to run as the requesting user and to be able to access network file resources. How do I get this to work?
I found one item that made a big difference on getting kerberos authentication to work, which is required to do impersonation and delegation. In IIS Manager I had to choose the web site, then run the Configuration Editor. Once it opened I had to choose the as from: DefaultWebSiteWeb.Config, and as the section: system.webServer/security/authentication/windowsAuthentication. Then set: useAppPoolCredentials = True. Note: useKernelMode was already set to true.
Additionally, for the web site I have the following set for Authentication:
ASP.NET: Enabled
Windows Authentication: Enabled, Provider: Negotiate, Kernel mode enabled.
Now my ASHX web handler (in C#) can start a process as the user, run a .cmd file that accesses network resources.

Cannot generate SSPI context exception after publishing mvc application to web server

After publishing a new version of my MVC app to our development web server I got the following error (abridged with account name redacted) :
Event code: 3005
Account name: xxx\xxxxxxxx
Exception type: SqlException
Exception message: The target principal name is incorrect. Cannot generate SSPI context. at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
What is causing the exception?
The issue was with a service account that we use to run our websites. I put in a request to have the accounts created and they were mistakenly set up to have the passwords expire. So everything worked great until the password expired.
Since this is a new medium priority app it was being developed in small increments over a period of several months by one developer. As a result the website did not get used very much.
The solution is to reset the password on the service account and make sure that it is set to never expire. Shut down the app pool. Update the password for the service account and then restart the app pool.
I was also facing the same issue. This was because my application is using windows authentication and defined in web.config.
Also need to change the property of web application in solution to
Windows Authentication "Enabled" which is by default "Disabled".
This helps me!!

Identifying the name of the application pool from a request

In .net, in a webservice (or website) is there an easy way of getting the name of the application pool that the service is running in, from a HttpRequest or the HttpContext?
I think its:
HttpRequest.ServerVariables["APP_POOL_ID"]
See ServerVariables on MSDN: http://msdn.microsoft.com/en-us/library/ms524602(v=vs.90).aspx

Access Session in WCF service from WebHttpBinding

I'm using WCF service (via WebGet attribute).
I'm trying to access Session from WCF service, but HttpContext.Current is null
I added AspNetCompatibilityRequirements and edited web.config but I still cannot access session.
Is it possible to use WebGet and Session together?
Thank you!
Yes, it is possible. If you edit the web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
and add the AspNetCompatiblityRequirements, the HttpContext.Current should be available.
Check everything once again, maybe you've put the attribute in the wrong place (the interface instead of the class?).
A RESTfull service with a session?
See excellent discussion here: Can you help me understand this? "Common REST Mistakes: Sessions are irrelevant"
http://javadialog.blogspot.co.uk/2009/06/common-rest-mistakes.html (point 6)
and
http://www.peej.co.uk/articles/no-sessions.html
Quote from Paul Prescod:
Sessions are irrelevant.
There should be no need for a client to "login" or "start a connection." HTTP authentication is done
automatically on every message. Client applications are consumers of
resources, not services. Therefore there is nothing to log in to!
Let's say that you are booking a flight on a REST web service. You
don't create a new "session" connection to the service. Rather you ask
the "itinerary creator object" to create you a new itinerary. You can
start filling in the blanks but then get some totally different
component elsewhere on the web to fill in some other blanks. There is
no session so there is no problem of migrating session state between
clients. There is also no issue of "session affinity" in the server
(though there are still load balancing issues to continue).

<machineKey decryptionKey="AutoGenerate"... being ignored by IIS. Won't invalidate previous session's cookies

(See question below for more context):
Are there any situations in which
<machineKey
validationKey="AutoGenerate,IsolateApps"
decryptionKey="AutoGenerate,IsolateApps"/>
in web.config would fail to AutoGenerate a new machineKey on App Pool recycle? This is the behavior I'm seeing...
I'm using standard ASP.NET FormsAuthentication in an MVC app. If I log a user in using FormsAuthentication.GetAuthCookie and don't use a persistent cookie (relying on the browser's session to remember my authorized state), I would expect recycling the IIS App Pool to invalidate the session's knowledge of this cookie...and thus logout all users who don't have persistent cookies.
This DOES happen on one of my IIS installs (XP), but on a different IIS configuration (Server 2K3) the FormsAuthentication cookie (under the standard name ".ASPXAUTH") remains valid and continues to authorize the user.
Does anyone know why this is happening or what configuration controls this behavior?
Obviously recycling the app pool has no control over whether or not the browser still sends the .ASPXAUTH cookie (as long as I haven't closed my browser and the cookie hasn't expired).
In the case of the IIS install that properly denies authentication after a recycle, I can see the incoming cookie in Request.Cookies during the Application_BeginRequest event...but once control moves to the next event available in Global.asax.cs (Application_AuthenticateRequest), the cookie has been removed from the Request.Cookies collection.
Why does this not happen for both IIS/ASP.NET configurations?
In case this isn't clear, a simpler way of forming the question is:
Why does HttpContext.Current.Request.Cookies[".ASPXAUTH"] change from {System.Web.HttpCookie} to null when I step, in a single request, from Application_BeginRequest to Application_AuthenticateRequest?
More debugging information:
If I attach the following code to Global.asax.cs's FormsAuthentication_OnAuthenticate event...
var cookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (cookie != null)
{
var val = cookie.Value;
try
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(val);
}
catch (Exception)
{
}
}
...then during a request before I recycle the IIS App Pool, no exception will be caught. After recycling the IIS App Pool, when the exact same .ASPXAUTH cookie is sent from the browser, a Cryptographic exception is caught ("Padding is invalid and cannot be removed.")
Why is this?
Our application is stateless (no session required), yet we had a situation where an app pool recycle caused invalidation of all machinekey-encrypted cookies on a server environment (above described issue). This was caused because the machinekey changes with every recycle, which should not be the case.
The AutoGenerate modifier specifies that ASP.NET generates a random key and stores it in the Local Security Authority (LSA)
https://msdn.microsoft.com/en-us/library/w8h3skw9%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
"Local Security Authority (LSA)" means the user assigned to app pool, see below for more details as this turned out to be the problem.
The issue lied in the fact that we are using a dedicated user account for running the application pool, and simply creating the user and then assigning it to the app pool did not seem to trigger the creation of the registry section where the machine key is then stored. You can verify this yourself by checking registry
HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/ProfileList (for getting the SID of the user you just created; if the user is not there, then this is already a bad sign)
HKU/[UserSIDFromBefore]/Software/Microsoft/ASP.NET/... (a machine key should be stored there)
The solution was to logon as that user once on the computer (normal Windows logon screen) so that the relevant registry sections are created. There might be quicker or more subtle ways to establish the registry sections though.
Internet Information Services (IIS) 7.0 (Windows Vista, Windows Server 2008) introduced application pool identity, a new isolation mechanism that helps provide increased security for servers that run ASP.NET applications. However, sites that are running under the application pool identity do not have access to the HKCU registry. This is where the ASP.NET runtime stores its auto-generated keys. The result is that ASP.NET cannot persist the auto-generated key when the application pool is reset. Therefore, every time w3wp.exe is reset, a new temporary key is generated.
Note This is not an issue in IIS 7.5 (Windows 7, Windows Server 2008 R2) and later versions. On these versions of IIS, ASP.NET can persist its auto-generated keys in a different location that survives application pool resets.
https://support.microsoft.com/en-us/help/2915218/resolving-view-state-message-authentication-code-mac-errors
Forms Authentication cookies have nothing to do with Session state.

Resources