Search code examples
c#asp.netiissecurityexception

Exception Details: System.Security.SecurityException: A specified logon session does not exist. It may already have been terminated


I deployed a test web app to virtual Windows server 2008 std. IIS does not have certificates features assigned to this app nor to any apps deployed on this server so none of the solutions I've found relate to my issue. All other apps on same server work fine which leads me to conclusion the problem must be with the code I am using to authenticate in the global.asax file.

I've checked gpedit.msc and Network access: Do not allow storage of credentials is already disabled. This posting is closest to my issue that I've been able to find but no solution was accepted. I've checked MMC but there is nothing in it but an empty Console Root node so there is nothing to delete and reinstall as some have suggested here and here. I cannot access blog sites from work-there were some that sounded promising but I can't read them. I added Full Trust to web.config it made no difference and noted that .NET Trust Levels in IIS were set at Full (internal) already.

The complete error message is:

System.Security.SecurityException: A specified logon session does not exist. It may already have been terminated.

   at System.Security.Principal.WindowsIdentity.KerbS4ULogon(String upn)
   at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName, String type)
   at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName)
   at EPRSystem.Global.IsInADGroup(String user, String group)
   at EPRSystem.Global.Application_AuthenticateRequest(Object sender, EventArgs e)
The Zone of the assembly that failed was:
MyComputer

Any ideas for me?

Here's my global code:

    public Boolean IsAdmin;
    public Boolean IsManager;
    public Boolean IsDeveloper;

    string UserName;

   public String GetUserName()
   {
        WindowsIdentity wiCurrentUser;
        wiCurrentUser = WindowsIdentity.GetCurrent();

        String strUserName = wiCurrentUser.Name;

        String[] strParts = strUserName.Split('\\');
        strUserName = strParts[1];  

        return strUserName; 
   }

   public Boolean IsInADGroup(string user, string group)
   {
       using (var identity = new WindowsIdentity(user))
       {
           var principal = new WindowsPrincipal(identity);

           return principal.IsInRole(group);
       }
   }   


    protected void Session_Start(object sender, EventArgs e)
    {
        //Write method: Get current user's username

        UserName = HttpContext.Current.User.Identity.Name; //get AD name of user

        HttpContext.Current.Session["UserName"] = GetUserName();

        HttpContext.Current.Session["IsAdmin"] = IsInADGroup(HttpContext.Current.Session["UserName"].ToString(), "group1");

        HttpContext.Current.Session["IsManager"] = IsInADGroup(HttpContext.Current.Session["UserName"].ToString(), "group2");

        HttpContext.Current.Session["IsDeveloper"] = IsInADGroup(HttpContext.Current.Session["UserName"].ToString(), "group3");  
    }


    protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        //Write method: Identity/Authenticate current user

        DAL.ErrorLog oErrorLog = new DAL.ErrorLog();
        try
        {
            String strUser = GetUserName();

            IsAdmin = IsInADGroup(strUser, "group1");

            IsManager = IsInADGroup(strUser, "group2");

            IsDeveloper = IsInADGroup(strUser, "group3");
        }
        catch (System.Security.SecurityException ex)
        {
            oErrorLog.WriteErrorLog(ex.ToString());
        }

    }  

Solution

  • I read this article by Shawn Farkas, focusing on his comment "1.Determine what permissions are being demanded that are causing your application to throw, and try to modify your application to not require these permissions any more. The SecurityException that is being thrown should tell you which demand failed.

    I removed the authorization code from Global.asax entirely, moving it to Default.aspx.cs. I replaced IsInADGroup(x,y) method which is where the error originated, with a mixture of code suggested by marc_s in a new method called CheckGroupMembership(). I instantiated a global array variable groupName[] containing the three AD groups I wanted to check membership for and ultimately these values IsMember[]are passed to Session variable so they can be used on another page. The heart of the solution is this method: requires namespace System.DirectoryServices.AccountManagement

    public void CheckGroupMembership()
        {
            // set up domain context
            PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "XXX");
    
            // find a user
            UserPrincipal user = UserPrincipal.FindByIdentity(ctx, GetUserName());
    
            for (int i = 0; i < 3; i++)
            {
                // find the group in question
                GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, groupName[i]);
    
                if (user != null)
                {
                    // check if user is member of that group
                    if (user.IsMemberOf(group))
                    { 
                        IsMember[i] = true;  
                    }
                    else
                    {
                        IsMember[i] = false;
                    }
                }
            }
        }