Cannot generate SSPI context exception after publishing mvc application to web server - asp.net

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!!

Related

Key not valid for use in specified state. After IIS Reset

I tried this:
runas /user: domain\user cmd with no luck
This seems to only occur now when IIS is reset and I try to resume my browsing session. So I am logged into the application, I reset IIS on the server, refresh the page and see the error.
I am building an application in .NET 4.0 MVC with a Secure Token Service that is using WIF 4.0. Everything works as expected, except this case. I even tried to use a custom error page, but the error is happening there as well. Because of that, I can't get the custom page to show either. Also, This is using a certificate that is located on both load balanced servers. This happens in my dev environment whihc consists of only one server (app, wfe, db operated there)
One thing I noticed is that if I switch my IIS APP Pool user back to Network Service account it doesn't throw the error any more. We have some restrictions (mostly network related) in the application that we need to use an account in our AD for the app pool sections
Anybody have any experience with this issue?
Key not valid for use in specified state.
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details:
System.Security.Cryptography.CryptographicException: Key not valid for
use in specified state.
Source Error:
An unhandled exception was generated during the execution of the
current web request. Information regarding the origin and location of
the exception can be identified using the exception stack trace below.
Stack Trace:
[CryptographicException: Key not valid for use in specified state. ]
System.Security.Cryptography.ProtectedData.Unprotect(Byte[]
encryptedData, Byte[] optionalEntropy, DataProtectionScope scope) +428
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[]
encoded) +54
[InvalidOperationException: ID1073: A CryptographicException occurred
when attempting to decrypt the cookie using the ProtectedData API (see
inner exception for details). If you are using IIS 7.5, this could be
due to the loadUserProfile setting on the Application Pool being set
to false. ]
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[]
encoded) +146
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[]
cookie, Boolean outbound) +113
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader
reader, SecurityTokenResolver tokenResolver) +647
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[]
token, SecurityTokenResolver tokenResolver) +105
Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[]
sessionCookie) +262
Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken&
sessionToken) +76
Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object
sender, EventArgs eventArgs) +53
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
+148 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
This issue is related to session cookies.
WIF protects session cookies using Data Protection API (DPAPI) by default, and the DPAPI is closely related to machine keys.
If the keys used to encrypt the session cookies change, it throws this exception.
It could be also related to your app hosting infrastructure.
if your app is running in an Network Load Balancer (NLB) environment
if you change the app pool settings (e.g., change the pool’s user)
More details about this scenario on the MSDN blog entry:
WIF 1.0 – ID1073 A CryptographicException occurred when attempting to decrypt the cookie using the ProtectedData API Archive.Today Shortlink
Todd Foust (October 29, 2012)
So, if your app runs in NLB environment, you could :
Configure your load balancer to use sticky sessions. This means that your user will be directed to the same server during the session duration. (I’m not very fond of that one)
Use a certificate to encrypt the session cookies
set all web.config files to use the same machine key in system.web
If you are not running the app in a NLB env, you could try:
set the machinekey in your web.config to use a pre-defined value instead of auto-generated values
Regarding auto-generated machinekey setting, please see:
How unique is your machine key?Archive.Today Shortlink

ASP.NET Web Service call failing after changing consuming Site SSL certificate

I'm running into a very weird scenario, have tried a lot of solutions and also tried searching for people having similar issues but couldn't find anything.
I have a webforms ASP.NET application for which the SSL certificate expired a couple of months ago, and we just received the renewed certificate. It was a new certificate instead of a renewal one, but issued to the same URL/SANs. It's also an internal certificate, not externally issued.
After installing the new SSL certificate in our production environment, an internal web service (asmx reference) call that we are making (to a java web service) is failing, complaining about no parameters being sent to the web service. This only happens if I browse through the SSL enabled version of the site, and only in production. The site with SSL works correctly in our dev/stage environments. Prod also works but only if I don't browse through HTTPS.
I cannot paste all the technical exception details, as it's a work related thing, but any help/guidance is appreciated.
System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Web.Services.Protocols.SoapHeaderException: Internal Server Error (Caught exception while handling request: java.lang.Exception: Last Name and/or First Name needs to be provided.)
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at OurProgram.com.Company.corp.amssvc.DirWs2.getEmployeeDataByName(String lastName, String firstName, String attData, String strDelim) in D:\somecodehere
For additional data, it is also not an IIS website on its own, it's hosted as an application under the Default Website, which is the one that has the SSL binding for the certificat.e
Has anyone experienced this?
TL;DR -- Disabled Anonymous Authentication.
Well, after 6 hours of fiddling with and comparing IIS and website configurations, the issue was that for some reason, Anonymous Authentication got enabled somehow after the site had been restarted for the new SSL certificate to kick in. Our application is an intranet one, so the web service takes the credentials of the logged in user. When Anon Auth got enabled somehow, it must have not been passing the correct credentials.
After disabling Anonymous Authentication, the site worked just fine. While it might seem a little related in hindsight, I would've expected a different error, anything other than the web service complaining that no parameters were sent.
Hope this helps someone.

WebDeploy - Not able to log on the user '.\WDeployConfigWriter'

I have problem with MsDeploy to publish my website to remote IIS from Visual Studio.
I encountered the following error:
Microsoft.Web.Delegation.DeploymentAuthorizationException: Not able to
log on the user '.\WDeployConfigWriter'. --->
System.Runtime.InteropServices.COMException: The user name or password
is incorrect. (Exception from HRESULT: 0x8007052E) --- End of inner
exception stack trace --- at
Microsoft.Web.Deployment.LogonUserHandle.LogonUser(String userName,
String domain, String password)
I tried to change WDeployConfigWriter's password in Local Users and Groups (lusrmgr.msc).
Then, I open Management Service Delegation.
I try to set credentials in edit rule for WDeployConfigWriter page and it's always fail with message "The spesified password is invalid. Type a new password".
I am working in Windows Server 2012.
Any help would be appreciate.
Thanks!
I had this too but with a slightly different detail
Not able to log on the user '.\WDeployConfigWriter'.
Logon failure: the specified account password has expired.
Full credit to this blog, the problem is that the Web Deploy installer creates users with expiring passwords that are used to elevate permissions during deployment. The fix is to:
Use server manager on the accounts WDeployAdmin and WDeployConfigWriter to
reset the password
check password never expires
uncheck user must change password next logon
Use IIS -> Management Service Delegation to reset the passwords for the rules where those accounts have been configured to elevate to a specific user
Fixed!
The easiest fix to this problem is:
Computer Management ->Local Users And Groups -> Users
Right click -> properties on WDeployAdmin
Uncheck "User must changed password at next logon
Check "Password never expires"
Do the same for WDeployConfigWriter
Done!
Similar to #fiat solution, but you don't really need to change the password.
Here are simple CMD commands:
WMIC USERACCOUNT WHERE "Name='WDeployConfigWriter'" SET PasswordExpires=FALSE
WMIC USERACCOUNT WHERE "Name='WDeployAdmin'" SET PasswordExpires=FALSE
It will set deploy users passwords to never expire
The WDeploy* users are not intended to be used directly as part of your deployment process. Instead, they are used to implicitly elevate permissions in order to perform specific tasks (modifying IIS for WDeployConfigWriter, and GAC installations among others for WDeployAdmin).
I'd recommend creating a non-admin user specifically for your website. You can find the instructions for doing so at Installing and Configuring Web Deploy on iis.net. If you continue to have problems with the WDeployConfigWriter user, you're probably best off uninstalling Web Deploy and starting again.
In my case, I got this error because either WDeployConfigWriter nor WDeployAdmin had been created during the installation of WebDeploy (3.6 / 4.) even if the installation ran through successfully.
Found out, that the servers rule for password complexity was more restricting that the generated one with the script in C:\Program Files\IIS\Microsoft Web Deploy V3\Scripts\AddDelegationRules.ps1 didn't meet the requirements.
So I edited GenerateStrongPassword() in the PowerShell file and run it.
The users then have been created successfully.
There is some cases where setting "Password never expires" not is enough. Reinstalling webdeploy will fix the issue.
The other way to fix this is to set new passwords for the users WDeployAdmin and WDeployConfigWriter.
User management
The next step is to set the new passwords in IIS > Management Service Delegation for those users.
Management Service Delegation
I had the same problem trying to changes the passwords in Management Service Delegation and it did not fix the problem. It turns out that I had to change the WDeployConfigWriter to a different user(ie Admin) change it back and then the password changes only took effect
I had the same problem with Visual Studio 2017 with a different error message. The solution is also uncheck (WDeployConfigWriter) "User must changed password at next logon"
Publish failed
Publish has encountered an error.
Publish failed due to build errors. Check the error list for more details.
A diagnostic log has been written to the following location:
"C:\User\MyUser\AppData\Local\Temp\tmpXXXX.tmp"
The content of the log file
06.04.2018 19:56:13
System.AggregateException: One or more errors occurred. ---> System.Exception: Publish failed due to build errors. Check the error list for more details.
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at Microsoft.VisualStudio.Web.Publish.PublishService.VsWebProjectPublish.<>c__DisplayClass40_0.<PublishAsync>b__2()
at System.Threading.Tasks.Task`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.ApplicationCapabilities.Publish.ViewModel.ProfileSelectorViewModel.<RunPublishTaskAsync>d__108.MoveNext()
---> (Inner Exception #0) System.Exception: Publish failed due to build errors. Check the error list for more details.<---
===================

<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.

ASP.NET Impersonation and SQL Server Trusted Connection Calls

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

Resources