[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

asp.net 4.0 windows auth

Posted on 2011-02-14
14
Medium Priority
?
811 Views
Last Modified: 2012-05-11
I'm trying to set up an intranet site using asp.net 4.0 and windows authentication. it works fine on my local xp workstation and directly on the windows 2008 web server. however, when i make a call from xp via ie 8 it does not work. The site is setup for windows auth. The site structure is:
references/ActiveDirectoryServices -- reference to ad object; this is a compiled dll
appcode/ clsAppCommon.cs
usercontrols/ greeting.ascx
default.aspx has the greeting usercontrol on it

I've attached the code files -- adservice, appcommon and greeting user control for help

Here is the error:

Exception Details: System.Runtime.InteropServices.COMException: An operations error occurred

Stack Trace:
[COMException (0x80072020): An operations error occurred.
]
   System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) +788
   System.DirectoryServices.DirectoryEntry.Bind() +44
   System.DirectoryServices.DirectoryEntry.get_AdsObject() +42
   System.DirectoryServices.PropertyValueCollection.PopulateList() +29
   System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName) +63
   System.DirectoryServices.PropertyCollection.get_Item(String propertyName) +163
   System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer() +521217
   System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit() +51
   System.DirectoryServices.AccountManagement.PrincipalContext.Initialize() +141
   System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx() +42
   System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate) +29
   System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, String identityValue) +95
   COMPANY.ActiveDirectoryServices.ADServices.getDisplayName(String dn, String un) +101
   COMPANY.Intranet.AppCommon..ctor() in C:\Projects\COMPANY.Intranet\COMPANY.Intranet\appcode\clsAppCommon.cs:108
   COMPANY.Intranet.SiteMaster..ctor() in C:\Projects\COMPANY.Intranet\COMPANY.Intranet\Site.Master.cs:16
   __ASP.FastObjectFactory_app_web_d5gy2voh.Create_ASP_site_master() +30
   System.Web.UI.MasterPage.CreateMaster(TemplateControl owner, HttpContext context, VirtualPath masterPageFile, IDictionary contentTemplateCollection) +370
   System.Web.UI.Page.ApplyMasterPage() +75
   System.Web.UI.Page.PerformPreInit() +210
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1700


What am I missing?


clsADServices.txt
clsAppCommon.txt
greeting.ascx.cs.txt
0
Comment
Question by:vicomin
  • 8
  • 6
14 Comments
 

Author Comment

by:vicomin
ID: 34888692
here is my web.config as well
<?xml version="1.0"?>
<configuration>
  <appSettings>
      <add key="CompanyName" value="Company" />
      <add key="ApplicationName" value="Intranet" />
</appSettings>
  <system.web>
      <identity impersonate="true"/>
      <authentication mode="Windows"/>
      <authorization>
          <deny users="?"/>
      </authorization>
      <trust level="Full" originUrl="" />
      <compilation debug="true" targetFramework="4.0" defaultLanguage="c#" />
      <customErrors mode="Off"/>
      <trace enabled="true" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="false"/>
  </system.web>
  <system.webServer>
     <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

Open in new window

0
 
LVL 51

Expert Comment

by:Ted Bouskill
ID: 34894293
Hmm, why are you converting strings into strings using ToString()?  For example, the GivenName is already a string and you convert it to a string a second time which is just overhead because it means another allocate/deallocate of the temporary string.

Also, the way you instantiate the AppCommon class means that every single page request is going to have to execute ALL the code, over and over and over again which is going to create a lot of unnecessary load.  I'd create one object per user and store it in the session array once per user.

