Windows Authentication in IIS 7.5 Fails with Trust Relationship Exception - asp.net

I have an ASP.Net 2.0 application that uses integrated Windows Authentication to authenticate/authorize users. The application works fine on Windows XP/IIS 5.1, Windows Server 2008/IIS 7, and Windows Vista/IIS 7. When I try to run this application on Windows 7/IIS 7.5, I get the following exception: The trust relationship between this workstation and the primary domain failed.
The stack trace is as follows:
[SystemException: The trust relationship between this workstation and the primary domain failed.
]
System.Security.Principal.NTAccount.TranslateToSids(IdentityReferenceCollection sourceAccounts, Boolean& someFailed) +1085
System.Security.Principal.NTAccount.Translate(IdentityReferenceCollection sourceAccounts, Type targetType, Boolean forceSuccess) +46
System.Security.Principal.WindowsPrincipal.IsInRole(String role) +128
System.Web.Configuration.AuthorizationRule.IsTheUserInAnyRole(StringCollection roles, IPrincipal principal) +229
System.Web.Configuration.AuthorizationRule.IsUserAllowed(IPrincipal user, String verb) +354
System.Web.Configuration.AuthorizationRuleCollection.IsUserAllowed(IPrincipal user, String verb) +245
System.Web.Security.UrlAuthorizationModule.OnEnter(Object source, EventArgs eventArgs) +11153304
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +171
The web.config file contains the following information related to authentication/authorization:
<authentication mode="Windows" />
<authorization&gt
<!--Deny anonymous users--&gt
<deny users="?"/&gt
<allow roles="domain\GroupWithAccess"/&gt
<deny users="*"/&gt
</authorization&gt
Most of the results I found when researching this error state that the problem is related to a broken computer account in the domain and list the solution as re-joining the domain. I've done this but the error still appears. "Normal" domain operations work fine (accessing UNC shares, logging in, etc.).
This application runs in the Classic .Net AppPool for compatibility reasons. I tried changing the identity of the AppPool to "NetworkService" but the error still persists.
Any help is greatly appreciated.

I finally found an answer to this after experiencing the same problem on Windows Server 2008 R2. From this article:
Disable the following policies on the Windows 2008 R2 server, run gpupdate /force and restart the server.
"Computer Configuration\Windows Setting\Security Settings\Local Policies\Security Option"
Domain Member: Digitally encrypt or sign secure channel data (always)
Domain Member: Digitally encrypt secure channel data (When possible)
Domain Member: Digitally sign secure channel data (When possible)
I can confirm that this fixed the problem on Windows 7 as well.

I'm adding this for future reference:
"Error 1789 when you use the LookupAccountName function on a computer that is running Windows 7 or Windows Server 2008 R2"
http://support.microsoft.com/kb/976494
That might be a solution to the problem as well.

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

Key not valid for use in specified state after IISRESET

I have created a Custom STS Login Application and logging in/out functionalities were working fine. But if i login as some user and do IISRESET and then reloaded the page the below error is spitted. (But as expected it works fine after I cleared the cookies and logged in again :) )
Apppool user for STS Application is "A" and he has never windows logged into the server machine, where STS Application is deployed(he is in administrators group and has access to encryption certificates).
I tried to login once as "A" in to the server(Windows Login) and after that all of a sudden this issue is solved.
Can anyone tell why was it not working after IISRESET and working after windows logging in once?
Server Error in '/’ Application.
Key not valid for use in specified state.
[CryptographicException: Key not valid for use in specified state.]
System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope)
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded)
[InvalidOperationException: 1D1073: A CryptographicException occurred when attempting to decrypt the cookie using the ProtectedData API (see inner exception for details).
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +433
Microsoft.IdentityModel .Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte] cookie, Boolean outbound) +189
Microsoft. IdentityModel .Tokens. SessionSecurityTokenHandler. ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver) +894
Microsoft. IdentityModel .Tokens. SessionSecurityTokenHandler. ReadToken(Byte]] token, SecurityTokenResolver tokenResolver) +118
Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenrrocCookie(Byte] sessionCookie) +363
Microsoft.IdentityModel.Web. SessionAuthenticationModule.TryReadSessionTokenFroaCookie(SessionSecurityToken& sessionToken) +124
Microsoft. IdentityModel .Web. SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs) +61
System.Web.SyncEventExecutionstep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System. Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +270
Version Information: Microsoft .NET Framework Version:4.D.30319; ASP NET Version:4.O.30319.272
If you're running with the default WIF config, the keys used to secure the session tokens are handled through DPAPI and are stored in the user profile. These keys change on iisreset unless you configure IIS with "Load User Profile" as true.
If you're running on .NET 4.5 the easiest approach would be to configure machineKeys for your application and use the new MachineKeySessionSecurityTokenHandler, as documented in Wif and Web Farms.

