ASP.NET 2.0 Membership Provider with Active Directory Application Mode

Ramblings by David Crawford [MSFT]

 

Here is a quick set of steps to get working fast with ASP.NET 2.0 ADAM Authentication from

Windows 2003 SP 1:

  • Install and Configure ADAM
  • Set security to allow access by your applications process owner or an ADAM user in appropriate ADAM role e.g. Administrators, Readers
  • Drop in web.config in your newly created web project and fire up Web Admin Tool in VS2005 or create a basic ASP.NET page and drop the create user wizard control on it.
  • Use the control on the new page or WAT to create a user (Each approach creates the necessary attributes and sets permissions in ADAM)
  • Configure the forms authentication in the web.config (to only allow authenticated users from here out)
  • Add a logon user page and drop the default control (login.aspx is default and overridden by loginUrl in the config)
  • Test Authentication with the newly created user

If you do not have the necessary fields set in ADAM on a “user” object the provider will not authenticate even if the connection to the store succeeds with the same user / administrator ADAM account. The “user” object is the only type supported for Authentication out of the box. E.g. no userProxy or other without custom extension. An example of a custom provider is

https://blogs.msdn.com/craigmcmurtry/archive/2005/03/04/385129.aspx

 

If using VS2005, IIS is not required to test this scenario – the VS2005 web server will do. (just remember that if you are impersonating a user in the web.config that when you run your project that you have given access to the project directory. Not every user has access to the my docs\vs projects directory )

 

Note: A key in ADAM is that the user account is created, enabled, has an email address, and a userPrincipalName. It is required that all these users are in the ADAM Readers Role. This isn’t done by default when creating an ADAM user with ADSI Edit however if you fire up the Web Administration Tool in VS2005 with a valid connection string these accounts are created properly – ignore a current bug with updates – the update occurs regardless of the error msg in the web tool. The ASPX controls do not have this error/message and work just fine as well (to create a user – just add the create user wizard on a page from the toolbox with a working connection string and away you go )

The SSL setup configurations are on ADAM FAQ https://www.microsoft.com/windowsserver2003/adam/ADAMfaq.mspx

I tested this approach with both ADAM and Windows credentials. I did it using SSL and without. If you are using the ADAM Provider without SSL then you need to set the connection protection in the adapter configuration to None and the ldap port to non-SSL e.g. 389. Connecting to ADAM with Windows Credentials will not support connectionProtection="None" however using ADAM credentials to connect to ADAM for authenticating ADAM principals will support it.

The following is used to drop the requirement for setting passwords over a clear connection:

Open ASDI edit and disable SSL bind requirement for connections (see https://support.microsoft.com/default.aspx?scid=kb;en-us;817583 for details):

· Go to the Configuration context and choose the properties for CN=Directory Services, CN=Windows NT, CN=Services.

· Double click the attributes "msDS-Other-Settings" and click edit and remove the entry "RequireSecureProxyBind=1" and replace it with "RequireSecureProxyBind=0", then choose "OK".

· Open a command prompt to disable the SSL bind requirement for setting passwords.

· Go to C:\WINDOWS\ADAM. Run dsmgmt.

· At the dsmgmt: prompt, type: ds behavior

· At the ds behavior: prompt, type: connections

· At the server connections: prompt, type: connect to server localhost:389

· At the server connections: prompt, type: quit

· At the ds behavior: prompt, type the following: allow passwd op on unsecured connection

· Type quit repeatedly until you’re back at a directory prompt.

There are a number of topologies that you may want to run using ADAM Authentication and when you are crossing between Workgroup and Domain machines, there are some configuration changes that you must be aware of. For instance, if running your own Certificate Authority or using a custom certificate, you have to remember to add the appropriate certificates to the correct store on each machine and then set permissions to the appropriate directory on the ADAM server. The scenario that I am discussing utilizes ADAM with SSL primarily. The machine in the domain runs ADAM and is accessed from a workgroup machine. There is a local shadow account – adamadmin which was tested demonstrating access to the remote file system via a UNC to ensure there was no prompting for credentials. With that test successful, I create an ADAM user (apparently it doesn’t matter if it has a userPrincipalName for the connection only – interesting tidbit that I picked up is that an account without a userPrincipalName doesn’t show up in Web Administration Tool or via the provider controls. Create a new user running WAT and then test authentication with the default control on a page. My site has two pages, default.aspx and login.aspx (note – there is a default login page set in machine.config) Another important note is that the login.aspx page should always be modified with a NAMESPACE otherwise if you pre-compile and publish – you get namespace error conflicts with the system.web control. Adding your own namespace prevents this failure on a pre-compiled site.

The web.config below has application impersonation setup, but you also have explicitly specified domain creds in the provider for the connection username. With this combination the provider will use the explicitly configured credentials - not the credentials in the <identity /> attribute.

 

If the intent is to run the ASP.NET site as "adamamin" (and hence the provider as well), then remove the connectionUsername and connectionPassword attributes from the provider config.

 web.config

<?xml version="1.0"?>

<!--

    Note: As an alternative to hand editing this file you can use the

    web admin tool to configure settings for your application. Use

    the Website->Asp.Net Configuration option in Visual Studio.

    A full list of settings and comments can be found in

    machine.config.comments usually located in

    \Windows\Microsoft.Net\Framework\v2.x\Config

-->

<configuration xmlns="https://schemas.microsoft.com/.NetConfiguration/v2.0">

      <appSettings/>

     

      <connectionStrings>

           

<!--

    Secure - LDAP with SSL default port is 636

-->

            <add name="ADConnectionString" connectionString="LDAP://ADOM.DOM.ORG:636/CN=TheUsers,CN=Program Data,DC=Portal,DC=US" />

      </connectionStrings>

     

      <system.web>

           

            <identity impersonate="true" userName="adamadmin" password="xxxxxxxxxxxx"/>

           

  <compilation debug="false" strict="false" explicit="true"/>

            <pages>

                  <namespaces>

                        <clear/>

                        <add namespace="System"/>

                        <add namespace="System.Collections"/>

                        <add namespace="System.Collections.Specialized"/>

                        <add namespace="System.Configuration"/>

                        <add namespace="System.Text"/>

                        <add namespace="System.Text.RegularExpressions"/>

                        <add namespace="System.Web"/>

                        <add namespace="System.Web.Caching"/>

                        <add namespace="System.Web.SessionState"/>

                        <add namespace="System.Web.Security"/>

                        <add namespace="System.Web.Profile"/>

                        <add namespace="System.Web.UI"/>

                        <add namespace="System.Web.UI.WebControls"/>

                        <add namespace="System.Web.UI.WebControls.WebParts"/>

                        <add namespace="System.Web.UI.HtmlControls"/>

                  </namespaces>

            </pages>

            <!--

 The name spaces directly above are not necessary for ADAM AuthN however the <authentication> section enables configuration of the security authentication mode used by

            ASP.NET to identify an incoming user.

        -->

            <authentication mode="Forms">

                  <forms requireSSL="false"/>

            </authentication>

           

                 

            <authorization>

                  <deny users="?" />

                  <allow users="*" />

            </authorization>

           

                  <membership defaultProvider="ADAMMembershipProvider">

                        <providers>

                             

                              <!-- connectionProtection="None" -->

                              <!-- connectionProtection="Secure" -->

                              <add

        name="ADAMMembershipProvider"

    type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

     connectionStringName="ADConnectionString"

  enableSearchMethods="true"

  connectionProtection="Secure"

  connectionUsername="ADOM.DOM.ORG\adamadmin"

   connectionPassword="xxxxxxxxxxxxxxxxx"

/>

 

<!—ADAM Identity to logon with (Interesting noteremoving the userPrincipal Name makes this ADAM account invisible to the Membership provider but works for connectivity and management – set the credentials below in place of what is in the add node above

  

connectionUsername="CN=ADMIN,CN=TheUsers,CN=Program Data,DC=Portal,DC=US "

                                    connectionPassword="xxxxxxxx"                        

-->

                                </providers>

            </membership>

      </system.web>

      </configuration>

You can alter the logon page using this node -  <forms loginUrl="logon.aspx" requireSSL="false"/>

 and use the default logon control on the page logon page.

The configuration above has the application impersonation setup, but also explicitly sets domain credentials in the provider for the connection username. This combination results in the provider using the explicitly configured credentials and not the credentials specified in the <identity /> attribute. When the intent is to run the ASP.NET site as "adamamin" (and hence the provider as well), then remove the connectionUsername and connectionPassword attributes from the provider configuration.

Note: The above configuration is meant to get started with the provider and ADAM however when ready for production check out the following :

patterns & practices ASP.NET 2.0 Security Guidance Index

https://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/ASPNET2SecurityGuidanceIndex.asp?frame=true

I hope you found this useful… Please let me know…

 

Also, a big thanks to a couple of my colleagues for helping me along…

Comments

  • Anonymous
    April 04, 2006
    I did some rambling on ASP.NET 2.0 Membership Provider with Active Directory Application Mode on the...

  • Anonymous
    April 04, 2006
    I am just wondering if this can be used with Windows Authentication - Our intranet portal is based on IBuySpy and works well with Windows Authentication. However we are planning to move to 2.0 but would like to have Windows Authentication (for the entire intranet site) and use AzMan for each individual application hosted on the intranet. I am thinking this would a common scenario for most intranet sites. I havent found much information with regard to the same. I would appreciate if you could provide me some pointers with regard to this (Form Authentication is a no-no for us).

    Thanks.

  • Anonymous
    April 05, 2006
    Authorization Manager does not require forms authentication and in fact has a lot of bells and whistles are specifically designed to work with Integrated Security.  

    The forms authentication is most commonly used with Internet access scenarios which the provider will still work with AzMan when directing to Active Directory. ADAM support for AzMan requires direct use of the API however and I will be writing more on that.  There will also be a white paper available pretty soon on the same.

    There are articles which demonstrate the capability you are describing such as the following
    - start here

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/PAGHT000019.asp
    and
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/paght000013.asp
    You can use the provider or directly to the API for fine grain authorization.  From the previous link...

    // Get the current user context
       IPrincipal userPrincipal = HttpContext.Current.User;
       WindowsIdentity userIdentity = userPrincipal.Identity as WindowsIdentity;

       IAzClientContext clientContext =
           azApp.InitializeClientContextFromToken(
                  (ulong)userIdentity.Token, null);
     
    Regards,
    David

  • Anonymous
    April 05, 2006
    Hi,

    I just want to know if my following scenario would work:
    - for Membership, I use SQL Server
    - for Roles, I use ADAM

    Thx.

  • Anonymous
    April 06, 2006
    The comment has been removed

  • Anonymous
    April 19, 2006
    According to this article, the ADAM user created and therefore used for authenticating should have granted the “Readers” role, but when I try to grant such in ADSI Edit tool –adding the user in the “member” property in the role-, I get an error: “A directory service error has occurred” (not too self-explanatory, in my opinion). Why? How can I add this user in the Readers role using ADSI Edit Tool? Thanks in advance.

  • Anonymous
    April 24, 2006
    Where are you attempting to add the user to a Readers role?

    You should be able to connect to a location such as the following...
    CN=Program Data,DC=AnyPortal,DC=US

    Let's say there will be the following contained:
    CN=Roles
    CN=PortalUsers

    within Roles, select Readers then properties, then select the member attribute and click the Edit button when the display should have the buttons for the object pickers shown as Add Windows Account and Add ADAM Account.

    or if you go to to the users container -
    CN=PortalUsers then you would select a user account and specify memberOf but would need the full path to the readers role - without the object picker.

    Is the process owner accessing ADAM via ADSI Edit in the Admin role for that container?

    Regards,
    David

  • Anonymous
    May 10, 2006
    Hi,

    I wanted to know if the following scenario would work:
    - for Membership and authentication, I use ADAM
    - for Roles, I use SQL Server.

    Thanks!

    Saumin

  • Anonymous
    July 05, 2006
    Hey Saumin, I have successfully implemented membership/authentication and roles in an application doing just as you describe very easily (using ADAM for Membership and SQLServer for Roles), so my answer is yes, it will work, and fairly easily.

    The Sql backing for the SqlRoleProvider is flexible enough to simply add username/role mappings that are independent of users that might exist in the SqlMembershipProvider store.  It takes a bit more effort to manage the mappings since they obviously aren't enforced by DB constraints, but the resulting effect works just like you'd expect.  Pretty simple!

    -Billy

  • Anonymous
    April 19, 2007
    The comment has been removed

  • Anonymous
    May 07, 2007
    Sorry for the delay... I apparently I didnt get the notification that this topic was modified.  Please post directly to the site with your contact into to this blog and we will take it offline. David

  • Anonymous
    February 26, 2008
    I am trying to implement Active Directory memebership provider with sharepoitn server 2007.I am getting the site alaos with form based authentication ,there is one issue is like the mysite links disappears from the home page of the aite when i shifted from windows based authentication to form based authentication

  • Anonymous
    October 02, 2008
    Can we use this code when Hosting domain and AD domain are diffrent but having site2site VPN connectivity

  • Anonymous
    November 03, 2009
    http://blogs.http://blogs.msdn.com/blogs/JpegImage.aspxmsdn.com/blogs/JpegImage.aspx     Please enter the code Enter Code Here: Req     Please enter the code Enter Code Here: Req     Please enter the code Enter Code Here: Req