48

I have the same web app working in three others servers. Anyone have any idea why is not working in the 4th server? See the error and stacktrace:

An operations error occurred.

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.DirectoryServices.DirectoryServicesCOMException: An operations error occurred.

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:

[DirectoryServicesCOMException (0x80072020): An operations error occurred. ] System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) +454 System.DirectoryServices.DirectoryEntry.Bind() +36 System.DirectoryServices.DirectoryEntry.get_AdsObject() +31 System.DirectoryServices.PropertyValueCollection.PopulateList() +22
System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName) +96
System.DirectoryServices.PropertyCollection.get_Item(String propertyName) +142 System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer() +1134 System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit() +37 System.DirectoryServices.AccountManagement.PrincipalContext.Initialize() +124 System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx() +31 System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable'1 identityType, String identityValue, DateTime refDate) +14
System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, String identityValue) +73
System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, String identityValue) +25
Infraero.TINE3.STTEnterprise.Web.Common.Seguranca.ServicoAutenticacao.EfetuarLogin(AcessoUsuario acessoUsuario, String senha) in D:\SVN\STT\trunk\4-0_CodigoFonte_Enterprise\4-4_SRC\Infraero.TINE3.STTEnterprise.Web\Common\Seguranca\ServicoAutenticacao.cs:34 Infraero.TINE3.STTEnterprise.Web.Controllers.LoginController.ValidarUsuarioAD(String matricula, String senha, AcessoUsuario acessoUsuario) in D:\SVN\STT\trunk\4-0_CodigoFonte_Enterprise\4-4_SRC\Infraero.TINE3.STTEnterprise.Web\Controllers\LoginController.cs:92 Infraero.TINE3.STTEnterprise.Web.Controllers.LoginController.ValidarUsuario(String matricula, String senha) in D:\SVN\STT\trunk\4-0_CodigoFonte_Enterprise\4-4_SRC\Infraero.TINE3.STTEnterprise.Web\Controllers\LoginController.cs:80 Infraero.TINE3.STTEnterprise.Web.Controllers.LoginController.Index(LoginViewModel loginViewModel) in D:\SVN\STT\trunk\4-0_CodigoFonte_Enterprise\4-4_SRC\Infraero.TINE3.STTEnterprise.Web\Controllers\LoginController.cs:54 lambda_method(Closure , ControllerBase , Object[] ) +108
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary'2 parameters) +208
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary'2 parameters) +27
System.Web.Mvc.<>c__DisplayClass15.b__12() +55 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func'1 continuation) +263
System.Web.Mvc.<>c__DisplayClass17.b__14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList'1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +191
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
System.Web.Mvc.Controller.ExecuteCore() +116
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
System.Web.Mvc.<>c__DisplayClassb.b__5() +37
System.Web.Mvc.Async.<>c__DisplayClass1.b__0() +21
System.Web.Mvc.Async.<>c__DisplayClass8'1.b__7(IAsyncResult _) +12 System.Web.Mvc.Async.WrappedAsyncResult'1.End() +62 System.Web.Mvc.<>c__DisplayClasse.b__d() +50
System.Web.Mvc.SecurityUtil.b__0(Action f) +7 System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8963149 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

EfetuarLogin Method:

public static bool EfetuarLogin(User user, string password)
{
    bool isValid = false;

    if (user != null)
    {
        PrincipalContext context = new PrincipalContext(ContextType.Domain);

        using (context)
        {
            isValid = context.ValidateCredentials(user.Login, password);

            if (isValid)
            {
                UserPrincipal userAD = UserPrincipal.FindByIdentity(context, user.Login);

                MySession.CurrentUser = new MyUserSession()
                {
                    Id = user.Id,
                    ProfileId = user.ProfileId ,
                    Login = user.Login ,
                    Name = userAD.Name
                };
            }
        }
    }

    return isValid;
}
Vinicius Ottoni
  • 4,631
  • 9
  • 42
  • 64
  • Are there **any** differences in permissions on that machine? It is attempting to find a user account and for one reason or another it cant. Are there any InnerExceptions? Those should have information from further down the stack trace. – CodeWarrior Dec 03 '12 at 17:02
  • What kind of permissions you mean? All apps run in the same intranet and I'm trying to login with same user. There isn't InnerExceptions. – Vinicius Ottoni Dec 03 '12 at 17:23
  • Well by permissions, I mean, is the web application running on the same account on all machines? EfetuarLogin looks like it is the last User Code that leads up to this exception. Have you tried stepping through the code from there? I assume that this is processing a login attempt against ActiveDirectory. Could you post the code in the EfetuarLogin method? – CodeWarrior Dec 03 '12 at 17:40
  • possible duplicate of [Error on publishing: System.DirectoryServices.DirectoryServicesCOMException](http://stackoverflow.com/questions/9181435/error-on-publishing-system-directoryservices-directoryservicescomexception) – Hans Passant Dec 03 '12 at 20:41
  • 1
    Seeing as the OP is the poster of the accepted answer in that question, it is unlikely that he has not checked to see that his answer would fix the problem. – CodeWarrior Dec 04 '12 at 15:53

7 Answers7

71

I had exactly the same error and fixed it by changing the site's application pool to run under the Network Service.

In IIS:

  • Select your site's application pool
  • Select Advanced Settings on the right-hand side
  • On the Advanced Settings pop-up window, scroll down to the Process Model group
  • Change the first option called Identity to NetworkService (mine was set to the default ApplicationPoolIdentity).

I hope this helps.

Neville
  • 1,080
  • 1
  • 12
  • 28
  • 3
    Thank you, you helped: http://stackoverflow.com/questions/19439873/cant-get-principalcontext-to-work-in-sharepoint-2010-with-claims-based-authenti/19554726#19554726 – billsecond Oct 24 '13 at 00:22
  • 2
    ApplicationPoolIdentity had been working for me and then spontaneously broke. I'm pretty sure the issue was this bug, which has a hotfix available: "This issue occurs because a flag is set in a global credential incorrectly after the computer password is changed. Therefore, authentication fails after the IIS service is restarted" (http://support.microsoft.com/kb/2545850) – Loren Paulsen Aug 13 '14 at 16:42
  • 2
    This did work for me but is apparently not the preferred solution per http://www.iis.net/learn/manage/configuring-security/application-pool-identities. I ended up doing the hotfix as noted in the answer below. – Tony L. Jan 30 '15 at 16:34
  • Thanks Tony for the additional info. In my case I'm working in a domain environment where the network service actually has some benefits and could be a better option depending on your setup. – Neville Feb 02 '15 at 09:18
  • I've had an app in prod for 2 years now and suddenly I get this error. Changing from ApplicationPoolIdentity to NetworkService didn't help. Something weird going on. – Christopher Painter Feb 23 '17 at 13:56
36

I know this topic is old but just for future people who will be looking for this issue Just use this method to execute the code with Elevate privileges

using (HostingEnvironment.Impersonate()) {
    // This code runs as the application pool user
    }
Matt67
  • 361
  • 3
  • 2
  • I've been pulling my hair out over a similar error on our server. I can't thank you enough for posting this even if it is an old thread. Your simple solution works perfect, thank you!! – ovaltein Jun 19 '13 at 15:27
  • A more detailed explanation of why this works can be found in [this answer](http://stackoverflow.com/a/19036826/601758) – PyreneesJim May 09 '16 at 12:56
8

There isn't an InnerException in this case, it's just wrapping a COM error.

Almost certainly it's because your Application Pool identity does not have permission to access Active Directory.

SliverNinja - MSFT
  • 31,051
  • 11
  • 110
  • 173
Joe
  • 122,218
  • 32
  • 205
  • 338
  • I put now a log to know which user is trying to login AD, and is a user that is registered in AD. – Vinicius Ottoni Dec 04 '12 at 13:58
  • Does the account have permission to query the domain controller? As I recall I had to ask for a service account to be given permission of some kind the last time I encountered this. – CodeWarrior Dec 04 '12 at 15:52
  • This was the exactly the issue for me - impersonating a user that does have access (*via p/invoke*) worked out fine to avoid using elevated Network Service credentials for the entire application. – SliverNinja - MSFT Sep 26 '14 at 13:31
6

In my case, switching from ApplicationPoolItentity to NetworkService in the app pool did work BUT it not preferred "because services running as Network Service can tamper with other services that run under the same identity" per the following link: (http://www.iis.net/learn/manage/configuring-security/application-pool-identities).

I ran the hotfix (KB2545850) on the server and rebooted per this answer:(DirectoryServicesCOMException 80072020 From IIS 7.5 Site Running Under ApplicationPoolIdentity)

It appears to be working well now.

Background on my task: Upgrading apps from .net framework 2.0 on Server 2003 to .net framework 4.0 on Server 2008 R2.

Community
  • 1
  • 1
Tony L.
  • 17,638
  • 8
  • 69
  • 66
4

My Experience was little different with this Error. I had to move on-premise application to Azure, where the LDAP call was happening from on-premise, but not from Azure even after opening the required firewall.

I tried all solution mentioned above, but none of them was helpful. Network service was already selected on Azure VM.

After lot of hit and trial and research. I fixed it.

Solution: On-Premise server was having permission to access LDAP and did not required any UserName and Password. But on Azure, you need to specifically make LDAP call with username and Password. Below is the code which helped.

 var directoryEntry= new DirectoryEntry(adspath, Username, Password)
Umair Akbar
  • 578
  • 5
  • 11
3

1 - Change application pool to run under the Network Service.
2 - Click on the Authentication and disable ASP.Net impersonation.

nPcomp
  • 8,637
  • 2
  • 54
  • 49
-1

So if you place a breakpoint on the line:

UserPrincipal userAD = UserPrincipal.FindByIdentity(context, user.Login);

and step through it, it generates the above exception which does not have any InnerExceptions?

According to the stack trace, that line is the beginning of the problem. The returned exception should have at least some other information in it as to why it was thrown.

InnerException Concatenator

The following method takes the top level exception and returns a tab and linebreak formatted breakdown of the inner exceptions as a string.

    private static string InnerExceptionConcatenator(Exception ex, int tabTracker = 0)
    {
        string retVal = "";
        if (ex.InnerException != null)
        {
            tabTracker ++;
            retVal = string.Format( "{0}\r\n{1}{2}", ex.Message, new String('\t', tabTracker), InnerExceptionConcatenator(ex.InnerException));
        }
        else
        {
            retVal = ex.Message;
        }
        return retVal;
    }

You can call it thusly:

try
{

}
catch(ex Exception)
{
    var exceptionString = InnerExceptionConcatenator(ex);
    var path = @"c:\temp\exception.txt";
    if (!File.Exists(path)) 
    {
        using (StreamWriter sw = File.CreateText(path)) 
        {
            sw.WriteLine(exceptionString);
        }   
    }
    else
    {
        using (StreamWriter sw = File.AppendText(path)) 
        {
            sw.WriteLine(exceptionString);
        }
    }
}
CodeWarrior
  • 7,388
  • 7
  • 51
  • 78
  • 1
    In the test machine, where I can use the breakpoint, it works. But in the prod machine, I cannot, and I get the error. – Vinicius Ottoni Dec 03 '12 at 19:20
  • I had a case similar to this a year ago or so. I ended up putting a Try...Catch around the offending code, and outputting the whole Exception chain to a file. I will post my ExceptionOutputBuilder in a minute. Once you can get the inner exception (which there really must be one there), you can then troubleshoot the real problem. – CodeWarrior Dec 03 '12 at 19:35
  • 3
    `Exception.ToString()` generates a string that includes details of any inner exception; no need for this home-made solution. – Joe Dec 03 '12 at 19:49
  • Perhaps I only created that to make it nice looking (readable). If so, I had completely forgotten about that. Regardless, I am almost positive that there is an inner exception missing, which should provide some key information. Having worked with DirectoryServices previously, I found the exceptions to be pretty verbose and useful. – CodeWarrior Dec 03 '12 at 20:35
  • There is not a InnerException, only the exception above. – Vinicius Ottoni Dec 04 '12 at 13:56