JavaRush /مدونة جافا /Random-AR /JAAS - مقدمة للتكنولوجيا (الجزء الأول)
Viacheslav
مستوى

JAAS - مقدمة للتكنولوجيا (الجزء الأول)

نشرت في المجموعة
لقد تم تطبيق أمان الوصول في Java لفترة طويلة وتسمى بنية توفير هذا الأمان JAAS - خدمة مصادقة وتفويض Java. ستحاول هذه المراجعة كشف سر ماهية المصادقة والترخيص وما علاقة JAAS به. كيف تكون JAAS صديقة لـ Servlet API، وأين توجد مشاكل في علاقتهما.
JAAS - مقدمة للتكنولوجيا (الجزء الأول) - 1

مقدمة

في هذه المراجعة أود مناقشة موضوع مثل أمان تطبيقات الويب. لدى Java العديد من التقنيات التي توفر الأمان:
  • " بنية أمان منصة Java SE "، يمكن قراءة المزيد من التفاصيل حول ذلك في الدليل من Oracle: " بنية أمان منصة JavaTM SE ". تصف هذه البنية مدى حاجتنا إلى تأمين تطبيقات Java الخاصة بنا في بيئة تشغيل Java SE. لكن هذا ليس موضوع حديثنا اليوم.

  • " Java Cryptography Architecture " هو امتداد Java الذي يصف تشفير البيانات. يمكنك قراءة المزيد عن هذا الامتداد على JavaRush في المراجعة " بنية تشفير Java: التعارف الأول " أو في الدليل من Oracle: " الدليل المرجعي لهندسة تشفير Java (JCA) ".

لكن حديثنا اليوم سيكون عن تقنية أخرى وهي “Java Authentication and Authorization Service (JAAS)”. هي التي تصف أشياء مهمة مثل المصادقة والترخيص. دعونا ننظر إلى هذا بمزيد من التفصيل.
JAAS - مقدمة للتكنولوجيا (الجزء الأول) - 2

جاس

يعد JAAS امتدادًا لـ Java SE ويتم وصفه في الدليل المرجعي لخدمة مصادقة Java وتفويضها (JAAS) . وكما يوحي اسم التقنية، يصف JAAS كيفية إجراء المصادقة والترخيص:
  • " المصادقة ": مترجمة من اليونانية، تعني كلمة "authentikos" "حقيقي، حقيقي". أي أن المصادقة هي اختبار للأصالة. أن كل من يتم المصادقة عليه هو حقًا ما يقولونه.

  • " الترخيص ": مترجم من الإنجليزية يعني "الإذن". أي أن التفويض هو التحكم في الوصول الذي يتم إجراؤه بعد المصادقة الناجحة.

أي أن JAAS يتعلق بتحديد من يطلب الوصول إلى أحد الموارد واتخاذ قرار بشأن ما إذا كان يمكنه الحصول على هذا الوصول. تشبيه صغير من الحياة: أنت تقود السيارة على طول الطريق وأوقفك المفتش. يرجى تقديم المستندات - المصادقة. هل يمكنك قيادة السيارة بالمستندات - التفويض. أو، على سبيل المثال، تريد شراء الكحول في المتجر. أولا، يطلب منك جواز السفر - المصادقة. بعد ذلك، بناءً على عمرك، يتم تحديد ما إذا كنت مؤهلاً لشراء الكحول. هذا إذن. في تطبيقات الويب، يعد تسجيل الدخول كمستخدم (إدخال اسم المستخدم وكلمة المرور) بمثابة مصادقة. ويتم تحديد الصفحات التي يمكنك فتحها عن طريق الترخيص. هذا هو المكان الذي تساعدنا فيه "خدمة مصادقة وتفويض Java (JAAS)". عند النظر في JAAS، من المهم فهم العديد من المفاهيم الأساسية التي يصفها JAAS: الموضوع، والمديرون، وبيانات الاعتماد. الموضوع هو موضوع المصادقة. أي أنه حامل الحقوق أو صاحبها. في الوثائق، يتم تعريف الموضوع على أنه مصدر طلب لتنفيذ بعض الإجراءات. يجب وصف الموضوع أو المصدر بطريقة أو بأخرى ولهذا الغرض يتم استخدام "الرئيسية"، والتي تسمى أحيانًا باللغة الروسية "الرئيسية". أي أن كل مدير يمثل موضوعًا ما من وجهة نظر معينة. لجعل الأمر أكثر وضوحا، دعونا نعطي مثالا: شخص معين هو موضوع. ويمكن لما يلي العمل كمديرين:
  • رخصة قيادته بمثابة تمثيل للشخص كمستخدم للطريق
  • جواز سفره، باعتباره تمثيلاً للشخص كمواطن في بلده
  • جواز سفره الأجنبي، كتمثيل للشخص كمشارك في العلاقات الدولية
  • بطاقة مكتبته في المكتبة، باعتبارها تمثيلاً للشخص كقارئ ملحق بالمكتبة
