ต้องการใช้บัญชีบริการเพื่อเชื่อมต่อกับ AD ที่แอปของฉันทำงานอยู่

ในแอปพลิเคชัน MVC-5 ของฉัน ฉันกำลังเพิ่ม/แก้ไขผู้ใช้ใน Active Directory ผ่านแอปพลิเคชันของฉัน เมื่อใดก็ตามที่ฉันทำการเปลี่ยนแปลงใน AD ทุกครั้งที่ฉันต้องส่ง ldapUserName(Admin) และ ldapPassword(pass@123) เพื่อเชื่อมต่อกับ Active Directory จากนั้นมีเพียงฉันเท่านั้นที่สามารถดำเนินการใน AD ได้ แทนที่จะส่งข้อมูลประจำตัวแต่ละครั้ง ฉันต้องการใช้บัญชีบริการ (โดเมน\บริการ_บัญชี) ที่แอปพลิเคชันของฉันทำงานอยู่เพื่อเชื่อมต่อกับ AD จะบรรลุสิ่งนั้นได้อย่างไร ??


person Kapil Kumar    schedule 17.10.2016    source แหล่งที่มา
comment
ขอบคุณล่วงหน้า !   -  person Kapil Kumar    schedule 17.10.2016
comment
คุณเชื่อมต่อกับ AD ยังไง   -  person lordkain    schedule 17.10.2016
comment
คุณได้ลองตั้งค่าบัญชีกลุ่มแอพเป็นบัญชีผู้ดูแลระบบ AD แล้วหรือยัง? คุณอาจต้องให้สิทธิ์โฟลเดอร์ add'l สำหรับบัญชีนี้เพื่อเข้าถึงโฟลเดอร์ของไซต์   -  person Stinky Towel    schedule 17.10.2016
comment
ลอง { โดยใช้ (var directoryEntry = new DirectoryEntry(ldabPath, ldapUserName, ldapPassword)) { โดยใช้ (var newUser = directoryEntry.Children.Add(CN= + userViewModel.UserName, User)) { newUser.CommitChanges(); newUser.Inrigg (ชุดรหัสผ่าน, userViewModel.Password); newUser.Properties[userAccountControl].Value = 0x0200; newUser.CommitChanges(); } }   -  person Kapil Kumar    schedule 17.10.2016
comment
มีการใช้โค้ดด้านบนเพื่อเพิ่มผู้ใช้ใน AD แทนที่จะส่งข้อมูลรับรอง ฉันต้องการใช้บัญชีบริการ ฉันต้องการเข้าถึง AD อย่างราบรื่นโดยใช้บัญชีบริการ   -  person Kapil Kumar    schedule 17.10.2016
comment
ลองดูสิ่งนี้ด้วย: stackoverflow.com/a/37565248/2779990   -  person Stinky Towel    schedule 17.10.2016
comment
ฉันตรวจสอบแล้ว แต่ไม่พบคำตอบของฉัน โดยไม่ต้องใช้ข้อมูลประจำตัว คุณสามารถเชื่อมต่อกับ AD ได้อย่างไร   -  person Kapil Kumar    schedule 18.10.2016


คำตอบ (2)


เพียงสร้าง DirectoryEntry โดย new DirectoryEntry(ldabPath, null, null) จะใช้ข้อมูลประจำตัวของผู้ใช้ปัจจุบัน (บัญชีบริการในกรณีบริการ Windows) คีย์กำลังส่ง null ไปยังทั้งชื่อผู้ใช้และรหัสผ่าน

นั่นคือสิ่งที่คุณต้องการ?

เพียงตรวจสอบให้แน่ใจว่าบัญชีบริการมีสิทธิ์เพียงพอที่จะตั้งรหัสผ่านสำหรับผู้ใช้ทั้งหมดที่เกี่ยวข้อง

person baldpate    schedule 18.10.2016

คุณสามารถเลือกหนึ่งใน 2 ตัวเลือก

ตัวเลือกที่ 1. คุณเรียกใช้แอปพลิเคชันของคุณบนคอมพิวเตอร์ที่เข้าร่วมกับโดเมนที่คุณเพิ่ม\ลบผู้ใช้ออก ในกรณีนี้ วิธีแก้ไขที่ง่ายที่สุดคือการเรียกใช้แอปพลิเคชันของคุณ (กลุ่มแอปพลิเคชัน) ภายใต้บัญชีโดเมนที่มีสิทธิ์เพียงพอ (ด้วยวิธีง่ายๆ อาจเป็นบัญชีที่อยู่ในกลุ่มผู้ดูแลระบบโดเมน จะเป็นผู้ดูแลระบบบนโฮสต์ที่แอปพลิเคชันทำงานด้วย)

ตัวเลือกที่ 2 คุณเรียกใช้แอปพลิเคชันของคุณบนคอมพิวเตอร์แบบสแตนด์อโลนที่ไม่ได้เข้าร่วมกับโดเมน ในกรณีนี้ คุณสามารถเลือกอย่างใดอย่างหนึ่งต่อไปนี้:

A. เลียนแบบเธรดของคุณเพื่อทำหน้าที่เป็นบัญชีโดเมนเมื่อทำการเชื่อมต่อเครือข่ายทั้งหมด คุณต้องใช้ LogonUser ฟังก์ชั่นพร้อมแฟล็ก LOGON32_LOGON_NEW_CREDENTIALS ข้อเสียเปรียบของวิธีนี้คือการเชื่อมต่อเครือข่ายทั้งหมด (เช่น คุณเชื่อมต่อกับเครือข่ายที่ใช้ร่วมกัน) จะทำภายใต้บัญชีโดเมน หากต้องการรายละเอียดเพิ่มเติมเกี่ยวกับการนำไปใช้ โปรดดูโพสต์นี้

B. สร้างตัวจัดการการเชื่อมต่อซึ่งจะสร้าง DirectoryEntry ให้กับคุณด้วยข้อมูลประจำตัวที่จำเป็น ดูรหัสด้านล่าง:

public interface IDirectoryEntryManager
{
    DirectoryEntry GetDirectoryEntry(string domain, string baseDn);
}

public interface ICredentialProvider
{
    Credential GetCredential(string domain);
}

public class Credential
{
    public string UserName { get; set; }
    public string Password { get; set; }
}

public class DirectoryEntryManager : IDirectoryEntryManager, IDisposable
{
    private class DomainConnectionInfo
    {
        internal DomainConnectionInfo(string server, Credential credential)
        {
            Server = server;
            Credential = credential;
        }

        internal string Server { get; private set; }
        internal Credential Credential { get; private set; }
    }

    private bool disposed;
    ICredentialProvider _credentialProvider;
    Dictionary<string, DomainConnectionInfo> connectionsInfo = new Dictionary<string, DomainConnectionInfo>(StringComparer.OrdinalIgnoreCase);
    Dictionary<string, DirectoryEntry> connections = new Dictionary<string, DirectoryEntry>(StringComparer.OrdinalIgnoreCase);

    public DirectoryEntryManager(ICredentialProvider credentialProvider)
    {
        _credentialProvider = credentialProvider;
    }

    public DirectoryEntry GetDirectoryEntry(string domain, string baseDn)
    {
        if (disposed)
        {
            throw new ObjectDisposedException(this.GetType().Name);
        }

        return GetOrCreateConnection(domain, baseDn);
    }

    public void Dispose()
    {
        if (!disposed)
        {
            foreach (var connection in connections)
            {
                connection.Value.Dispose();
            }

            connections.Clear();
            disposed = true;
        }
    }

    private DirectoryEntry GetOrCreateConnection(string domain, string baseDn)
    {
        DomainConnectionInfo info;

        if (!connectionsInfo.TryGetValue(domain, out info))
        {
            var credential = _credentialProvider.GetCredential(domain);
            var dc = DomainController.FindOne(new DirectoryContext(DirectoryContextType.Domain, credential.UserName, credential.Password));
            info = new DomainConnectionInfo(dc.Name, credential);

            // maintaining a connection to rootDse object to make all LDAP queries use this single connection under the hood. Increasing performance
            var entry = new DirectoryEntry(string.Format("LDAP://{0}/RootDSE", dc.Name));
            entry.RefreshCache();

            connections.Add(domain, entry);
            connectionsInfo.Add(domain, info);
        }

        return new DirectoryEntry(string.Format("LDAP://{0}/{1}", info.Server, baseDn), info.Credential.UserName, info.Credential.Password);
    }
}

ไม่ได้ทดสอบรหัส ใช้การผูกเซิร์ฟเวอร์แทนการผูกแบบไร้เซิร์ฟเวอร์ (เช่น LDAP://domain.com) จะดีกว่าในกรณีที่คุณสร้างผู้ใช้ในส่วนหนึ่งของโปรแกรมและพยายามเข้าถึงในส่วนอื่น การใช้ Serverless Bind ทำให้คุณสามารถเชื่อมต่อกับ DC ต่างๆ ได้ ดังนั้นผู้ใช้ที่คุณพยายามเข้าถึงอาจไม่ถูกจำลองแบบไปยัง DC ตัวที่ 2

โปรดทราบว่าตัวควบคุมโดเมนอาจไม่พร้อมใช้งาน ดังนั้นคุณต้องใช้ตรรกะเพื่อค้นหา DC อื่นและรีเฟรชแคชการเชื่อมต่อของคุณหากจำเป็น

คุณสามารถจัดเก็บข้อมูลประจำตัวในไฟล์\LSA ที่อาจเข้ารหัส และทำให้คลาส DirectoryEntryManager เป็นซิงเกิลตัน

person oldovets    schedule 17.10.2016
comment
คุณช่วยอธิบายรายละเอียดได้ไหม? - person Kapil Kumar; 18.10.2016
comment
@Kapil Kumar: สร้างคำตอบโดยละเอียด ยินดีต้อนรับ - person oldovets; 19.10.2016