繁体   English   中英

Asp.net Active Directory LDAP:尝试向下过滤到组级别

[英]Asp.net Active Directory LDAP: Trying to filter down into a group level

我已经使用c#在asp.net中创建了一个登录页面,但是在尝试仅允许某个组具有访问权限时遇到了困难。 现在,我正在访问所有人,但似乎无法仅过滤所需的组,因此只有那些人才能访问我的应用程序。

任何帮助都将非常有用,因此我可以只允许该应用程序访问Active Directory中的那个组。

这是我用来传递分组的班级:

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);
        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();
    }

    public bool isMember( String groupname )
    {
        DirectorySearcher search = new DirectorySearcher(_path);
        search.Filter = "(cn=" + _filterAttribute + ")";
        search.PropertiesToLoad.Add("memberOf");
        try
        {
            SearchResult result = search.FindOne();
            int propertyCount = result.Properties["memberOf"].Count;

            for (int propertyCounter = 0; propertyCounter < propertyCount;
                    propertyCounter++)
            {
                String dn = (String)result.Properties["memberOf"][propertyCounter];
                // The comma in the regex is important to prevent accidental matches
                if ( Regex.IsMatch( dn, @"cn="+groupname+",.*", RegexOptions.IgnoreCase))
                    return true;
            }
        }
        catch (Exception ex)
        { 
            // Some logging here probably
        }
        return false;
    }
}

它必须在“获取组”功能中,但是我不确定如何传递我要查找的组。 如果有人可以提供帮助,将不胜感激。 提前致谢。

这是我的按钮单击事件:

    protected void btnLogin_Click(object sender, EventArgs e)
    {
        // Path to you LDAP directory server.
        // Contact your network administrator to obtain a valid path.
        string adPath = "LDAP://domain.com";
        LdapAuthentication adAuth = new LdapAuthentication(adPath);
        String myGroupName = "Some_Group";

        try
        {
            if (true == adAuth.IsAuthenticated(txtDomainName.Text, txtLoginID.Text, txtPassword.Text))
            {
                if( adAuth.isMember( myGroupName ) )
                  {
                      // User is authenticated and a member of the group. 
                      // Create your auth ticket, cookie, and whatnot
                      // Retrieve the user's groups
                        string groups = adAuth.GetGroups();
                        // Create the authetication ticket
                        FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1,  // version
                                                          txtLoginID.Text,
                                                          DateTime.Now,
                                                          DateTime.Now.AddMinutes(60),
                                                          false, groups);
                        // Now encrypt the ticket.
                        string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
                        // Create a cookie and add the encrypted ticket to the 
                        // cookie as data.
                        HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);

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

                        // Redirect the user to the originally requested page
                        //Response.Redirect(FormsAuthentication.GetRedirectUrl(txtLoginID.Text, false));

                        Response.Redirect("LookupEdit.aspx");   
                  }
                  else
                  {
                      lblError.Text = "Authorization failed. You are not a member of the "+myGroupName+" group";
                  }
                }
                else
                {
                  lblError.Text = "Authentication did not succeed. Check user name and password.";
                }
              }
              catch(Exception ex)
              {
                lblError.Text = "Error authenticating. " + ex.Message;
              }
    }

我对此也有疑问。 我使用与您进行AD身份验证几乎相同的类。 我使用另一种方式连接到AD,但遇到了一些奇怪的问题。 在更改此代码之前,我实现了一个角色提供程序,但仍在使用该角色提供程序拒绝和授予访问权限。 这就是我基本上做到的方式。 请点击此链接 ,因为它将帮助您设置角色。

我唯一更改的是带有的“ GetRolesForUser”。

public override string[] GetRolesForUser(string username)
{
    var allRoles = new List();
    var ctx = new PrincipalContext(ContextType.Domain);
    UserPrincipal user = UserPrincipal.FindByIdentity(ctx, username);
    if (user != null)
    {
       var groups = user.GetGroups();
       allRoles.AddRange(groups.Select(x => x.Name));
    }

    return allRoles.ToArray();
}

这样,您可以拒绝和授予web.config中的组。

我是这样的

<location path="TestPage.aspx">
    <system.web>
      <authorization>
        <allow roles="SoftwareDevelopers" />
        <deny users="*" />
      </authorization>
    </system.web>
 </location>

因此,我拒绝除广告组SoftwareDevelopers之外的所有人访问TestPage.aspx。