بالإضافة إلى ذلك، يحتوي الموضوع على مجموعة من "Credential"، والتي تعني "الهوية" باللغة الإنجليزية. هكذا يؤكد الذات أنه هو. على سبيل المثال، يمكن أن تكون كلمة مرور المستخدم هي بيانات الاعتماد. أو أي شيء يمكن للمستخدم من خلاله التأكد من أنه هو بالفعل. دعونا الآن نرى كيف يتم استخدام JAAS في تطبيقات الويب.
JAAS - مقدمة للتكنولوجيا (الجزء الأول) - 3

تطبيق ويب

لذلك، نحن بحاجة إلى تطبيق ويب. سيساعدنا نظام بناء المشروع التلقائي Gradle في إنشائه. بفضل استخدام Gradle، يمكننا، من خلال تنفيذ أوامر صغيرة، تجميع مشروع Java بالتنسيق الذي نحتاجه، وإنشاء بنية الدليل الضرورية تلقائيًا، وغير ذلك الكثير. يمكنك قراءة المزيد عن Gradle في النظرة العامة القصيرة: " مقدمة موجزة عن Gradle " أو في الوثائق الرسمية " Gradle Getting Started ". نحن بحاجة إلى تهيئة المشروع (التهيئة)، ولهذا الغرض، يحتوي Gradle على مكون إضافي خاص: " Gradle Init Plugin " (Init هو اختصار للتهيئة، وسهل التذكر). لاستخدام هذا البرنامج المساعد، قم بتشغيل الأمر في سطر الأوامر:
gradle init --type java-application
بعد الانتهاء بنجاح، سيكون لدينا مشروع جافا. دعونا الآن نفتح البرنامج النصي لبناء مشروعنا للتحرير. البرنامج النصي للبناء هو ملف يسمى build.gradle، والذي يصف الفروق الدقيقة في بناء التطبيق. ومن هنا الاسم، بناء البرنامج النصي. يمكننا القول أن هذا هو برنامج نصي لبناء المشروع. Gradle هي أداة متعددة الاستخدامات، حيث يتم توسيع إمكانياتها الأساسية باستخدام المكونات الإضافية. لذلك، أولاً وقبل كل شيء، دعونا ننتبه إلى كتلة "المكونات الإضافية":
plugins {
    id 'java'
    id 'application'
}
افتراضيًا، قام Gradle، وفقًا لما حددناه " --type java-application"، بإعداد مجموعة من بعض المكونات الإضافية الأساسية، أي تلك المكونات الإضافية المضمنة في توزيع Gradle نفسه. إذا ذهبت إلى قسم "المستندات" (أي الوثائق) على موقع الويب gradle.org ، فعندئذ على اليسار في قائمة المواضيع في قسم "المرجع"، نرى قسم " المكونات الإضافية الأساسية "، أي. قسم يحتوي على وصف لهذه المكونات الإضافية الأساسية جدًا. دعنا نختار المكونات الإضافية التي نحتاجها بالضبط، وليس تلك التي أنشأها Gradle لنا. وفقًا للوثائق، يوفر " Gradle Java Plugin " العمليات الأساسية باستخدام كود Java، مثل تجميع التعليمات البرمجية المصدر. أيضًا، وفقًا للوثائق، يوفر لنا " البرنامج المساعد لتطبيق Gradle " أدوات للعمل مع "تطبيق JVM القابل للتنفيذ"، أي. باستخدام تطبيق Java الذي يمكن تشغيله كتطبيق مستقل (على سبيل المثال، تطبيق وحدة تحكم أو تطبيق بواجهة مستخدم خاصة به). اتضح أننا لسنا بحاجة إلى البرنامج المساعد "التطبيق"، لأن... لا نحتاج إلى تطبيق مستقل، بل نحتاج إلى تطبيق ويب. دعونا حذفه. بالإضافة إلى إعداد "mainClassName" المعروف فقط لهذا البرنامج المساعد. علاوة على ذلك، في نفس قسم " التعبئة والتوزيع " حيث تم توفير الرابط إلى وثائق البرنامج الإضافي للتطبيق، يوجد رابط إلى البرنامج الإضافي Gradle War. يوفر Gradle War Plugin ، كما هو مذكور في الوثائق، الدعم لإنشاء تطبيقات ويب Java بتنسيق الحرب. يعني تنسيق WAR أنه بدلاً من أرشيف JAR، سيتم إنشاء أرشيف WAR. ويبدو أن هذا هو ما نحتاجه. أيضًا، كما تقول الوثائق، "يعمل المكون الإضافي War على توسيع مكون Java الإضافي". أي أنه يمكننا استبدال مكون Java الإضافي بملحق الحرب. لذلك، ستبدو كتلة المكونات الإضافية الخاصة بنا في النهاية كما يلي:
plugins {
    id 'war'
}
يُقال أيضًا في وثائق "Gradle War Plugin" أن المكون الإضافي يستخدم "تخطيط مشروع" إضافي. تتم ترجمة التخطيط من اللغة الإنجليزية كموقع. أي أن ملحق الحرب يتوقع بشكل افتراضي وجود موقع معين من الملفات التي سيستخدمها في مهامه. وسوف يستخدم الدليل التالي لتخزين ملفات تطبيق الويب: src/main/webapp يتم وصف سلوك البرنامج المساعد على النحو التالي:
JAAS - مقدمة للتكنولوجيا (الجزء الأول) - 4
أي أن المكون الإضافي سيأخذ في الاعتبار الملفات من هذا الموقع عند إنشاء أرشيف WAR لتطبيق الويب الخاص بنا. بالإضافة إلى ذلك، تشير وثائق Gradle War Plugin إلى أن هذا الدليل سيكون "جذر الأرشيف". وبالفعل يمكننا إنشاء دليل WEB-INF وإضافة ملف web.xml هناك. أي نوع من الملف هذا؟ web.xml- هذا هو "واصف النشر" أو "واصف النشر". هذا ملف يصف كيفية تكوين تطبيق الويب الخاص بنا للعمل. يحدد هذا الملف الطلبات التي سيتعامل معها تطبيقنا وإعدادات الأمان وغير ذلك الكثير. يشبه في جوهره إلى حد ما ملف البيان من ملف JAR (راجع " العمل مع ملفات البيان: الأساسيات "). يخبرك ملف Manifest عن كيفية العمل مع تطبيق Java (أي أرشيف JAR)، ويخبرك ملف web.xml عن كيفية العمل مع تطبيق Java Web (أي أرشيف WAR). لم ينشأ مفهوم "واصف النشر" من تلقاء نفسه، ولكن تم وصفه في المستند " مواصفات Servlet API"". يعتمد أي تطبيق ويب Java على "Servlet API". من المهم أن نفهم أن هذه واجهة برمجة تطبيقات - أي أنها وصف لبعض عقود التفاعل. تطبيقات الويب ليست تطبيقات مستقلة. فهي تعمل على خادم ويب. ، الذي يوفر اتصالات الشبكة مع المستخدمين. أي أن خادم الويب هو نوع من "الحاوية" لتطبيقات الويب. وهذا أمر منطقي، لأننا نريد كتابة منطق تطبيق الويب، أي ما هي الصفحات التي سيراها المستخدم وكيف يجب أن يتفاعلوا مع تصرفات المستخدم. ونحن لا نريد أن نكتب تعليمات برمجية لكيفية إرسال الرسالة إلى المستخدم، وكيف سيتم نقل بايت من المعلومات وغيرها من الأشياء ذات المستوى المنخفض والتي تتطلب جودة كبيرة. بالإضافة إلى ذلك، اتضح أن تطبيقات الويب كلها مختلفة، لكن نقل البيانات هو نفسه، أي أنه سيتعين على مليون مبرمج كتابة تعليمات برمجية لنفس الغرض مرارًا وتكرارًا، لذا فإن خادم الويب مسؤول عن بعض تفاعلات المستخدم وتبادل البيانات، ويكون تطبيق الويب والمطور مسؤولين عن إنشاء تلك البيانات. ومن أجل ربط هذين الجزأين، أي. خادم الويب وتطبيق الويب، فأنت بحاجة إلى عقد للتفاعل بينهما، أي. ما هي القواعد التي سيتبعونها للقيام بذلك؟ من أجل وصف العقد بطريقة أو بأخرى، وكيف يجب أن يبدو التفاعل بين تطبيق الويب وخادم الويب، تم اختراع Servlet API. ومن المثير للاهتمام، حتى إذا كنت تستخدم أطر عمل مثل Spring، فلا تزال هناك واجهة برمجة تطبيقات Servlet تعمل تحت الغطاء. أي أنك تستخدم Spring، ويعمل Spring مع Servlet API نيابةً عنك. اتضح أن مشروع تطبيق الويب الخاص بنا يجب أن يعتمد على Servlet API. في هذه الحالة، ستكون واجهة برمجة تطبيقات Servlet تابعة. كما نعلم، يسمح لك Gradle أيضًا بوصف تبعيات المشروع بطريقة تعريفية. تصف المكونات الإضافية كيفية إدارة التبعيات. على سبيل المثال، يقدم Java Gradle Plugin طريقة إدارة التبعية "testImplementation"، والتي تنص على أن مثل هذه التبعية مطلوبة فقط للاختبارات. لكن البرنامج المساعد Gradle War يضيف طريقة لإدارة التبعية "providedCompile"، والتي تنص على أن مثل هذه التبعية لن يتم تضمينها في أرشيف WAR لتطبيق الويب الخاص بنا. لماذا لا نقوم بتضمين Servlet API في أرشيف WAR الخاص بنا؟ لأنه سيتم توفير واجهة برمجة تطبيقات Servlet لتطبيق الويب الخاص بنا بواسطة خادم الويب نفسه. إذا كان خادم الويب يوفر واجهة برمجة تطبيقات Servlet، فإن الخادم يسمى حاوية servlet. لذلك، تقع على عاتق خادم الويب مسؤولية تزويدنا بـ Servlet API، وتقع على عاتقنا مسؤولية توفير ServletAPI فقط في وقت تجميع التعليمات البرمجية. لهذا providedCompile. وبالتالي، ستبدو كتلة التبعيات كما يلي:
dependencies {
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
    testImplementation 'junit:junit:4.12'
}
لذلك، دعونا نعود إلى ملف web.xml. افتراضيًا، لا يقوم Gradle بإنشاء أي واصف نشر، لذلك نحتاج إلى القيام بذلك بأنفسنا. لنقم بإنشاء دليل src/main/webapp/WEB-INF، وسنقوم فيه بإنشاء ملف XML يسمى web.xml. الآن دعونا نفتح "مواصفات Java Servlet" نفسها والفصل " الفصل 14 واصف النشر ". كما هو مذكور في "14.3 واصف النشر"، يتم وصف مستند XML الخاص بواصف النشر بواسطة المخطط http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd . يصف مخطط XML العناصر التي يمكن أن تتكون منها الوثيقة وبأي ترتيب يجب أن تظهر. ما هي إلزامية والتي ليست كذلك. بشكل عام، فهو يصف بنية المستند ويسمح لك بالتحقق مما إذا كان مستند XML مكونًا بشكل صحيح. الآن دعونا نستخدم المثال من الفصل " 14.5 أمثلة "، ولكن يجب تحديد المخطط للإصدار 3.1، أي.
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd
سوف تبدو فارغة لدينا web.xmlمثل هذا:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <display-name>JAAS Example</display-name>
</web-app>
دعونا الآن نصف servlet الذي سنحميه باستخدام JAAS. في السابق، أنشأ Gradle فئة التطبيق لنا. دعونا نحوله إلى servlet. كما هو مذكور في المواصفات الواردة في " الفصل 2 واجهة Servlet "، أنه " بالنسبة لمعظم الأغراض، سيقوم المطورون بتوسيع HttpServlet لتنفيذ servlet الخاصة بهم "، أي لجعل فئة ما servlet، تحتاج إلى وراثة هذه الفئة من HttpServlet:
public class App extends HttpServlet {
	public String getGreeting() {
        return "Secret!";
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().print(getGreeting());
    }
}
كما قلنا، فإن Servlet API عبارة عن عقد بين الخادم وتطبيق الويب الخاص بنا. يسمح لنا هذا العقد بوصف أنه عندما يتصل مستخدم بالخادم، سيقوم الخادم بإنشاء طلب من المستخدم في شكل كائن HttpServletRequestوتمريره إلى servlet. كما سيزود servlet بكائن HttpServletResponseحتى يتمكن servlet من كتابة رد عليه للمستخدم. بمجرد الانتهاء من تشغيل servlet، سيكون الخادم قادرًا على تزويد المستخدم باستجابة بناءً عليه HttpServletResponse. أي أن servlet لا يتواصل مباشرة مع المستخدم، بل مع الخادم فقط. لكي يعرف الخادم أن لدينا servlet وما هي الطلبات التي يجب استخدامها، نحتاج إلى إخبار الخادم بذلك في واصف النشر:
<servlet>
	<servlet-name>app</servlet-name>
	<servlet-class>jaas.App</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>app</servlet-name>
	<url-pattern>/secret</url-pattern>