I'd turn of the impersonate="true" because that isn't really necessary from what I can see in your app and the problem is that the account of the user shouldn't be used to query active directory because on my domains the user won't have that privilege (and shouldn't)

What you need to do is make sure the identity of the application pool has permissions to query active directory.  Usually I create a specific domain service account that has permissions to do execute LDAP queries without giving the user that right.
0
 

Author Comment

by:vicomin
ID: 34895925
okay so I'll drop the tostrings
not sure how to put the appcommon stuff into one object per user and store it in the session array
will turn off impersonation
will set up the app pool to use a domain service account to query ad

it is clear that i need more help
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:vicomin
ID: 34896964
drop the tostrings - done
turn off impersonation - done
set up the app pool to use a domain service account to query ad - done

so how do i place the appcommon stuff into one object per user and store it in the session array? would this be handled in the global asax?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;

namespace COMPANY.Intranet
{
    public class Global : System.Web.HttpApplication
    {
        AppCommon ac = new AppCommon();

        void Application_Start(object sender, EventArgs e)
        {
            // Code that runs on application startup
            //AppCommon ac = new AppCommon();

        }

        void Application_End(object sender, EventArgs e)
        {
            //  Code that runs on application shutdown

        }

        void Application_Error(object sender, EventArgs e)
        {
            // Code that runs when an unhandled error occurs

        }

        void Session_Start(object sender, EventArgs e)
        {
            // Code that runs when a new session is started
            
        }

        void Session_End(object sender, EventArgs e)
        {
            // Code that runs when a session ends. 
            // Note: The Session_End event is raised only when the sessionstate mode
            // is set to InProc in the Web.config file. If session mode is set to StateServer 
            // or SQLServer, the event is not raised.

        }

    }
}

Open in new window

0
 

Author Comment

by:vicomin
ID: 34900464
also, my code now runs but i'm not getting back a user name. It works great locally and directly on the web server but not through the browser.
clsAppcommon.cs        

#region Public Methods
        public string getUserFName(string dn, string un)
        {
            try
            {
                userFullName = COMPANYAD.getDisplayName(domainName, userName);
            }
            catch (Exception ex)
            {
                //handle error - this is a TBD item 
                ex.Message.ToString();
            }
            if (userFullName == "")
            {
                userFullName = "No Name";
            }
            return userFullName; //is now returning No Name and not the user full name like Tom Foolery
        }
        #endregion

Open in new window

0
 
LVL 51

Expert Comment

by:Ted Bouskill
ID: 34901831
Wait a minute I just notice a big error in your code I missed earlier.

Global.asax is used global which means this line AppCommon ac = new AppCommon();  is set once for the first user accessing the page is and isn't reset for each user!

Change your code to this:
        void Session_Start(object sender, EventArgs e)  
        {  
            Session["UserInfo"] = new  new AppCommon();  
        }  

In looking at your code I'm not sure why are aren't using static helper methods and avoiding creating an object.  If retrieving user details takes milliseconds why create memory pressure by storing objects in memory when you can simply retrieve the data?
0
 

Author Comment

by:vicomin
ID: 34912336
not sure how to use static helper methods. I'll give the code change above a try.
0
 
LVL 51

Expert Comment

by:Ted Bouskill
ID: 34913087
Here is a simple sample for a static class and function:

public static class Helpers
{
        public static string SessionIPAddress()
        {
            return System.Web.HttpContext.Current.Request.ServerVariables["remote_addr"];
        }
}

Cheers
0
 

Author Comment

by:vicomin
ID: 34964761
tedbilly, if i do:
void Session_Start(object sender, EventArgs e)
        {
            // Code that runs when a new session is started
            Session["UserInfo"] = new AppCommon();      
        }

in the global.asax how do i get access to the properties - such as  the userFullName?


to use the static class and function should i create another class file with methods for getComputerName and getIPAddress?
0
 
LVL 51

Expert Comment

by:Ted Bouskill
ID: 34966629
Yes, create a new file with a static class that has static helper methods.  You could then add a method like this:

public string getUserFullName()
{
    return ((AppCommon)Session["UserInfo"]).userFullName;
}

NOTE: I didn't add any exception or error handling in my examples to keep it simple.
0
 

Author Comment

by:vicomin
ID: 34972000
okay will try that; will deal with error handling once i get it working. how do i use this with the global asa?

tedbilly, if i do:
void Session_Start(object sender, EventArgs e)
        {
            // Code that runs when a new session is started
            Session["UserInfo"] = new AppCommon();      
        }

in the global.asax how do i get access to the properties - such as  the userFullName?
0
 
LVL 51

Expert Comment

by:Ted Bouskill
ID: 34973403
My last comment explained how to do it.  I don't know how to make it any simpler.
0
 

Author Comment

by:vicomin
ID: 34974775
got an error trying this

'getUserFullName': cannot declare instance members in a static class

see my clsStaticHelpers.cs file code below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.SessionState;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Security;
using System.Security.Principal;
using System.Net;
using System.Data;
using System.Collections;
using System.Data.SqlClient;

namespace Company
{
    public static class StaticHelpers
    {
        public static string SessionIPAddress()
        {
            return System.Web.HttpContext.Current.Request.ServerVariables["remote_addr"];
        }


        public string getUserFullName()
        {
            return ((AppCommon)System.Web.HttpContext.Current.Session["UserInfo"]).userFullName;
            //return ((AppCommon)Session["UserInfo"]).userFullName;
        }

    }
}

Open in new window

0
 
LVL 51

Accepted Solution

by:
Ted Bouskill earned 2000 total points
ID: 34976485
Sorry there was a typo with my example.  Add the 'static' keyword to the getUserFullName()
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.SessionState;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Security;
using System.Security.Principal;
using System.Net;
using System.Data;
using System.Collections;
using System.Data.SqlClient;

namespace Company
{
    public static class StaticHelpers
    {
        public static string SessionIPAddress()
        {
            return System.Web.HttpContext.Current.Request.ServerVariables["remote_addr"];
        }


        public static string getUserFullName()
        {
            return ((AppCommon)System.Web.HttpContext.Current.Session["UserInfo"]).userFullName;
            //return ((AppCommon)Session["UserInfo"]).userFullName;
        }

    }
}

Open in new window

0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this Article, I will provide a few tips in problem and solution manner. Opening an ASPX page in Visual studio 2003 is very slow. To make it fast, please do follow below steps:   Open the Solution/Project. Right click the ASPX file to b…
IntroductionWhile developing web applications, a single page might contain many regions and each region might contain many number of controls with the capability to perform  postback. Many times you might need to perform some action on an ASP.NET po…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
Suggested Courses
Course of the Month19 days, 16 hours left to enroll

872 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question