المصادقة والترخيص وإدارة المستخدم والأدوار والأمن العام في .NET

StackOverflow https://stackoverflow.com/questions/1222974

سؤال

أحتاج إلى معرفة كيفية تنفيذ الأمان العام لتطبيق C#.ما هي الخيارات المتاحة لي في هذا الصدد؟أفضّل استخدام إطار عمل موجود إذا كان يلبي احتياجاتي - لا أرغب في إعادة اختراع العجلة.

متطلباتي هي كما يلي:

  • مصادقة اسم المستخدم/كلمة المرور المعتادة
  • إدارة المستخدمين - تعيين الأذونات للمستخدمين
  • إدارة الأدوار - تعيين المستخدمين للأدوار، وتعيين الأذونات للأدوار
  • ترخيص المستخدمين بناءً على اسم المستخدم والدور الخاص بهم

أنا أبحث عن إطار عمل/مكتبة مجانية/مفتوحة المصدر تم اختبارها زمنيًا واستخدامها من قبل مجتمع .Net.

يأخذ تطبيقي نهج العميل/الخادم، حيث يعمل الخادم كخدمة Windows، ويتصل بقاعدة بيانات SQL Server.سيتم التواصل بين العميل والخادم من خلال WCF.

هناك شيء آخر مهم وهو أنني بحاجة إلى أن أكون قادرًا على تعيين مستخدمين محددين أو أذونات أدوار لعرض/تحديث/حذف كيان معين، سواء كان عميلاً أو منتجًا وما إلى ذلك.على سبيل المثال.يستطيع جاك عرض 3 عملاء معينين من أصل 10، لكنه يقوم فقط بتحديث تفاصيل عملاء Microsoft وYahoo وGoogle، ويمكنه حذف Yahoo فقط.

هل كانت مفيدة؟

المحلول

بالنسبة للأمان الدقيق، قد تجد الكود الأساسي المدمج مفيدًا؛يتم التحكم في كائن المستخدم (وأدواره) في .NET بواسطة "الرئيس"، ولكن من المفيد أن يتمكن وقت التشغيل نفسه من فرض ذلك.

يمكن أن يكون تنفيذ المبدأ محددًا بالتنفيذ، ويمكنك عادةً إدخال ما تريده بنفسك؛ على سبيل المثال في WCF.

لرؤية وقت التشغيل الذي يفرض الوصول الخشن (أيأيّ وظائف يمكن الوصول إليها، على سبيل المثال لا الحصر بيانات):

static class Roles {
    public const string Administrator = "ADMIN";
}
static class Program {
    static void Main() {
        Thread.CurrentPrincipal = new GenericPrincipal(
            new GenericIdentity("Fred"), new string[] { Roles.Administrator });
        DeleteDatabase(); // fine
        Thread.CurrentPrincipal = new GenericPrincipal(
            new GenericIdentity("Barney"), new string[] { });
        DeleteDatabase(); // boom
    }

    [PrincipalPermission(SecurityAction.Demand, Role = Roles.Administrator)]
    public static void DeleteDatabase()
    {
        Console.WriteLine(
            Thread.CurrentPrincipal.Identity.Name + " has deleted the database...");
    }
}

ومع ذلك، فإن هذا لا يساعد في الوصول إلى التفاصيل الدقيقة (أي.""يمكن لفريد الوصول إلى العميل "أ" ولكن ليس العميل "ب"").


إضافي؛بالطبع، بالنسبة للتفاصيل الدقيقة، يمكنك ببساطة التحقق من الأدوار المطلوبة في وقت التشغيل، عن طريق التحقق IsInRole على المبدأ:

static void EnforceRole(string role)
{
    if (string.IsNullOrEmpty(role)) { return; } // assume anon OK
    IPrincipal principal = Thread.CurrentPrincipal;
    if (principal == null || !principal.IsInRole(role))
    {
        throw new SecurityException("Access denied to role: " + role);
    }
}
public static User GetUser(string id)
{
    User user = Repository.GetUser(id);
    EnforceRole(user.AccessRole);
    return user;
}

يمكنك أيضًا كتابة كائنات الهوية/الرئيسية الخاصة بك والتي تقوم بإجراء اختبارات كسولة/التخزين المؤقت للأدوار، بدلاً من الاضطرار إلى معرفتها جميعًا مقدمًا:

class CustomPrincipal : IPrincipal, IIdentity
{
    private string cn;
    public CustomPrincipal(string cn)
    {
        if (string.IsNullOrEmpty(cn)) throw new ArgumentNullException("cn");
        this.cn = cn;
    }
    // perhaps not ideal, but serves as an example
    readonly Dictionary<string, bool> roleCache =
        new Dictionary<string, bool>();
    public override string ToString() { return cn; }
    bool IIdentity.IsAuthenticated { get { return true; } }
    string IIdentity.AuthenticationType { get { return "iris scan"; } }
    string IIdentity.Name { get { return cn; } }
    IIdentity IPrincipal.Identity { get { return this; } }

    bool IPrincipal.IsInRole(string role)
    {
        if (string.IsNullOrEmpty(role)) return true; // assume anon OK
        lock (roleCache)
        {
            bool value;
            if (!roleCache.TryGetValue(role, out value)) {
                value = RoleHasAccess(cn, role);
                roleCache.Add(role, value);
            }
            return value;
        }
    }
    private static bool RoleHasAccess(string cn, string role)
    {
        //TODO: talk to your own security store
    }
}

نصائح أخرى

تفحص موفري عضوية ASP.NET.لا أعتقد أن SQLMembershipProvider الجاهز سيعمل في حالتك ولكن من السهل تشغيل المزود الخاص بك.

ربما تعتمد إجابتي على إجابة هذا السؤال: هل هذا تطبيق مؤسسي موجود داخل شبكة بها Active Directory؟

إذا كانت الإجابة بنعم فهذه هي الخطوات التي سأقدمها:

1) قم بإنشاء مجموعات عامة لتطبيقك، في حالتي، كان لدي مجموعة APPUSER ومجموعة APPADMIN.

2) اجعل SQL Server الخاص بك قادرًا على الوصول إلى وضع المصادقة المختلطة، ثم قم بتعيين مجموعة (مجموعات) APPUSER الخاصة بك باعتبارها تسجيل دخول SQL SERVER إلى قاعدة البيانات الخاصة بك مع حقوق CRUD المناسبة لقاعدة (قواعد) البيانات الخاصة بك، وتأكد من وصولك خادم SQL مع اتصال موثوق = صحيح في سلسلة الاتصال الخاصة بك.

في هذه المرحلة، سيكون متجر AD الخاص بك مسؤولاً عن المصادقة.نظرًا لأنك تصل إلى التطبيق عبر اتصال موثوق به، فسوف يقوم بتمرير هوية أي حساب يقوم بتشغيل التطبيق إلى خادم SQL.

الآن، للترخيص (أي.إخبار التطبيق الخاص بك بما يُسمح للمستخدم الذي قام بتسجيل الدخول بفعله) إنها مسألة بسيطة تتمثل في الاستعلام عن قائمة المجموعات التي يكون المستخدم الذي قام بتسجيل الدخول عضوًا فيها.ثم تحقق من أسماء المجموعات المناسبة وقم ببناء واجهة المستخدم الخاصة بك بناءً على العضوية بهذه الطريقة.

الطريقة التي تعمل بها تطبيقاتي هي كالتالي:

  1. عند تشغيل التطبيق، تعتمد بيانات الاعتماد على المستخدم الذي قام بتسجيل الدخول، وهذا هو الجانب الأساسي للمصادقة (أي.يمكنهم تسجيل الدخول وبالتالي هم موجودون)
  2. أحصل على كافة المجموعات الخاصة بهوية Windows المعنية
  3. أتحقق من مجموعة المستخدمين القياسية - إذا لم تكن هذه المجموعة موجودة لهوية Windows المعنية، فهذا يعني فشل المصادقة
  4. أتحقق من مجموعة مستخدمي ADMIN - مع وجود هذه المجموعة في مجموعات المستخدمين، أقوم بتعديل واجهة المستخدم للسماح بالوصول إلى مكونات الإدارة
  5. عرض واجهة المستخدم

لدي بعد ذلك إما كائن PRINCIPLE مع الحقوق المحددة/إلخ عليه، أو أستخدم المتغيرات العالمية التي يمكنني الوصول إليها لتحديد واجهة المستخدم المناسبة أثناء إنشاء النماذج الخاصة بي (على سبيل المثال.إذا لم يكن المستخدم الخاص بي عضوًا في مجموعة ADMIN، فسأقوم بإخفاء جميع أزرار الحذف).

لماذا أقترح هذا؟

إنها مسألة نشر.

لقد كانت تجربتي أن معظم تطبيقات المؤسسات يتم نشرها بواسطة مهندسي الشبكات بدلاً من المبرمجين - وبالتالي، فإن جعل المصادقة/الترخيص مسؤولية AD أمر منطقي، حيث أن هذا هو المكان الذي يذهب إليه رجال الشبكة عندما تناقش المصادقة/الترخيص.

بالإضافة إلى ذلك، أثناء إنشاء مستخدمين جدد للشبكة، يكون مهندس الشبكة (أو أي شخص مسؤول عن إنشاء مستخدمين جدد للشبكة) أكثر ملاءمة لتذكر أداء مهام المجموعة أثناء وجودهم في AD بدلاً من حقيقة أنه يتعين عليهم الدخول في عشرات التطبيقات لتحليل مهام الترخيص.

يساعد القيام بذلك في متاهة الأذونات والحقوق التي يجب منحها للموظفين الجدد أو رفض أولئك الذين يغادرون الشركة ويحافظ على المصادقة والترخيص في المستودع المركزي الذي ينتمي إليه (على سبيل المثال.في م @ مستوى وحدة تحكم المجال).

أود أن ألقي نظرة على شيء مثل CSLA.net: خبير C # 2008 كائنات الأعمال

يجب أن توفر كل ما تحتاجه.

تتمتع WCF بوظائف غنية متعلقة بالأمان توفر كلاً من التفويض والمصادقة.في التفاصيل هنا:http://msdn.microsoft.com/en-us/library/ms735093.aspx

أعتقد أنك تنظر إلى بعض المشكلات المنفصلة هنا - وليس من قبيل المصادفة أن معظم أنظمة الأمان تفصل بين المصادقة والترخيص.

بالنسبة للمصادقة، السؤال الأكبر هو لوجستي.أو، هل هناك مكان منطقي ليعيش فيه هؤلاء المستخدمون، سواء كان ذلك محليًا في التطبيق، أو في Active Directory، أو في بعض متاجر LDAP الأخرى، أو حتى في بعض التطبيقات الأخرى.المكان المحدد غير مهم إلى حد كبير - نحتاج فقط إلى أن نكون قادرين على تحديد المستخدمين بشكل ثابت ويفضل أن نجعل هذه المهمة مشكلة لشخص آخر.في نهاية اليوم، كل ما تحتاج إليه هو معرف فريد والراحة التي يشعر بها بوب من المحاسبة وهو في الواقع بوب من المحاسبة.

التفويض هو الجزء الأكثر إثارة للاهتمام من المشكلة هنا.أعتقد أنه إذا كان الأمر دقيقًا حقًا، فأنت تريد حقًا إدارة هذا بالكامل داخل تطبيقك، بغض النظر عن المكان الذي يأتي منه المستخدمون.لقد توصل مارك جرافيل حقًا إلى طريقة جيدة لنمذجة بعض من هذا على الأقل - يعد استخدام بعض التطبيقات المخصصة لـ IPrincipal وPrincipalPermission لإدارة الأشياء طريقة نظيفة جدًا للبدء.أبعد من ذلك يمكنك استخدام تقنيات مثل هذا لاتخاذ قرارات ترخيص أكثر تعقيدًا بطريقة نظيفة إلى حد ما.

سأستخدم المصطلح - "RBAC" (نظام التحكم في الوصول القائم على الدور) كحل لجميع متطلباتك.

لن أخوض في الكثير من التفاصيل لشرح "RBAC" هنا، بل سأصفها بإيجاز على النحو التالي:

يحتوي بشكل أساسي على 3 ميزات.

1) المصادقة - تؤكد هوية المستخدم.عادةً ما يتم ذلك عبر حسابات المستخدمين وكلمات المرور أو بيانات الاعتماد.

2) التفويض - يحدد ما يمكن للمستخدم فعله وما لا يمكنه فعله في التطبيق.السابق."تعديل الطلب" مسموح به ولكن "إنشاء طلب جديد" غير مسموح به.

3) تدقيق إجراءات المستخدم على التطبيقات.- يتتبع تصرفات المستخدم على التطبيقات، وكذلك من منح حق الوصول لأي مستخدم؟

يمكنك التحقق من RBAC على الويكي هنا.

https://en.wikipedia.org/wiki/Role-based_access_control

الآن، فيما يتعلق بالإجابة على متطلباتك - أحد الحلول الممكنة هو تمديد عضوية ASP.NET وفقًا لاحتياجاتك.

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

يمكنك أيضًا مراجعة هذه المقالة للحصول على مزيد من الفهم حول نظام الأذونات والأدوار.

http://www.visual-guard.com/EN/net-powerbuilder-application-security-authentication-permission-access-control-rbac-articles/dotnet-security-article-ressources/role-based-access-control- source_soforum.html

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top