Heute habe ich bei einem Kunden den Fall gehabt, dass trotz dass Windows-Anmeldung im IIS 7 konfiguriert war, und im korrekt angezeigten Browser-Anmelde-Dialog die richtigen Anmeldedaten eingegeben wurden, keine Anmeldung möglich war.
Vielmehr ist 3 mal der Anmelde-Dialog erschienen und danach kam die HTTP-Fehlermeldung 401.2 (oder war’s 401.1?).
Die Lösung wurde dann von einem wirklich kompetenten Administrator beim Kunden geliefert: Die Authentifizierungsprovider waren in der Reihenfolge „Negotiate“ und dann „NTLM“.
Als wir NTLM ganz nach oben geschoben haben, ging alles.
Gestern hatte ein Kollege beim Aufsetzen einer Website ASP.NET MVC 4 auf einem IIS unter Windows Server 2008 R2 eine Fehlermeldung:
[CryptographicException: Unbekannter Fehler -1073741766.]
System.Security.Cryptography.ProtectedData.Protect(Byte[] userData, Byte[] optionalEntropy, DataProtectionScope scope) +504
Oracle.ManagedDataAccess.Client.ConnectionString.Secure() +493
OracleInternal.ConnectionPool.PoolManager`3.Initialize(ConnectionString cs) +1760
OracleInternal.ConnectionPool.OraclePoolManager.Initialize(ConnectionString cs) +21
OracleInternal.ConnectionPool.OracleConnectionDispenser`3.GetPM(ConnectionString cs, PM conPM, ConnectionString pmCS, Byte[] securedPassword, Byte[] securedProxyPassword, Boolean& bAuthenticated, Boolean& newPM) +296
OracleInternal.ConnectionPool.OracleConnectionDispenser`3.Get(ConnectionString cs, PM conPM, ConnectionString pmCS, Byte[] securedPassword, Byte[] securedProxyPassword) +1576
Oracle.ManagedDataAccess.Client.OracleConnection.Open() +3756
OracleInternal.EntityFramework.EFOracleProviderServices.GetDbProviderManifestToken(DbConnection connection) +274
System.Data.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection) +91
[ProviderIncompatibleException: Der Anbieter hat keine ProviderManifestToken-Zeichenfolge zurückgegeben.]
System.Data.Common.DbProviderServices.GetProviderManifestToken(DbConnection connection) +10947809
System.Data.Entity.ModelConfiguration.Utilities.DbProviderServicesExtensions.GetProviderManifestTokenChecked(DbProviderServices providerServices, DbConnection connection) +48
[ProviderIncompatibleException: An error occurred while getting provider information from the database. This can be caused by Entity Framework using an incorrect connection string. Check the inner exceptions for details and ensure that the connection string is correct.]
System.Data.Entity.ModelConfiguration.Utilities.DbProviderServicesExtensions.GetProviderManifestTokenChecked(DbProviderServices providerServices, DbConnection connection) +242
System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection) +82
System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext) +88
System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input) +248
System.Data.Entity.Internal.LazyInternalContext.InitializeContext() +524
System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +26
System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() +71
System.Data.Entity.Internal.Linq.InternalSet`1.GetEnumerator() +21
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +446
System.Linq.Enumerable.ToList(IEnumerable`1 source) +80
Zunächst war es eine Herausforderung, statt den „normalen“ Oracle.DataAccess-Klassen die Oracle.ManagedDataAccess-Klassen zum Laufen zu bringen. Hier haben uns zwei Artikel geholfen:
„Oracle Managed ODP.NET“ – Weblog-Artikel eines Inders zum Thema Konfiguration via Web.config.
A text editor like Notepad to create a batch script file.
the Task Scheduler to make the batch script run every n Minutes (e.g. every 10 Minutes)
The batch file I created for one of my own web servers looks like:
@REM ==============================================
@REM Automatically restart IIS if website is not available.
@REM (Checks for a sub string in a page of the website).
@REM
@REM Created 2011-10-28, Uwe Keim uk@zeta.li
@REM ==============================================
@REM Remove any existing previous downloads.
del d:\scripts\index.html
@REM Change drive and folder so that WGET stored in a
@REM well-defined location.
D:
cd d:\scripts
@REM Download file.
D:\scripts\wget.exe ^
--timeout=30 ^
--tries=1 ^
http://www.my-server.com/index.html
@REM Search for the term in the previously downloaded file.
find /I /C "Some String On Website" d:\scripts\index.html
@REM Restart IIS if string is not found.
IF ERRORLEVEL 1 iisreset /RESTART /TIMEOUT:120 /REBOOTONERROR
Please note the following:
WGET downloads the URL to a file with the same file name („index.html“ in my above example)
The scheduled task must be created to run with an administrative user.
The scheduled task must have the „Run with highest privileges“ checkbox set, because IISRESET only runs with administrative privileges.
Über vier Manntage hat mich insgesamt das folgende (in meinen Augen falsche) Verhalten von ASP.NET gekostet.
Beschreibung
Eine ASP.NET 2.0-Webanwendung läuft in der Testumgebung ganz normal und auch im Echtbetrieb.
Zu nicht-vorhersehbaren Zeiten „hängt“ die Anwendung auf einmal. D.h. die Anwendung reagiert für den Benutzer einfach nicht und der Browser lädt ewig.
Wenn ich dann den entsprechenden „w3wp.exe“ kille (ich habe extra einen AppPool nur für die eine Webanwendung gemacht), dann wird sofort automatisch ein neuer w3wp.exe gestartet und die Anwendung läuft wieder normal.
Ursache
Ein Aufruf von Debug.Assert in einer von der Webanwendung verwendeten DLL hat den Prozess zum Hängen gebracht.
Debug.Assert direkt in einer
Webanwendung ausgeführt hält den „w3wp.exe“ nicht an, sondern wird
schlicht ignoriert.
Debug.Assert indirekt
in einer DLL, die von der Webanwendung verwendet wird, hält den
w3wp.exe an und kann nur durch killen des „w3wp.exe“ beendet werden.
Lösung
Als schnellen Workaround habe ich jetzt alle Debug.Assert-Aufrufe in der DLL auskommentiert. Natürlich könnt Ihr auch schlicht alles im Release-Modus kompilieren, das ist aber in meinem Fall nicht nötig gewesen (keine Performance-Verbesserungen).