【发布时间】:2015-02-20 20:53:41
【问题描述】:
我正在研究Web Services,它根据Active Directory 对用户进行身份验证。我目前的解决方案是有效的,但是,我正在尝试采用不同的方法。
我有一个位于防火墙后面的Active Directory(生产)。我还在DMZ 中安装了Active Directory。它们之间存在一种单向关系。 DMZ 信任生产,而生产并不关心DMZ。
我想要完成的是通过DMZ Active Directory 对每个人进行身份验证。目前,根据用户名,我知道要针对哪个 AD 服务器进行身份验证。
例如,我的生产 Active Directory(比如说域 domain.local)和我的 DMZ Active Directory(比如说域 domain.public)。在对任何 AD 服务器进行身份验证之前,我会检查提供的用户名是否存在于其中一台服务器中。然后,我检查用户是否处于活动状态,然后才进行身份验证。 (我在第一个函数中遇到问题。它永远不会到达第二个或第三个函数)。
更新:添加了所有内容:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.DirectoryServices;
using System.Security.Principal;
using System.DirectoryServices.AccountManagement;
namespace ActiveDirectory
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
public class Service1 : IService1
{
#region Does User Exist in AD
public string local = string.Empty;
public string ldappath = string.Empty;
public string userNameToUse = string.Empty;
public string domain = string.Empty;
public bool DoesUserExist(string userName)
{
string _userName = userName;
bool exist = true;
using (var domainContext = new PrincipalContext(ContextType.Domain, domain))
{
using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userNameToUse))
{
if (foundUser == null)
{
exist = false;
}
else
{
return exist;
}
}
}
return exist;
}
#endregion
#region Check if User Active
public bool isActive (string userName)
{
string _userNameToBeSearched = userNameToUse;
string _username = string.Empty;
string _pwd = string.Empty;
if (local == "YES")
{
_username = "xx";
_pwd = "xx";
ldappath = "LDAP://xxx/DC=xx, DC=local";
}
else
{
_username = "xx";
_pwd = "xx";
ldappath = "LDAP://xxx/DC=xx, DC=public";
}
bool isActive = true;
try
{
DirectoryEntry entry = new DirectoryEntry(ldappath, _username, _pwd);
DirectorySearcher search = new DirectorySearcher(entry);
entry.AuthenticationType = AuthenticationTypes.Secure;
search.SearchRoot = entry;
search.Filter = "(SAMAccountName=" + _userNameToBeSearched + ")";
SearchResult results = search.FindOne();
if (results.ToString() != "")
{
int flags = Convert.ToInt32(results.Properties["userAccountControl"][0].ToString());
//CHECK IF THE ACCOUNT IS DISABLED
if (flags == 66050)
{
isActive = false;
}
}
}
catch (DirectoryServicesCOMException ex)
{
ex.ToString();
}
return isActive;
}
#endregion
#region Is user authenticated
public string isAuthenticated (string userName, string pwd)
{
string _userName, _pwd, message;
_userName = userName;
_pwd = pwd;
char[] splitchar = { '@' };
string[] strSplit = _userName.Split(splitchar);
string z = strSplit[0];
if (strSplit.Length == 2)
{
domain = "x.public";
userNameToUse = z.ToString();
local = "NO";
}
else
{
domain = "x.local";
userNameToUse = z.ToString();
local = "YES";
}
if (DoesUserExist (userNameToUse) == true)
{
if (isActive(userNameToUse) == true)
{
try
{
DirectoryEntry entry = new DirectoryEntry(ldappath, userNameToUse, _pwd);
object nativeObject = entry.NativeObject;
var GUIDID = "";
using (var domainContext = new PrincipalContext(ContextType.Domain, domain))
{
using (var user = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userNameToUse))
{
if (user != null)
{
GUIDID = user.Guid.ToString();
}
}
message = "Successfully authenticated:" + GUIDID;
}
}
catch (DirectoryServicesCOMException)
{
message = "Invalid password.";
}
}
else
{
message = "Account is disabled";
}
}
else
{
message = "There's an issue with your account.";
}
return message;
}
#endregion
}
}
如果DMZ AD 中存在用户名,则返回 true,否则返回 false。但是,将有一些用户只存在于生产 AD 中,但在 DMZ 中没有任何条目。因为,我建立了一种方式,相信我应该能够做到这一点:
username@domain.local 用于生产,username@domain.public 但是,即使我指定了完整的用户名,如果 DMZ AD 中不存在条目,它也会返回 null,尽管它存在于生产 AD 中。
任何建议,关于我如何通过DMZ AD 使用对生产广告具有完全权限的 web 服务帐户对每个人进行身份验证?
注意如果需要我可以提供其余的代码...*
谢谢
【问题讨论】:
-
上面的程序是用哪个用户来运行的?您必须使用生产 AD 的凭据才能访问这两个 AD。
userName的格式和domain的内容是什么? -
是每个用户。我在两个 AD 中都有服务帐户。典型的用户名是
sjohns,将针对生产环境进行验证,sjohns@mail.com将针对 DMZ 进行验证。 -
如果@codingChris 的回答不符合您的需要,请提供其余代码。上述方法只取1个参数
userName。我仍然不太明白domain和userNameToUse的价值从何而来...... -
@baldpate,感谢您的回复。我添加了所有代码。从应用程序调用函数
isAuthenticated。如果您有任何问题,请告诉我。
标签: c# web-services active-directory