سؤال

أقوم بتنفيذ خدمة WCF آمنة.تتم المصادقة باستخدام اسم المستخدم / كلمة المرور أو بيانات اعتماد Windows.تتم استضافة الخدمة في عملية خدمة Windows.الآن، أحاول معرفة أفضل طريقة للتنفيذ تفويض لكل عملية خدمة.

على سبيل المثال، فكر في الطريقة التالية:

public EntityInfo GetEntityInfo(string entityId);

كما تعلم، يوجد في WCF كائن OperationContext يمكنك من خلاله استرداد بيانات اعتماد الأمان التي تم تمريرها بواسطة المتصل/العميل.الآن،المصادقة سيكون قد انتهى بالفعل بحلول الوقت الذي يتم فيه استدعاء السطر الأول في الطريقة.ولكن كيف يمكننا تنفيذ الترخيص إذا كان القرار يعتمد على البيانات المدخلة نفسها؟على سبيل المثال، في الحالة المذكورة أعلاه، لنفترض أن المستخدمين "المسؤولين" (الذين يتم تخزين أذوناتهم وما إلى ذلك في قاعدة بيانات)، يُسمح لهم بالحصول على معلومات الكيان، ولا ينبغي السماح للمستخدمين الآخرين...أين نضع شيكات التفويض؟

لنفترض أننا وضعناها في السطر الأول من الطريقة كما يلي:

CheckAccessPermission(PermissionType.GetEntity, user, entityId) //user is pulled from the current OperationContext

والآن هناك سؤالان:

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

  2. كيف يمكننا اختبار وحدة خدمة WCF عندما تكون عمليات فحص التفويض في كل مكان مثل هذا، وليس لدينا OperationContext في اختبار الوحدة !؟(على افتراض أنني أحاول اختبار تطبيق فئة الخدمة هذه مباشرة دون أي من إعدادات WCF).

أي أفكار يا شباب؟

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

المحلول

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

بالنسبة للسؤال 2، يمكنك التعامل مع هذا عن طريق تصنيف تنفيذ الخدمة الملموسة لديك إلى فئة فرعية.اجعل تنفيذ منطق العمل الحقيقي فئة مجردة باستخدام طريقة "CheckPermissions" مجردة كما ذكرت أعلاه.ثم قم بإنشاء فئتين فرعيتين، واحدة لاستخدام WCF، والأخرى (معزولة جدًا في ملف DLL غير منشور) والتي تُرجع صحيحًا (أو أي شيء تريد القيام به في اختبار الوحدة الخاصة بك).

مثال (لاحظ أن هذه العناصر لا ينبغي أن تكون في نفس الملف أو حتى DLL بالرغم من ذلك!):

public abstract class MyServiceImpl
{
    public void MyMethod(string entityId)
    {
        CheckPermissions(entityId);
        //move along...
    }
    protected abstract bool CheckPermissions(string entityId);
}

public class MyServiceUnitTest
{
    private bool CheckPermissions(string entityId)
    {
        return true;
    }
}

public class MyServiceMyAuth
{
    private bool CheckPermissions(string entityId)
    {
        //do some custom authentication
        return true;
    }
}

ثم يستخدم نشر WCF الخاص بك الفئة "MyServiceMyAuth"، وتقوم بإجراء اختبار الوحدة الخاصة بك مقابل الآخر.

نصائح أخرى

بالنسبة للسؤال 1، من الأفضل إجراء التفويض أولاً.وبهذه الطريقة، لا تقوم بتسريب رسائل خطأ التحقق من الصحة مرة أخرى إلى مستخدمين غير مصرح لهم.

راجع للشغل، بدلاً من استخدام طريقة مصادقة محلية الصنع (والتي أفترض أنها هي CheckAccessPermission الخاصة بك)، قد تتمكن من الاتصال بدعم WCF الجاهز لموفري دور ASP.NET.بمجرد الانتهاء من ذلك، يمكنك إجراء التفويض عبر OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.IsInRole().الهوية الأساسية هي IPrincipal.

فيما يتعلق بالسؤال رقم 2، سأفعل ذلك باستخدام Dependency Engine وقم بإعداد تنفيذ الخدمة الخاصة بك على النحو التالي:

class MyService : IMyService
{
    public MyService() : this(new UserAuthorization()) { }
    public MyService(IAuthorization auth) { _auth = auth; }

    private IAuthorization _auth;

    public EntityInfo GetEntityInfo(string entityId)
    {
            _auth.CheckAccessPermission(PermissionType.GetEntity, 
                    user, entityId);

            //Get the entity info
    }
}

لاحظ أن IAuthorization عبارة عن واجهة يمكنك تحديدها.

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

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

إطار السخرية المفضل لدي هو RhinoMocks وهو مجاني وله واجهة رائعة جدًا ولكن هناك الكثير من التطبيقات الأخرى.إذا كنت ترغب في معرفة المزيد عن DI، فإليك بعض التمهيديات الجيدة وأطر عمل .Net:

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