我使用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;
}
}
它必须在Get groups功能中,但我不知道如何通过我正在寻找的组。如果有人可以提供帮助,那将非常感激。提前谢谢。
这是我的按钮点击事件:
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;
}
}
答案 0 :(得分:0)
我也遇到了这个问题。我使用与进行AD身份验证几乎相同的类。我使用不同的方式连接到AD,但有一些奇怪的问题。在我更改为此代码之前,我实现了角色提供程序,并且我仍然使用该角色提供程序来拒绝和授予访问权限。这就是我基本上做到的。 Follow this link因为它可以帮助您设置角色。
我唯一改变的是“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>
所以我拒绝所有人访问除了AD组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的链接可能是你最好的选择。
答案 1 :(得分:0)
您想检查用户是否是正确群组的成员,对吗? 为什么不创建一个接受组名并返回布尔值的函数,如下所示:
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;
}
祝你好运!
答案 2 :(得分:0)
好的,在你的评论之后,这是你应该做的:
在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。