How to restrict access to static files in IIS 7.5 Classic mode

I need to restrict access to static HTML files in several ASP.NET applications. As those applications implement their own authentication mechanisms it looks like I need just to get those files to go through the ASP.NET request processing pipeline instead of the "standard" IIS static content handling. Some of applications are relatively modern ASP.NET MVC applications and use integrated pipeline on IIS 7.5 and it looks like it is not a big deal to do what I need for them. But others are legacy ASP.NET web sites working on the classic pipeline mode (IIS 7.5) and at the moment it is not possible to move them to the integrated pipeline for certain reasons.
UPD: The issue is that applications contain some static files (help pages) and unauthorized user can see them if they type the direct URL. And my task is to make the application show the login page in such a case.
Adding a handler into Web.config:
<add name="StaticHTMLHandler" path="*.htm*" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
caused me just to get this exception:
[HttpException (0x80004005): Failed to Execute URL]
System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.BeginExecuteUrl(String url, String method, String childHeaders, Boolean sendHeaders, Boolean addUserIndo, IntPtr token, String name, String authType, Byte[] entity, AsyncCallback cb, Object state) +4136452
System.Web.HttpResponse.BeginExecuteUrlForEntireResponse(String pathOverride, NameValueCollection requestHeaders, AsyncCallback cb, Object state) +653
System.Web.DefaultHttpHandler.BeginProcessRequest(HttpContext context, AsyncCallback callback, Object state) +279
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +12551795
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288
So what am I doing wrong? Can anybody point me to the right way?
I've never tried your methods, but I also have some FW 1.1, classic asp. and modern web apps mixed on my web servers. What I do is create a seperate app pool per framework. I run 1.1 on 1.1 classic mode app pool that I create, and run modern apps on another app pool: integrated fw 4.0. The classic asp stuff is out of scope for this question. Each app pool is it's own process, so there's no real downside to using more app pools, 1 app pool per application is a perfectly acceptable security policy for example.
So finally no practical way was found for bringing authentication to static files with the classic pipeline mode. Finally we have decided to update the old legacy platform and make it work with the integrated pipeline mode.

asp.net windows authentication to sql server

I can not seem to get sql server to recognize my credentials.
Asp.net recognizes me when I login but when I execute a sql command I get a login failed message.
The IIS server and SQL server are on different machines.
There are other applications the IIS server which are able to authenticate to the sql server. I believe the Active Directory settings are correct. I am investigating what I am doing differently.
I must be missing something.
I check the IIS settings
The web config is set to impersonate.
Below is the relevant information. If anyone has any idea as to what I missed or am doing wrong I would appreciate some help.
IIS Settings:
'Integrated Windows authentication' is checked
'Enable anonymous access" is not checked
Web Config
<authentication mode="Windows"/>
<identity impersonate="true"/>
<authorization>
<deny users="?" />
</authorization>
Page_Load Code:
Dim winId As IIdentity = HttpContext.Current.User.Identity
TextBoxMessage.Text = winId.Name + Environment.NewLine
Dim cnn As SqlClient.SqlConnection
Try
Dim sql As String = "*****"
cnn = New SqlClient.SqlConnection("Data Source=*****;Initial Catalog=****;Integrated Security=True")
cnn.Open()
Dim cmd As New SqlClient.SqlCommand(sql, cnn)
cmd.ExecuteNonQuery()
cnn.Close()
Catch ex As Exception
TextBoxMessage.Text += ex.Message
cnn.Close()
End Try
Output:
Domain\UserName
Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'.
This is key = The IIS server and SQL server are on different machines. You're facing the classic double hop issue. Think of it in this way:
You access the web application under your credentials
IIS in this case has to present who you say you are to the SQL Server
IIS says, "Why hello SQL Server, I'm passing on Tony's kerberos creds, they are legit"
SQL Server says, "Hmmm, IIS I'm not sure I trust you, I need proof that you are trusted to present these credentials to me".
Thus once you enable delegation as mentioned by Remus, your SQL Server will trust the credentials your IIS server is presenting on your behalf.
In terms of security, under delegation, it would be wise to choose:
Trust this computer for delegation for specified services only | Use Kerberos only | and then underneath the "Services to which this account can present delegated credentials" make sure you explicitly set only the server/port you need.
You also need to enable constrained delegation:
Enabling Constrained Delegation
How To: Use Protocol Transition and Constrained Delegation in ASP.NET 2.0
Windows Server 2003 Constrained Delegation (IIS 6.0)
Are your ISS server and SQL Server running on the same machine?
If not, Active Directory has to be configured to allow your IIS server to impersonate your accout towards the SQL Server. See How To: Use Protocol Transition and Constrained Delegation in ASP.NET 2.0.
Long story short: IIS server should have "trusted for delegation" checkbox checked in Active Directory.
You need to set you credentials in Application Pool.
- Open IIS
- Select Application Pools
- Enter the name, select .Net framework version and click OK
- Select the new added application pool and click on Advanced Settings..
- In the Process Model section click on Identity - choose custom account and enter the AD username, password, confirm password and click OK
- Select your application and in the Basic settings choose your application pool just created.
Hope this helps

EventLog permission failing in ASP.Net on Win7

I have an ASP.Net app .net 3.5 SP1, running in Win7 . During the login process, something within the ASP.Net login control is causing a write to the security log (this sounds acceptable to me) in the event log. The problem is that it seems the app doesn't have permission to do this. There error is:
Description: The application attempted to perform an operation not allowed by the security policy. To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.
Exception Details: System.Security.SecurityException: Request for the permission of type 'System.Diagnostics.EventLogPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
The stack trace doesn't show a single line of code from my application, its all in the framework.
The last 5 lines are:
System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet) +0
System.Security.CodeAccessPermission.Demand() +61
System.Diagnostics.EventLog..ctor(String logName, String machineName, String source) +125
System.Diagnostics.EventLog..ctor() +24
System.Diagnostics.EventLog.WriteEntry(String source, String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData) +52
This same app works fine on XP SP2. I've hunted around and can't find how to give permissions. I've tried running hte app pool as LocalSystem and ApplicationPoolIdentity.
Whats the easiest way to get this running? Its my local dev machine and I don't care if I open up security holes, as long as I don't have to modify code (ie I need the solution to be an INETMGR change or web.config or some local permissions, etc).
Thanks!
This link appears to discuss the issue you are having.
I am not sure about the differences between the default CAS (code access security) on XP vs. win 7, however the assembly writing to the event log (and all calling assemblies) must have EventLogPermission.
You can add the AllowPartiallyTrustedCallers attribute or sign the assembly with a strong name key.
If you are writing to the default Application log you need to provide permisson to the LocalSystem before using it inside app pool.
Open RegistryEdit and goto
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\services\eventlog\Application
RightClick over the Applicatuion and click permissions
If the user(LOCALSYSTEM) is not present in the list then Add and Allow full Control

Resources