asp.net-mvcldapdefaultcredentials

LDAP auth in ASP.NET MVC authentication error: "Default credentials are not supported when the connection protection is set to None"


I am trying to implement LDAP authentication on the ADAM LDAP server of my company with ASP.NET MVC.

I already tested coordinates and credentials with other LDAP clients and they work fine. The server is not SSL secured and it works on standard 389 port, so I set connectionProtection="None" in web.config membership provider.

When I try login with default login page, I get this error:

Default credentials are not supported when the connection protection is set to None.

Here are parts of web.config

<configuration>
  <connectionStrings>
    <add name="ADConnectionString"    connectionString="LDAP://mycompanyldapserver.com:389"/>
    
  ....

<membership defaultProvider="DefaultMembershipProvider">
  <providers>
    <add name="DefaultMembershipProvider"
         type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0,Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
         connectionStringName="ADConnectionString"
         connectionProtection="None"
         attributeMapUsername="sAMAccountName"
         enableSearchMethods="True"/>
  </providers>
</membership>

AccountController

    [AllowAnonymous]
    [HttpPost]
    public JsonResult JsonLogOn(LogOnModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            // >> Membership.ValidateUser THROWS EXCEPTION AFTER LOGIN TRY >>
            if (Membership.ValidateUser(model.UserName, model.Password)) 
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                return Json(new { success = true, redirect = returnUrl });
            }

EDIT

I discovered that the exception "Default credentials are not supported when the connection protection is set to None" is not thrown when I add these parameters to DefaultMembershipProvider:

connectionUsername="username"
connectionPassword="userpwd"

The problem is that username and password must change runtime, based on login form...may you help me to set these parameters runtime, please? I tried to implement this solution, which I suppose could work...I suppose because now I get a "wrong username or password" error instead of above exception specified in the subject. I think I am a step away to solve this problem, anyway I need help from some expert. I do not konw if the following solution can work properly to validate user:

MODIFIED ACCOUNT CONTROLLER: I AM TRYING TO ADD MEMBERSHIP PROVIDER RUNTIME

    [AllowAnonymous]
    [HttpPost]
    public JsonResult JsonLogOn(LogOnModel model, string returnUrl)
    {

        // I'm trying to add membership provider runtime...

        System.Web.Security.ActiveDirectoryMembershipProvider mprov = new System.Web.Security.ActiveDirectoryMembershipProvider();

        NameValueCollection objConfig = new NameValueCollection();
        objConfig.Add("name", "DefaultMembershipProvider");
        objConfig.Add("type", "System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0,Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
        objConfig.Add("connectionStringName", "ADConnectionString");
        objConfig.Add("connectionProtection", "None");
        objConfig.Add("connectionUsername", model.UserName);
        objConfig.Add("connectionPassword", model.Password);
        objConfig.Add("attributeMapUsername", "sAMAccountName");
        objConfig.Add("enableSearchMethods", "True");

        try
        {
            // Here I get "wrong username or password error...wrong DN base? I do not know.....
                 mprov.Initialize(objConfig["name"], objConfig);
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                return Json(new { success = true, redirect = returnUrl });
        }

        catch (System.Runtime.InteropServices.COMException ex)
        {
            // For now I am catching all COMExceptions...if it works I could change behavior...
            ModelState.AddModelError("", ex.Message);

        }

Solution

  • The main problem was the following error: "Default credentials are not supported when the connection protection is set to None". When DefaultMembershipProvider has connectionProtection="None" it needs connectionUsername and connectionPassword to be set:

    web.config

         <membership defaultProvider="DefaultMembershipProvider">
         <providers>
            <add name="DefaultMembershipProvider"
            type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0,Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
            connectionStringName="ADConnectionString"
            connectionProtection="None"
            connectionUsername="username"
            connectionPassword="userpwd"
            attributeMapUsername="sAMAccountName"
            enableSearchMethods="True"/>
          </providers>
          </membership>
    

    The second problem was that I use LDAP for authentication, so I did not want to use static connectionUsername and connectionPassword. So I decided to define whole MembershipProvider runtime, modifying my account controller JsonLogOn action (LogOn action should be modified in similar way):

    ACCOUNT CONTROLLER / LOGON

        // POST: /Account/JsonLogOn
    
        [AllowAnonymous]
        [HttpPost]
        public JsonResult JsonLogOn(LogOnModel model, string returnUrl)
        {
            System.Web.Security.ActiveDirectoryMembershipProvider mprov = new System.Web.Security.ActiveDirectoryMembershipProvider();
            string baseDN = "OU=myou,OU=myou1,O=myO";
            NameValueCollection objConfig = new NameValueCollection();
            objConfig.Add("name", "DefaultMembershipProvider");
            objConfig.Add("type", "System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0,Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
            objConfig.Add("connectionStringName", "ADConnectionString");
            objConfig.Add("connectionProtection", "None");
            objConfig.Add("connectionUsername", "uid=" + model.UserName + "," + baseDN);
            objConfig.Add("connectionPassword", model.Password);
            objConfig.Add("attributeMapUsername", "sAMAccountName");
            objConfig.Add("enableSearchMethods", "True");
    
            try
            {
                mprov.Initialize(objConfig["name"], objConfig);
               
            }
    
            catch (System.Runtime.InteropServices.COMException ex)
            {
                switch (ex.ErrorCode)
                {
                    // Server give back a value...
                    case -2147016661:
                        {
                            FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                            return Json(new { success = true, redirect = returnUrl });
                        }
                }
                ModelState.AddModelError("", ex.Message);
            }
            
            // If we got this far, something failed
            return Json(new { errors = GetErrorsFromModelState() });
        }