</servlet-mapping>
في هذه الحالة، /secretلن يتم توجيه جميع الطلبات إلى servlet الخاص بنا بالاسم app، والذي يتوافق مع الفئة jaas.App. كما قلنا سابقًا، لا يمكن نشر تطبيق الويب إلا على خادم الويب. يمكن تثبيت خادم الويب بشكل منفصل (مستقل). ولكن لأغراض هذه المراجعة، فإن الخيار البديل مناسب - يعمل على خادم مضمن. هذا يعني أنه سيتم إنشاء الخادم وتشغيله برمجيًا (سيقوم البرنامج الإضافي بذلك نيابةً عنا)، وفي نفس الوقت سيتم نشر تطبيق الويب الخاص بنا عليه. يتيح لك نظام بناء Gradle استخدام المكوّن الإضافي " Gradle Gretty Plugin " لهذه الأغراض:
plugins {
    id 'war'
    id 'org.gretty' version '2.2.0'
}
بالإضافة إلى ذلك، يحتوي البرنامج المساعد Gretty على وثائق جيدة . لنبدأ بحقيقة أن المكون الإضافي Gretty يسمح لك بالتبديل بين خوادم الويب المختلفة. تم توضيح ذلك بمزيد من التفصيل في الوثائق: " التبديل بين حاويات servlet ". فلننتقل إلى Tomcat، لأن... وهو من الأكثر استخدامًا، كما أنه يحتوي على توثيق جيد والعديد من الأمثلة والمشكلات التي تم تحليلها:
gretty {
    // Переключаемся с дефолтного Jetty на Tomcat
    servletContainer = 'tomcat8'
    // Укажем Context Path, он же Context Root
    contextPath = '/jaas'
}
يمكننا الآن تشغيل "gradle appRun" ومن ثم سيكون تطبيق الويب الخاص بنا متاحًا على http://localhost:8080/jaas/secret
JAAS - مقدمة للتكنولوجيا (الجزء الأول) - 5
من المهم التحقق من تحديد حاوية servlet بواسطة Tomcat (انظر رقم 1) والتحقق من العنوان الذي يتوفر فيه تطبيق الويب الخاص بنا (انظر رقم 2).
JAAS - مقدمة للتكنولوجيا (الجزء الأول) - 6

المصادقة

تتكون إعدادات المصادقة غالبًا من جزأين: الإعدادات على جانب الخادم والإعدادات على جانب تطبيق الويب الذي يتم تشغيله على هذا الخادم. لا يمكن لإعدادات الأمان لتطبيق الويب إلا أن تتفاعل مع إعدادات الأمان لخادم الويب، إذا لم يكن هناك سبب آخر غير أن تطبيق الويب لا يمكنه إلا أن يتفاعل مع خادم الويب. لم يكن عبثًا أن تحولنا إلى Tomcat، لأن... يتمتع Tomcat ببنية موصوفة جيدًا (راجع " Apache Tomcat 8 Architecture "). من وصف هذه البنية يتضح أن Tomcat، كخادم ويب، يمثل تطبيق الويب كسياق معين، وهو ما يسمى " سياق Tomcat ". يتيح هذا السياق لكل تطبيق ويب أن يكون له إعداداته الخاصة، معزولة عن تطبيقات الويب الأخرى. بالإضافة إلى ذلك، يمكن لتطبيق الويب التأثير على إعدادات هذا السياق. مرنة ومريحة. للحصول على فهم أعمق، نوصي بقراءة المقالة " فهم حاويات سياق Tomcat " وقسم وثائق Tomcat " حاوية السياق ". كما هو مذكور أعلاه، يمكن لتطبيق الويب الخاص بنا التأثير على سياق Tomcat الخاص بتطبيقنا باستخدام ملف /META-INF/context.xml. وأحد الإعدادات المهمة جدًا التي يمكننا التأثير عليها هي عوالم الأمان. العوالم الأمنية هي نوع من "المنطقة الأمنية". المنطقة التي تم تحديد إعدادات أمان محددة لها. وبناء على ذلك، عند استخدام مجال الأمان، فإننا نطبق إعدادات الأمان المحددة لهذا المجال. تتم إدارة عوالم الأمان بواسطة حاوية، أي. خادم الويب، وليس تطبيق الويب الخاص بنا. يمكننا فقط إخبار الخادم بنطاق الأمان الذي يجب توسيعه ليشمل تطبيقنا. تصف وثائق Tomcat في القسم " مكون المجال " المجال كمجموعة من البيانات حول المستخدمين وأدوارهم في إجراء المصادقة. يوفر Tomcat مجموعة من تطبيقات عالم الأمان المختلفة، أحدها هو " Jaas Realm ". بعد أن فهمنا القليل من المصطلحات، دعنا نصف سياق Tomcat في الملف /META-INF/context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Realm className="org.apache.catalina.realm.JAASRealm"
           appName="JaasLogin"
           userClassNames="jaas.login.UserPrincipal"
           roleClassNames="jaas.login.RolePrincipal"
           configFile="jaas.config" />