我希望这有帮助。 编辑:如果您正在使用注释中的链接来执行此活动目录,则获取组的一种方法是使用登录时创建的身份验证票证。

        if (Request.Cookies["ADAuthCookie"] != null)
        {
            HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
            FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);

            string cookiePath = ticket.CookiePath;
            DateTime expiration = ticket.Expiration;
            bool expired = ticket.Expired;
            bool isPersistent = ticket.IsPersistent;
            DateTime issueDate = ticket.IssueDate;
            string name = ticket.Name;
            string userData = ticket.UserData;
            int version = ticket.Version;
            System.Diagnostics.Debug.WriteLine(cookiePath);
            System.Diagnostics.Debug.WriteLine(expiration);
            System.Diagnostics.Debug.WriteLine(expired);
            System.Diagnostics.Debug.WriteLine(isPersistent);
            System.Diagnostics.Debug.WriteLine(issueDate);
            System.Diagnostics.Debug.WriteLine(name);
            System.Diagnostics.Debug.WriteLine(userData);
            System.Diagnostics.Debug.WriteLine(version);

            if (userData.Contains("SoftwareDevelopers"))
            {
                lblMessage.Text = "You're a software developer.";
            }

        }

您将必须解密票证才能读取信息。 我提供了如何将其写入控制台,以便您了解其工作原理。 如果您愿意,上面提供的if语句是限制/显示页面部分的一种方法。

但是,我发现此答案中有关如何设置ADRoleProvider的链接可能是您的最佳选择。

您想检查用户是否是正确组的成员,对吗? 为什么不创建一个接受组名并返回布尔值的函数,如下所示:

public boolean isMember( String username, String groupname )
    {
        DirectorySearcher search = new DirectorySearcher(_path);
        search.Filter = "(cn=" + username + ")";
        search.PropertiesToLoad.Add("memberOf");
        try
        {
            SearchResult result = search.FindOne();
            int propertyCount = result.Properties["memberOf"].Count;

            for (int propertyCounter = 0; propertyCounter < propertyCount;
                 propertyCounter++)
            {
                String dn = (String)result.Properties["memberOf"][propertyCounter];
                // The comma in the regex is important to prevent accidental matches
                if ( Regex.IsMatch( dn, @"cn="+groupname+",.*", RegexOptions.IgnoreCase)
                  return true;
            }
        }
        catch (Exception ex)
        { // Some logging here probably
        }
        return false;
    }

最好的方法是通过在搜索中指定组名来让LDAP进行成员资格迭代。 然而,需要的groupname是完整的组DN(例如cn=mygroup,ou=groups,dc=xxx,dc=xxx ),所以这可能不是你是可行的:

public boolean isMember( String username, String groupdn )
    {
        DirectorySearcher search = new DirectorySearcher(_path);
        // Escaping the input strings is advisable from a security standpoint!
        search.Filter = "(&(cn=" + username + ")(memberOf=" + groupdn + "))";
        search.PropertiesToLoad.Add("cn");
        try
        {
            SearchResult result = search.FindOne();
            // The LDAP server has done the matching for us
            if ( result != null )
               return true;
        }
        catch (Exception ex)
        { // Some logging here probably
        }
        return false;
    }

祝好运!

好的,所以在您发表评论后,您应该执行以下操作:

在您的LdapAuthentication类中创建一个isMember(String)函数:

public boolean isMember( String groupname )
{
    DirectorySearcher search = new DirectorySearcher(_path);
    search.Filter = "(cn=" + _filterAttribute + ")";
    search.PropertiesToLoad.Add("memberOf");
    try
    {
        SearchResult result = search.FindOne();
        int propertyCount = result.Properties["memberOf"].Count;

        for (int propertyCounter = 0; propertyCounter < propertyCount;
             propertyCounter++)
        {
            String dn = (String)result.Properties["memberOf"][propertyCounter];
            // The comma in the regex is important to prevent accidental matches
            if ( Regex.IsMatch( dn, @"cn="+groupname+",.*", RegexOptions.IgnoreCase)
              return true;
        }
    }
    catch (Exception ex)
    { // Some logging here probably
    }
    return false;
}

接下来,将其添加为您的btnlogin_Click代码:

<script runat=server>
void btnlogin_Click(Object sender, EventArgs e)
{
  String adPath = "LDAP://your.domain.com"; //Enter your domain name here
  LdapAuthentication adAuth = new LdapAuthentication(adPath);
  String myGroupName = "auth-group-name"; //Enter your group's name (cn) here
  try
  {
    if(true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text))
    {
      if( adAuth.isMember( myGroupName ) )
      {
          // User is authenticated and a member of the group. 
          // Create your auth ticket, cookie, and whatnot
      }
      else
      {
          errorLabel.Text = "Authorization failed. You are not a member of the "+myGroupName+" group";
      }
    }
    else
    {
      errorLabel.Text = "Authentication did not succeed. Check user name and password.";
    }
  }
  catch(Exception ex)
  {
    errorLabel.Text = "Error authenticating. " + ex.Message;
  }
}
</script>

这应该为您解决问题。 显然,您应该在isMember()检查之后创建一些代码,以创建一个安全cookie,该cookie允许其他页面检查用户的身份验证状态。

祝好运。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM