Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to work with LDAP 1

Status
Not open for further replies.

taree

Technical User
May 31, 2008
316
US
I am trying to create a secure page and I would like to use Active Directory to authenticate users.I am really new to this and I would like to get some help from you experts.what are the steps that I need to follow to get this working. I would like the users to enter their Ad account user Id and password and then the page will be redirected to the secured page. My web config file look like the one on below. please your help is really appreciated.


Code:
<configuration>  
    
	<connectionStrings>
		  <add name="ADConnectionString" connectionString="LDAP://ad.xx.xxxxx.xx.xx:350/DC=ad,DC=xxx,DC=xxxxx,DC=xx,DC=xx"/>
	</connectionStrings>
  
  <system.web>
        <compilation debug="true"/>
  </system.web>
    
  <system.web>
      <authentication mode="Forms">
        <forms name=".ASPNET" loginUrl="logon.aspx"  defaultUrl="secure/default.aspx" />
      </authentication>
  </system.web>
  
  <location path="secure">   
    <system.web>
       <authorization>
         <deny users="?"/>
         <allow users="*"/>
         <allow roles="secure" />
       </authorization>
     </system.web>
   </location>
   
  <system.web>    
	<membership>
     <providers>
         <add connectionStringName="ADConnectionString"
              connectionUsername="ldapbr"
              connectionPassword="ldapbr" 
              attributeMapUsername="sAMAccountName"
              name="MembershipADProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
     </providers>
 </membership>
  </system.web>
 
</configuration>
 
Code:
<system.web>
      <authentication mode="Windows" />
      <identity impersonate="true" />
</system.web>

<location path="secure">   
   <system.web>
      <authorization>
         <deny users="?"/>
         <allow roles="secure" />
      </authorization>
   </system.web>
</location>
where secure is a role/group in active directory.

By using Windows authentication instead of Forms the users get the convenience of single signon.

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Thank you Jason for your help.The reason why I want to use form authentication is for me to learn and see how the form authentication works and I just want to give an access for the a limited users and I am not sure if I can do this with windows authentication.please clarify that for me if I am wrong with windows authentication.
I just work with the web.config file a little bit and seems to work ok. please help if I am missing in the web.config file for the form authentication to work properly
Code:
configuration>
	<connectionStrings>
		<add name="ADConnectionString" connectionString="LDAP://xx.xxx.xxx.xx.xx:389/DC=ad,DC=xx,DC=xxx,DC=xx,DC=xx"/>
	</connectionStrings>
	<system.web>
		<compilation debug="true">
			<assemblies>
				<add assembly="System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/></assemblies></compilation>
	</system.web>
	<system.web>
		<authentication mode="Forms">
			<forms name=".ASPNET" loginUrl="secure/logon.aspx" defaultUrl="secure/default.aspx"/>
		</authentication>
	</system.web>
	<location path="secure">
		<system.web>
			<authorization>
				<deny users="?"/>
				<allow users="*"/>
			</authorization>
		</system.web>
	</location>
	<system.web>
    <membership defaultProvider="MembershipADProvider">
      <providers>
        <add
           name="MembershipADProvider"
           type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
           connectionStringName="ADConnectionString"
           connectionUsername="ldapbrowse"
           connectionPassword="ldapbrowse"
           attributeMapUsername="sAMAccountName"
            />
      </providers>
    </membership>
    
	</system.web>
</configuration>
 
The reason why I want to use form authentication is for me to learn and see how the form authentication works
If your spiking code for Forms authentication, then focus on Forms and do not introduce AD.
I just want to give an access for the a limited users
authentication and authorization are two different concerns. Authentication is how the user is validated (Forms, Windows, etc.)
Authorization is what the user can do(directory/page access)
You can modify one without effecting the other.

As for your web.config. I try to keep as much configuration in my code as possible. XML is ugly and prone to errors. So I do not have too much experience with elaborate web.configs.

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Thank you Jason for your info. I always lear a lot from you and all the other experts. I am really greatful for that.just to get back to my question. I am following your suggestions and now I am using windows authentication...

Do I need to have this in my web.config file

if this works what is the next thing I should do...I know I am asking to much but I am really eager to learn and I do not find a good tutorials that explain windows authentication and LDAP. thank you all

Code:
  <membership defaultProvider="MembershipADProvider">
      <providers>
        <add
           name="MembershipADProvider"
           type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
           connectionStringName="ADConnectionString"
           connectionUsername="ldapbrowse"
           connectionPassword="ldapbrowse"
           attributeMapUsername="sAMAccountName"
            />
      </providers>
    </membership>
 
I use windows authentication for my applications. my web.config looks like this
Code:
<?xml version="1.0"?>
<configuration xmlns="[URL unfurl="true"]http://schemas.microsoft.com/.NetConfiguration/v2.0">[/URL]
	<system.web>
		<authentication mode="Windows"/>
		<identity impersonate="true"/>
		<roleManager defaultProvider="AspNetWindowsTokenRoleProvider">
			<providers>
				<remove name="AspNetSqlRoleProvider" />
			</providers>
		</roleManager>
		<!-- order of allow/deny is important. start specific | end general-->
		<authorization>
			<allow roles="DOMAIN\role1, DOMAIN\role_2" />
			<deny users="*" />
		</authorization>
	</system.web>
	<location path="to\somewhere\">
		<authorization>
			<allow roles="DOMAIN\role_3" users="DOMAIN\username" />
			<deny users="?" />
		</authorization>
	</location>
</configuration>
* is a wild card for all users
? is a wild card for unauthenticated users

this type of configuration works for simple/small websites. if you have a complex set of roles over a large user base this approach quickly falls apart due to the amount of configuration required.

In this type of scenario I would abandon this altogether and implement my own IHttpModule and wire into the BeginRequest event where authorization could take place. if the user is not authorized throw a custom SecurityBreachException exception. with a message like

user X attempted to access URL at CURRENT_TIME.

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Jason,

using your suggestion I am able to work with windows authentication and thank yo for that. my other question is how does this work when a user to access the page by typing a URL, let assume this is a valid user.Can I still use windows authentication or do i need to change to form authentication. Thank you and I hope my question makes sense.
 
do you mean:
how is validation affected if the user clicks a link vs. types the url?
It doesn't each request is validated. The server doesn't care whether the user typed the url manually, or clicked a link. all the server knows is that a client is requesting the asp.net pipeline to process the current url.

with web development each request is autonomous and has no knowledge of prior or concurrent requests. session & cookies (and viewstate if you're using webforms) can create an illusion of state; but its still a web environment. There is no state.

authentication, authorization, and requesting a url are all indpenendent tasks. the asp.net pipeline puts them all together. but each piece can be changed without effecting others.

also, you wouldn't change authentication mechanisms midway through the application. Pick one and stick with it. (maybe you can by making one set of pages windows authentication, and another forms authentication, but I don't see how that is beneficial.)

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Thank you Jason for your reply. please bear with me as I am trying to understand this. This might be a stupid question but what If I am trying to access the page from the user who does not have a right to access the page. Do I need to logout first and login as me to access the page or do I need to create a login page and type my windows userid and password. please clarify this for me. thank you
 
ok, that is different.

using windows authentication the current windows credentials are passed with the request. if a user attempts to access a page they do not have rights to view an exception is thrown (i think).

with windows authentication the login occurs when the user logs into the computer. when the webpage is accessed their credentials are passed with the request. the user is never prompted to login to the website. This is also referred to as "single signon".

for a different user to log into the system the current user must log off and the new user must logon. if you want multiple logins from a single windows account then you need to use Forms authentication.

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Thank you very much for the clarification. I think it is better for me to go with form authentication and LDAp and hopefully it will not be very difficult to work with. I thank you for your time and your valuable information Jason.
 
Eventhough I set up my web.config file to deny access for user that are not in the group they still access using their AD account. I do not understand why they are able to access the page eventhough they do not have access.

Code:
<configuration>
	<connectionStrings>
		    <add name="ADConnectionString" connectionString="LDAP://xx.xx.xxx.xx.xx:389/DC=xx,DC=xxx,DC=xxx,DC=xx,DC=xx"/>
	</connectionStrings>
	<system.web>
		<compilation debug="true">
			 <assemblies>
				<add assembly="System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/></assemblies></compilation>
	</system.web>
 
  <system.web>
    <authentication mode="Forms" >
      <forms name=".ASPNET"
          slidingExpiration="false"
          loginUrl="secure/logIn.aspx"             
          defaultUrl="secure/FillOutForm.aspx"
          cookieless="UseCookies" />
    </authentication>
  </system.web>
	<location path="secure">
		<system.web>

         <authorization>
         <deny users ="?"/>
         <allow users="*"/>
         <allow roles="AD\TS "/>              
         <allow users="AD\racc1Ytts"/>
       </authorization>
		</system.web>
	</location>
	<system.web>
    <membership defaultProvider="MembershipADProvider">
      <providers>
        <add
           name="MembershipADProvider"
           type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
           connectionStringName="ADConnectionString"
           connectionUsername="ldapbrowse"
           connectionPassword="ldapbrowse"
           attributeMapUsername="sAMAccountName"
           />
      </providers>
    </membership>    
	</system.web>
</configuration>
 
<deny users ="?"/>
<allow users="*"/>

deny unauthenticated users. allows all authenticated users.

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
you can also compress the nodes like this
<allow roles="AD\TS" users="AD\racc1Ytts"/>
<deny users ="?"/>

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Thank you Jason again for the help. I just used your suggestion and for some reason unauthorized user can still access the page. Am I missing something here or something needs to be reconfigured in the server side?It is just a mistery to me.....thank you
 
oh, it's the location node. you are only securing the path 'secure' any pages outside of the 'secure' are accessible by anyone.

also you cannot put your login page within the secured directory. that's like locking ye our keys in the car. you need the keys to open the car, but the keys are in the locked car.

put the login page in the root folder. anyone should have access to this. if you want the site to be secure put all pages in the secure folder. the project structure would look like this
[tt]
web project
login.aspx
global.asax (optional)
web.config
secure/
default.aspx
other files/directories as necessary
[/tt]

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Jason thank you again for the help and believe it or not after I restructure my folder Unathorized user still accessing the secured page.I am really furstrated and I do not know what to do with this thing. It seems so simple and straight forward and I do not know where I got it wrong. I thank you for your help and I do not waste your valuabvle time I probably need to do more googling ....thank you again
 
some other insights:
1. you are using MembershipADProvider with Forms Authentication. if this is an intranet application why not use Windows Authentication and remove the need to login?
2. anyone who is a part of AD\TS or the user AD\racc1Ytts can login. Are you testing under the AD\racc1Ytts account, or another account that is part of the AD\TS group?
if so then you may be bypassing the login page because you are already validated. If this is the case it is most likely the MembershipADProvider mixed with Form Auth. that's causing this.

as a test put this code on one of the secured pages
Code:
public void Page_Init(object sender, EventArgs e)
{
   bool is_in_role = User.IsInRole("AD\TS");
   System.Diagnostics.Debug.WriteLine("user {1} is in role AD\TD: {0}", is_in_role, User.Name);
}
debug the app and visit this page. watch the debugger windows to see the results. this will tell you if the user really is unauthorized.

Jason Meckley
Programmer
Specialty Bakers, Inc.
 
Hi jason,
I was out for few days and sorry I did not tell you why it was not working for me. Like you guessed it I think it is MembershipADProvider mixed with Form Auth....I just decided to abandon this and work with Ad to find the user group and compare it with my hard coded group to see if it mached then I want to redirected it to the secure ...here is my new code looks like. the problem is eventhough there is a match between the user group the does not redirect the user to the secure page.

Code:
  Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim username As String = User.Text 'Context.User.Identity.Name
        Dim grouptoCheck As String = "Bid"

        Dim domain As String = "AD"
        Dim ADlogin As String = "ldapbrowse"
        Dim ADpassword As String = "ldapbrowse"

        Dim EntryString As String
        EntryString = "LDAP://" & domain
        Dim myDE As DirectoryEntry
        grouptoCheck = grouptoCheck.ToLower()
        If (ADlogin <> "" AndAlso ADpassword <> "") Then
            myDE = New DirectoryEntry(EntryString, ADlogin, ADpassword)
        Else
            myDE = New DirectoryEntry(EntryString)
        End If
        Dim myDirectorySearcher As New DirectorySearcher(myDE)
        myDirectorySearcher.Filter = "sAMAccountName=" & username
        myDirectorySearcher.PropertiesToLoad.Add("MemberOf")
        Dim myresult As SearchResult = myDirectorySearcher.FindOne()
        Dim NumberOfGroups As Integer
        NumberOfGroups = myresult.Properties("memberOf").Count() - 1


        Dim UserADGroup As String
        While (NumberOfGroups >= 0)

            UserADGroup = myresult.Properties("MemberOf").Item(NumberOfGroups)
            UserADGroup = UserADGroup.Substring(0, UserADGroup.IndexOf(",", 0))
            UserADGroup = UserADGroup.Replace("CN=", "")
            UserADGroup = UserADGroup.ToLower()
            UserADGroup = UserADGroup.Trim()

            If (grouptoCheck = UserADGroup) Then
                Response.Redirect("/secure/FillOutForm.aspx")
            Else
                NumberOfGroups = NumberOfGroups - 1
            End If

        End While

    End Sub

login page
Code:
 <form id="form1" runat="server">
    <div style="text-align: left">
        &nbsp; &nbsp;<br />
        <asp:TextBox ID="UsName" runat="server" Width="160px"></asp:TextBox>&nbsp;<br />
        <asp:TextBox ID="pass" runat="server" Width="160px"></asp:TextBox><br />
        <br />
        <asp:Button ID="Button1" runat="server" Text="Submit" />&nbsp;
    
    </div>
    </form>
 
Check the case of the values. VB is weird with case sensitivity comparisons sometimes. Usually I will convert any values I compare to all lowercase, then do the compare, just to avoid the problem.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top