كيفية مصادقة مقابل "Active Directory" باستخدام مصادقة النماذج و Visual C#.NET

تشير هذه المقالة إلى مكتبة فئات Microsoft.NET Framework مساحات الأسماء التالية:
  • System.Text
  • System.DirectoryServices
  • System.Security.Principal
  • System.Web.Security

ملخص

توضح هذه المقالة خطوة بخطوة كيفية استخدام أحد تطبيقات ASP.NET مصادقة النماذج للسماح للمستخدمين بالمصادقة مقابل "Active Directory" باستخدام بروتوكول الوصول الخفيف لتغيير بيانات الدليل (LDAP). بعد مصادقة المستخدم وإعادة توجيهها، يمكنك استخدام أسلوب Application_AuthenticateRequest لملف Global.asax لتخزين كائن GenericPrincipal في HttpContext.User الخاصية تنساب خلال الطلب.

إنشاء تطبيق ويب ASP.NET في Visual C#.NET

اتبع الخطوات لإنشاء تطبيق ويب ASP.NET جديد يسمى فورمسوثاد في Visual C#.NET التالية:
  1. Microsoft Visual Studio.NET.بدء تشغيل
  2. من القائمة ملف، أشر إلى جديد ثم انقر فوق المشروع.
  3. انقر فوق مشاريع Visual C# ضمن أنواع المشروعومن ثم انقر فوق تطبيق ويب ASP.NET ضمن قوالب.
  4. في المربع الموقع ، استبدال webapplication1 برمجياً باستخدام فورمسوثاد.
  5. انقر فوق موافق.
  6. زر الماوس الأيمن فوق العقدة المراجع في "مستكشف الحلول" ومن ثم انقر فوق إضافة مرجع.
  7. ضمن علامة التبويب .NET في مربع الحوار إضافة المرجع ، انقر فوق System.DirectoryServices.dllانقر فوق تحديدومن ثم انقر فوق موافق.

كتابة رمز المصادقة

اتبع هذه الخطوات لإنشاء ملف فئة جديد يسمى LdapAuthentication.cs:
  1. في "مستكشف الحلول"، انقر نقراً مزدوجاً فوق عقده المشروع أشر إلى إضافةوثم انقر فوق إضافة عنصر جديد.
  2. انقر فوق فئة ضمن قوالب.
  3. اكتب LdapAuthentication.cs في مربع الاسم ، ومن ثم انقر فوق فتح.
  4. استبدال التعليمات البرمجية الموجودة في الملف LdapAuthentication.cs باستخدام التعليمات البرمجية التالية.
    using System;using System.Text;
    using System.Collections;
    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);
    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();
    }
    }
    }

يقبل رمز مصادقة مجال واسم مستخدم، وكلمة مرور ومسار إلى الشجرة في "Active Directory". يستخدم هذا الرمز الموفر دليل LDAP.

التعليمات البرمجية في الصفحة Logon.aspx استدعاء الأسلوب LdapAuthentication.IsAuthenticated ويقوم بتمرير بيانات اعتماد التي تم تجميعها من المستخدم. ثم يتم إنشاء كائن DirectoryEntry المسار إلى شجرة الدليل واسم المستخدم وكلمة المرور. يجب أن يكون اسم المستخدم في تنسيق "المجال/اسم المستخدم". ثم يحاول كائن DirectoryEntry فرض ربط أدسوبجيكت عن طريق الحصول على خاصية ناتيفيوبجيكت . في حال نجاح ذلك، يتم الحصول على سمة CN للمستخدم عن طريق إنشاء كائن ديريكتوريسيرتشير والتصفية على SAMAccountName. بعد أن تتم المصادقة على المستخدم، إيسوثينتيكاتيد الأسلوب بإرجاع true.

للحصول على قائمة بالمجموعات التي ينتمي إليها المستخدم، هذه التعليمات البرمجية باستدعاء الأسلوب LdapAuthentication.GetGroups . أسلوب LdapAuthentication.GetGroups تحصل على قائمة بمجموعات الأمان والتوزيع التي ينتمي إليها المستخدم عن طريق إنشاء كائن ديريكتوريسيرتشير والتصفية حسب السمة عضو . هذا الأسلوب بإرجاع قائمة مجموعات مفصولة بتوجيهات الإخراج (|).

لاحظ أن الأسلوب LdapAuthentication.GetGroups تعالج واقتطاع سلاسل. وهذا يقلل طول السلسلة التي يتم تخزينها في ملف تعريف ارتباط المصادقة. إذا لم يتم اقتطاع السلسلة، تنسيق كل مجموعة تظهر كما يلي.
CN=...,...,DC=domain,DC=com
يؤدي هذا إلى إنشاء سلسلة طويلة جداً. إذا كان طول هذه السلسلة أكبر من طول ملف تعريف الارتباط، قد لا يقبل المستعرضات ملف تعريف ارتباط المصادقة، وتتم إعادة توجيهك إلى صفحة تسجيل الدخول. ومع ذلك، إذا كنت تعمل في بيئة متعددة المجالات، قد تضطر للحفاظ على اسم المجال باسم المجموعة للمجموعات في مجالات مختلفة يمكن أن يكون نفس اسم المجموعة. يجب عليك الاحتفاظ باسم المجال للتفرقة بين مجموعة واحدة من آخر.

معظم المستعرضات تدعم ملفات تعريف الارتباط هو 4096 بايت. هذه السلسلة قد المحتمل أن يتجاوز طول ملف تعريف الارتباط، قد تحتاج إلى تخزين معلومات المجموعة في كائن ذاكرة التخزين المؤقت في ASP.NET أو في قاعدة بيانات. بدلاً من ذلك، قد تحتاج إلى تشفير المعلومات المجموعة وتخزين هذه المعلومات في حقل نموذج مخفي.

كتابة التعليمات البرمجية Global.asax

التعليمات البرمجية في ملف Global.asax يوفر معالج حدث Application_AuthenticateRequest . معالج الحدث هذا استرداد ملف تعريف ارتباط المصادقة من مجموعة Context.Request.Cookies ويقوم بفك تشفير ملف تعريف الارتباط واسترداد قائمة الجماعات التي سيتم تخزينها في الخاصية FormsAuthenticationTicket.UserData . تظهر المجموعات في قائمة مفصولة بتوجيه الإخراج الذي تم إنشاؤه في الصفحة Logon.aspx.

الرمز يفسر السلسلة في صفيف سلسلة لإنشاء كائن GenericPrincipal . بعد إنشاء الكائن GenericPrincipal ، يتم وضع هذا الكائن في خاصية HttpContext.User .
  1. في "مستكشف الحلول"، انقر بالزر الأيمن Global.asax، وثم انقر فوق عرض التعليمات البرمجية.
  2. أضف التعليمات البرمجية التالية في الجزء العلوي من الملف Global.asax.cs التعليمات البرمجية الخلفية:
    using System.Web.Security;using System.Security.Principal;

  3. استبدال معالج حدث فارغ موجود ل Application_AuthenticateRequest مع التعليمات البرمجية التالية.
    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;

    }

تعديل ملف Web.config

في هذا القسم، يمكنك تكوين < النماذج > < المصادقة >والعناصر < الترخيص > في ملف Web.config. وبهذه التغييرات، يمكن المستخدمين المصادق عليهم فقط من الوصول إلى التطبيق، وتتم إعادة توجيه طلبات غير مصادقة إلى صفحة Logon.aspx. يمكنك تعديل هذا التكوين للسماح لبعض المستخدمين والمجموعات في الوصول إلى التطبيق فقط.

استبدال التعليمات البرمجية الموجودة في الملف Web.config باستخدام التعليمات البرمجية التالية.
<?xml version="1.0" encoding="utf-8" ?><configuration>    
<system.web>
<authentication mode="Forms">
<forms loginUrl="logon.aspx" name="adAuthCookie" timeout="10" path="/" >
</forms>
</authentication>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
<identity impersonate="true" />
</system.web>
</configuration>

لاحظ < انتحال هوية = "true"/> عنصر التكوين. يؤدي ASP.NET لانتحال الحساب الذي تم تكوينه كحساب مجهول من خدمات معلومات إنترنت (IIS) ل Microsoft. نتيجة هذا التكوين، تشغيل كافة طلبات إلى هذا التطبيق ضمن سياق الأمان للحساب الذي تم تكوينه. المستخدم توفير بيانات الاعتماد لمصادقة مقابل "Active Directory"، ولكن حساب يمكنه الوصول إلى Active Directory هو الحساب الذي تم تكوينه. لمزيد من المعلومات، راجع قسم المراجع .

تكوين IIS للمصادقة المجهولة

لتكوين IIS للمصادقة المجهولة، اتبع الخطوات التالية:
  1. في IIS، قم بتوسيع عقده الكمبيوتر الملقم توسيع مواقع ويب، قم بتوسيع موقع ويب الافتراضي، انقر نقراً مزدوجاً فوق فورمسوثادوثم انقر فوق خصائص.
  2. انقر فوق علامة التبويب أمان الدليلومن ثم انقر فوق تحرير ضمن التحكم المصادقة والوصول المجهول.
  3. إجراء الحساب المجهول للتطبيق حساب له إذن الوصول إلى Active Directory.
  4. انقر لإلغاء تحديد خانة الاختيار "السماح IIS إلى كلمة مرور التحكم".
  5. في المقطع "مصادقة الوصول"، قم بإلغاء تحديد خانة الاختيار "مصادقة Windows المتكاملة".
  6. انقر فوق موافق.
  7. انقر فوق تطبيق
الحساب الافتراضي IUSR_computername ليس لديه الإذن "خدمة active Directory".

إنشاء صفحة Logon.aspx

اتبع هذه الخطوات لإنشاء نموذج ويب ASP.NET جديد اسم Logon.aspx:
  1. في "مستكشف الحلول"، انقر نقراً مزدوجاً فوق عقده المشروع أشر إلى إضافةوثم انقر فوق إضافة نموذج ويب.
  2. اكتب Logon.aspx في المربع الاسم ، ومن ثم انقر فوق فتح.
  3. في "مستكشف الحلول"، انقر بالزر الأيمن Logon.aspx، وثم انقر فوق عرض المصمم.
  4. انقر فوق علامة تبويب HTML في المصمم.
  5. استبدال التعليمات البرمجية الموجودة بالتعليمة البرمجية التالية.
    <%@ Page language="c#" AutoEventWireup="true" %><%@ Import Namespace="FormsAuth" %>
    <html>
    <body>
    <form id="Login" method="post" runat="server">
    <asp:Label ID="Label1" Runat=server >Domain:</asp:Label>
    <asp:TextBox ID="txtDomain" Runat=server ></asp:TextBox><br>
    <asp:Label ID="Label2" Runat=server >Username:</asp:Label>
    <asp:TextBox ID=txtUsername Runat=server ></asp:TextBox><br>
    <asp:Label ID="Label3" Runat=server >Password:</asp:Label>
    <asp:TextBox ID="txtPassword" Runat=server TextMode=Password></asp:TextBox><br>
    <asp:Button ID="btnLogin" Runat=server Text="Login" OnClick="Login_Click"></asp:Button><br>
    <asp:Label ID="errorLabel" Runat=server ForeColor=#ff3300></asp:Label><br>
    <asp:CheckBox ID=chkPersist Runat=server Text="Persist Cookie" />
    </form>
    </body>
    </html>
    <script runat=server>
    void Login_Click(Object sender, EventArgs e)
    {
    String adPath = "LDAP://corp.com"; //Fully-qualified Domain Name
    LdapAuthentication adAuth = new LdapAuthentication(adPath);
    try
    {
    if(true == adAuth.IsAuthenticated(txtDomain.Text, 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));
    }
    else
    {
    errorLabel.Text = "Authentication did not succeed. Check user name and password.";
    }
    }
    catch(Exception ex)
    {
    errorLabel.Text = "Error authenticating. " + ex.Message;
    }
    }
    </script>
  6. قم بتعديل المسار في الصفحة Logon.aspx للإشارة إلى ملقم دليل LDAP.
الصفحة Logon.aspx هي صفحة بتجميع المعلومات من المستخدم واستدعاء الأساليب في الفئة لدابوثينتيكيشن . بعد الرمز مصادقة المستخدم ويحصل على قائمة المجموعات، التعليمات البرمجية يقوم بإنشاء كائن فورمسوثينتيكاتيونتيكيت تشفير التذكرة، يضيف تذكرة مشفرة إلى ملف تعريف ارتباط، إضافة ملف تعريف الارتباط إلى مجموعة HttpResponse.Cookies وقم بإعادة توجيه الطلب إلى URL المطلوب أصلاً.

تعديل الصفحة WebForm1.aspx

الصفحة WebForm1.aspx هي الصفحة التي يتم طلبها بالأصل. عند قيام المستخدم بطلب هذه الصفحة، يتم توجيه الطلب إلى صفحة Logon.aspx. بعد أن تتم المصادقة على الطلب، يتم توجيه الطلب إلى الصفحة WebForm1.aspx.
  1. في "مستكشف الحلول"، انقر بالزر الأيمن WebForm1.aspx، وثم انقر فوق عرض المصمم.
  2. انقر فوق علامة تبويب HTML في المصمم.
  3. استبدال التعليمات البرمجية الموجودة بالتعليمة البرمجية التالية.
    <%@ Page language="c#" AutoEventWireup="true" %><%@ Import Namespace="System.Security.Principal" %>
    <html>
    <body>
    <form id="Form1" method="post" runat="server">
    <asp:Label ID="lblName" Runat=server /><br>
    <asp:Label ID="lblAuthType" Runat=server />
    </form>
    </body>
    </html>
    <script runat=server>
    void Page_Load(Object sender, EventArgs e)
    {
    lblName.Text = "Hello " + Context.User.Identity.Name + ".";
    lblAuthType.Text = "You were authenticated using " + Context.User.Identity.AuthenticationType + ".";
    }
    </script>

  4. حفظ كافة الملفات ومن ثم ترجمة المشروع.
  5. طلب الصفحة WebForm1.aspx. لاحظ أنه يتم توجيهك إلى Logon.aspx.
  6. اكتب بيانات اعتماد تسجيل الدخول ومن ثم انقر فوق إرسال. عندما تتم إعادة توجيهك إلى الصفحة WebForm1.aspx، لاحظ أن يظهر اسم المستخدم الخاص بك وأن لدابوثينتيكيشن المصادقة اكتب الخاصية Context.User.AuthenticationType .
ملاحظة: توصي Microsoft باستخدام تشفير طبقة مأخذ التوصيل الآمنة (SSL) عند استخدام مصادقة النماذج. وهذا لأنه يتم تعريف المستخدم استناداً إلى ملف تعريف ارتباط مصادقة وتشفير SSL على تطبيق هذا يمنع أي شخص من تسوية ملف تعريف ارتباط المصادقة وقيمة المعلومات الأخرى التي يتم نقلها.

المراجع

لمزيد من المعلومات، انقر فوق أرقام المقالات التالية لعرضها في "قاعدة معارف Microsoft":

نظرة عامة حول أمان ASP.NET 306590

هوية العملية وطلب 317012 في ASP.NET

كيفية تطبيق الأمان المستند إلى الدور باستخدام المصادقة المستندة إلى النماذج في تطبيق ASP.NET الخاص بك باستخدام Visual C#.NET 311495

313091 كيفية إنشاء المفاتيح باستخدام Visual Basic.NET لاستخدامه في مصادقة النماذج

313116 طلبات مصادقة النماذج غير موجهة إلى صفحة loginUrl

خصائص

رقم الموضوع: 316748 - آخر مراجعة: 09‏/01‏/2017 - المراجعة: 1

تعليقات