LDAP身份验证仅在localhost上的远程服务器中不起作用

时间:2015-06-23 07:23:11

标签: asp.net authentication iis-7 ldap c#-3.0

我正在使用asp.net c#3.5创建一个Web应用程序,我的服务器是在IIS7中运行的Windows SQL Server 2008 R2,我从MSDN获得了这个LDAP身份验证代码:Active Directory Domain Services Authentication from ASP .NET它工作正常在localhost上运行:

enter image description here

然而,当我尝试通过远程服务器访问它时,身份验证不再起作用,它给了我运行时错误:

enter image description here

以下是我的身份验证设置:

enter image description here

我的应用程序池在.Net Framework版本:2.0,管道模式:集成中运行。请让我知道我做错了什么,我是LDAP身份验证的新手。提前谢谢。

这是我的完整代码:

的Login.aspx

<asp:Login ID="LoginUser" runat="server" ViewStateMode="Disabled" RenderOuterTable="false">
        <LayoutTemplate>
            <table style="width:200px;text-align:center;margin:0 auto;">
                <tr>
                    <td colspan="2" style="text-align:center;"><h3 style="color:#00A5D3;">LDAP Authentication</h3></td>
                </tr>
                <tr>
                    <td colspan="2"><asp:TextBox CssClass="tb" placeholder="User name" runat="server" ID="UserName" /></td>
                </tr>
                <tr>
                    <td colspan="2"><asp:TextBox CssClass="tb" placeholder="Password" runat="server" ID="Password" TextMode="Password" /></td>
                </tr>
                <tr>
                    <td colspan="2"><asp:Button Height="40" ID="btnLogin" Width="300" OnClick="Login_Click" CssClass="btn btn-info" runat="server" CommandName="Login" Text="Log in" /></td>
                </tr>
            </table>
            <asp:CheckBox ID="chkPersist" runat="server" Text="Persist Cookie" />
            <center><asp:Label ID="errorLabel" runat="server" ForeColor="#ff3300"></asp:Label></center>
        </LayoutTemplate>
    </asp:Login>

<script runat="server">
    void Login_Click(object sender, EventArgs e)
    {
        String txtDomain = "hardcodedDomain"; //to avoid confusion to users
        TextBox txtUsername = (TextBox)LoginUser.FindControl("UserName");
        TextBox txtPassword = (TextBox)LoginUser.FindControl("Password");
        CheckBox chkPersist = (CheckBox)LoginUser.FindControl("chkPersist");
        Label errorLabel = (Label)LoginUser.FindControl("errorLabel");

        string adPath = "LDAP://company.domain.org"; //Path to your LDAP directory server

        LdapAuthentication adAuth = new LdapAuthentication(adPath);
      try
      {
        if(true == adAuth.IsAuthenticated(txtDomain, txtUsername.Text, txtPassword.Text))
        {
          string groups = adAuth.GetGroups();

          //Create the ticket, and add the groups.
          bool isCookiePersistent = chkPersist.Checked;
          FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, 
                    txtUsername.Text,DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups);

          //Encrypt the ticket.
          string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

          //Create a cookie, and then add the encrypted ticket to the cookie as data.
          HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);

          if(true == isCookiePersistent)
          authCookie.Expires = authTicket.Expiration;

          //Add the cookie to the outgoing cookies collection.
          Response.Cookies.Add(authCookie);

          //You can redirect now.
          //Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false));
            Response.Redirect("WebForm1.aspx");
        }
        else
        {
          errorLabel.Text = "Authentication did not succeed. Check user name and password.";
        }
      }
      catch(Exception ex)
      {
        errorLabel.Text = "Error authenticating. " + ex.Message;
      }
    }
</script>

LdapAuthentication.cs

using System;
using System.Text;
using System.Collections;
using System.Web.Security;
using System.Security.Principal;
using System.DirectoryServices;


namespace FormsAuth
{
    public class LdapAuthentication
    {
        private string _path;
        private string _filterAttribute;

        public LdapAuthentication(string path)
        {
            _path = path;
        }

        public bool IsAuthenticated(string domain, string username, string pwd)
        {
            string domainAndUsername = domain + @"\" + username;
            DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, pwd);

            try
            {
                //Bind to the native AdsObject to force authentication.
                object obj = entry.NativeObject;

                DirectorySearcher search = new DirectorySearcher(entry);

                search.Filter = "(SAMAccountName=" + username + ")";
                search.PropertiesToLoad.Add("cn");
                SearchResult result = search.FindOne();

                if (null == result)
                {
                    return false;
                }

                //Update the new path to the user in the directory.
                _path = result.Path;
                _filterAttribute = (string)result.Properties["cn"][0];
            }
            catch (Exception ex)
            {
                throw new Exception("Error authenticating user. " + ex.Message);
            }

            return true;
        }

        public string GetGroups()
        {
            //DirectorySearcher search = new DirectorySearcher(_path);
            DirectoryEntry searchRoot = new DirectoryEntry(_path);
            DirectorySearcher search = new DirectorySearcher(searchRoot);
            search.Filter = "(cn=" + _filterAttribute + ")";
            search.PropertiesToLoad.Add("memberOf");
            StringBuilder groupNames = new StringBuilder();

            try
            {
                SearchResult result = search.FindOne();
                int propertyCount = result.Properties["memberOf"].Count;
                string dn;
                int equalsIndex, commaIndex;

                for (int propertyCounter = 0; propertyCounter < propertyCount; propertyCounter++)
                {
                    dn = (string)result.Properties["memberOf"][propertyCounter];
                    equalsIndex = dn.IndexOf("=", 1);
                    commaIndex = dn.IndexOf(",", 1);
                    if (-1 == equalsIndex)
                    {
                        return null;
                    }
                    groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1));
                    groupNames.Append("|");
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Error obtaining group names. " + ex.Message);
            }
            return groupNames.ToString();
        }
    }
}

的Global.asax.cs

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

namespace FormsAuthAd
{
    public class Global : System.Web.HttpApplication
    {

        protected void Application_Start(object sender, EventArgs e)
        {

        }

        protected void Session_Start(object sender, EventArgs e)
        {

        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {

        }

        void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            string cookieName = FormsAuthentication.FormsCookieName;
            HttpCookie authCookie = Context.Request.Cookies[cookieName];

            if (null == authCookie)
            {
                //There is no authentication cookie.
                return;
            }
            FormsAuthenticationTicket authTicket = null;
            try
            {
                authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            }
            catch (Exception ex)
            {
                //Write the exception to the Event Log.
                return;
            }
            if (null == authTicket)
            {
                //Cookie failed to decrypt.
                return;
            }
            //When the ticket was created, the UserData property was assigned a
            //pipe-delimited string of group names.
            string[] groups = authTicket.UserData.Split(new char[] { '|' });
            //Create an Identity.
            GenericIdentity id = new GenericIdentity(authTicket.Name, "LdapAuthentication");
            //This principal flows throughout the request.
            GenericPrincipal principal = new GenericPrincipal(id, groups);
            Context.User = principal;
        }

        protected void Application_Error(object sender, EventArgs e)
        {

        }

        protected void Session_End(object sender, EventArgs e)
        {

        }

        protected void Application_End(object sender, EventArgs e)
        {

        }
    }
}

的Web.config

<authentication mode="Forms">
  <forms loginUrl="login.aspx" name="adAuthCookie" timeout="10" path="/">
  </forms>
</authentication>
<authorization>
  <deny users="?"/>
</authorization>
<identity impersonate="true"/>

0 个答案:

没有答案