</Context>
appName- اسم التطبيق. سيحاول Tomcat مطابقة هذا الاسم مع الأسماء المحددة في ملف configFile. configFile- هذا هو "ملف تكوين تسجيل الدخول". يمكن رؤية مثال على ذلك في وثائق JAAS: " الملحق ب: مثال لتكوينات تسجيل الدخول ". بالإضافة إلى ذلك، من المهم أن يتم البحث في هذا الملف أولاً في الموارد. لذلك، يمكن لتطبيق الويب الخاص بنا توفير هذا الملف نفسه. السمات userClassNamesوتحتوي roleClassNamesعلى إشارة إلى الفئات التي تمثل مدير المستخدم. يفصل JAAS بين مفهومي "المستخدم" و"الدور" كمفهومين مختلفين java.security.Principal. دعونا تصف الطبقات المذكورة أعلاه. لنقم بإنشاء أبسط تطبيق لمبدأ المستخدم:
public class UserPrincipal implements Principal {
    private String name;
    public UserPrincipal(String name) {
        this.name = name;
    }
    @Override
    public String getName() {
        return name;
    }
}
سنكرر نفس التنفيذ تمامًا لـ RolePrincipal. كما ترون من الواجهة، فإن الشيء الرئيسي بالنسبة للمدير هو تخزين وإرجاع بعض الاسم (أو المعرف) الذي يمثل المدير. الآن، لدينا عالم أمني، لدينا فئات رئيسية. يبقى ملء الملف من configFileالسمة " "، المعروفة أيضًا باسم login configuration file. يمكن العثور على وصفه في وثائق Tomcat: " The Realm Component ".
JAAS - مقدمة للتكنولوجيا (الجزء الأول) - 7
وهذا يعني أنه يمكننا وضع إعداد تكوين تسجيل الدخول JAAS في موارد تطبيق الويب الخاص بنا وبفضل Tomcat context سنكون قادرين على استخدامه. يجب أن يكون هذا الملف متاحًا كمورد لـ ClassLoader، لذا يجب أن يكون مساره كما يلي: \src\main\resources\jaas.config لنقم بتعيين محتويات هذا الملف:
JaasLogin {
    jaas.login.JaasLoginModule required debug=true;
};
ومن الجدير بالذكر أن context.xmlنفس الاسم يستخدم هنا وفي. يؤدي هذا إلى تعيين عالم الأمان إلى LoginModule. لذلك، أخبرنا سياق Tomcat بالفئات التي تمثل المبادئ الأساسية، بالإضافة إلى وحدة تسجيل الدخول التي يجب استخدامها. كل ما يتعين علينا القيام به هو تنفيذ وحدة تسجيل الدخول هذه. ربما يكون LoginModule أحد أكثر الأشياء إثارة للاهتمام في JAAS. ستساعدنا الوثائق الرسمية في تطوير LoginModule: " خدمة مصادقة وتفويض Java (JAAS): دليل مطور LoginModule ". دعونا ننفذ وحدة تسجيل الدخول. لنقم بإنشاء فئة تنفذ الواجهة LoginModule:
public class JaasLoginModule implements LoginModule {
}
أولاً نوضح طريقة التهيئة LoginModule:
private CallbackHandler handler;
private Subject subject;
@Override
public void initialize(Subject subject, CallbackHandler callbackHandler, <String, ?> sharedState, Map<String, ?> options) {
	handler = callbackHandler;
	this.subject = subject;
}
ستوفر هذه الطريقة Subject، وسنقوم بمراجعتها وملئها بالمعلومات حول المبادئ الأساسية. سنقوم أيضًا بحفظه للاستخدام المستقبلي CallbackHandler، وهو ما تم تقديمه لنا. وبمساعدة، CallbackHandlerيمكننا طلب معلومات مختلفة حول موضوع المصادقة بعد قليل. يمكنك قراءة المزيد عنها CallbackHandlerفي القسم المقابل من الوثائق: " الدليل المرجعي لـ JAAS: CallbackHandler ". بعد ذلك، يتم تنفيذ طريقة loginالمصادقة Subject. هذه هي المرحلة الأولى من المصادقة:
@Override
public boolean login() throws LoginException {
	// Добавляем колбэки
	Callback[] callbacks = new Callback[2];
	callbacks[0] = new NameCallback("login");
	callbacks[1] = new PasswordCallback("password", true);
	// При помощи колбэков получаем через CallbackHandler логин и пароль
	try {
		handler.handle(callbacks);
		String name = ((NameCallback) callbacks[0]).getName();
		String password = String.valueOf(((PasswordCallback) callbacks[1]).getPassword());
		// Далее выполняем валидацию.
		// Тут просто для примера проверяем определённые значения
		if (name != null && name.equals("user123") && password != null && password.equals("pass123")) {
			// Сохраняем информацию, которая будет использована в методе commit
			// Не "пачкаем" Subject, т.к. не факт, что commit выполнится
			// Для примера проставим группы вручную, "хардcodeно".
			login = name;
			userGroups = new ArrayList<String>();
			userGroups.add("admin");
			return true;
		} else {
			throw new LoginException("Authentication failed");
		}
	} catch (IOException | UnsupportedCallbackException e) {
		throw new LoginException(e.getMessage());
	}
}
ومن المهم loginألا نغير Subject. يجب أن تحدث مثل هذه التغييرات فقط في طريقة التأكيد commit. بعد ذلك، يجب علينا وصف طريقة تأكيد المصادقة الناجحة:
@Override
public boolean commit() throws LoginException {
	userPrincipal = new UserPrincipal(login);
	subject.getPrincipals().add(userPrincipal);
	if (userGroups != null && userGroups.size() > 0) {
		for (String groupName : userGroups) {
			rolePrincipal = new RolePrincipal(groupName);
			subject.getPrincipals().add(rolePrincipal);
		}
	}
	return true;
}
قد يبدو غريباً الفصل بين الطريقة loginو commit. لكن النقطة المهمة هي أنه يمكن دمج وحدات تسجيل الدخول. ومن أجل المصادقة الناجحة، قد يكون من الضروري أن تعمل العديد من وحدات تسجيل الدخول بنجاح. وفقط إذا عملت جميع الوحدات الضرورية، فاحفظ التغييرات. هذه هي المرحلة الثانية من المصادقة. لننتهي من الطرق abortوالطرق logout:
@Override
public boolean abort() throws LoginException {
	return false;
}
@Override
public boolean logout() throws LoginException {
	subject.getPrincipals().remove(userPrincipal);
	subject.getPrincipals().remove(rolePrincipal);
	return true;
}
يتم استدعاء الأسلوب abortعند فشل المرحلة الأولى من المصادقة. يتم استدعاء الطريقة logoutعند تسجيل خروج النظام. بعد تنفيذنا Login Moduleوتكوينه Security Realm، نحتاج الآن إلى الإشارة إلى web.xmlحقيقة أننا نريد استخدام واحد محدد Login Config:
<login-config>
  <auth-method>BASIC</auth-method>
  <realm-name>JaasLogin</realm-name>
</login-config>
لقد حددنا اسم مجال الأمان الخاص بنا وحددنا طريقة المصادقة - BASIC. يعد هذا أحد أنواع المصادقة الموضحة في Servlet API في القسم " 13.6 المصادقة ". بقي ن
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION