
CVE-2016-4468
UAA هي خدمة إدارة هوية متعددة المستأجرين، تُستخدم في Cloud Foundry، ولكنها متاحة أيضًا كخادم OAuth2 مستقل. دورها الأساسي هو مزود OAuth2، حيث تُصدر رموزًا لتطبيقات العميل لاستخدامها عندما تتصرف نيابةً عن مستخدمي Cloud Foundry. يمكنها أيضًا مصادقة المستخدمين ببيانات اعتماد Cloud Foundry الخاصة بهم، ويمكن أن تعمل كخدمة SSO باستخدام تلك البيانات الاعتمادية (أو غيرها). لديها نقاط نهاية لإدارة حسابات المستخدمين وتسجيل عملاء OAuth2، بالإضافة إلى وظائف إدارية متنوعة أخرى.
المتطلبات:
إذا نجح هذا فأنت جاهز:
$ git clone git://github.com/cloudfoundry/uaa.git
$ cd uaa
$ ./gradlew run
تعمل التطبيقات جميعها معًا على نفس المنفذ
(8080) عبر /uaa و/app و/api.
ستكتب UAA السجلات إلى ملف باسم uaa.log يمكن العثور عليه باستخدام الأمر التالي:-
$ sudo find / -name uaa.log
والذي ستجده في مسار مشابه لما يلي:-
/private/var/folders/7v/518b18d97_3f4c8fzxphy6f8zcm51c/T/cargo/conf/logs/
يمكنك أيضًا بناء التطبيق ودفعه إلى Cloud Foundry، على سبيل المثال. طريقتنا الموصى بها هي استخدام ملف manifest، لكن يمكنك القيام بكل شيء من سطر الأوامر.
$ ./gradlew :cloudfoundry-identity-uaa:war
$ cf push myuaa --no-start -m 512M -p uaa/build/libs/cloudfoundry-identity-uaa-2.3.2-SNAPSHOT.war
$ cf set-env myuaa SPRING_PROFILES_ACTIVE default,hsqldb
$ cf set-env myuaa UAA_URL http://myuaa.<domain>
$ cf set-env myuaa LOGIN_URL http://myuaa.<domain>
$ cf set-env myuaa JBP_CONFIG_SPRING_AUTO_RECONFIGURATION '[enabled: false]'
$ cf set-env myuaa JBP_CONFIG_TOMCAT '{tomcat: { version: 7.0.+ }}'
$ cf start myuaa
في الخطوات أعلاه، استبدل:
myuaa باسم تطبيق فريد2.3.2-SNAPSHOT بملصق الإصدار المناسب من بنائك<domain> هذا هو نطاق تطبيقك. سنقوم بتحليل هذا من بيئة النظام في المستقبلأولاً، قم بتشغيل خادم UAA كما هو موضح أعلاه:
$ ./gradlew run
ثم افتح طرفية أخرى ومن المجلد الأساسي للمشروع، اطلب من نقطة نهاية تسجيل الدخول إخبارك عن النظام:
$ curl -H "Accept: application/json" localhost:8080/uaa/login
{
"timestamp":"2012-03-28T18:25:49+0100",
"commit_id":"111274e",
"prompts":{"username":["text","Username"],
"password":["password","Password"]
}
}
ثم يمكنك محاولة تسجيل الدخول باستخدام جوهرة UAA ruby. تأكد من تثبيت ruby 1.9، ثم
$ gem install cf-uaac
$ uaac target http://localhost:8080/uaa
$ uaac token get marissa koala
(أو اترك اسم المستخدم / كلمة المرور فارغين ليتم سؤالك عنهما).
يقوم هذا بمصادقتك والحصول على رمز وصول من الخادم باستخدام
منحة OAuth2 الضمنية، على غرار النهج المقصود لعميل
مثل CF. يتم تخزين الرمز في ~/.uaac.yml، لذا اطلع على
ذلك الملف واستخرج رمز الوصول لهدف cf الخاص بك (أو استخدم
--verbose في سطر أوامر تسجيل الدخول أعلاه لرؤيته مسجلًا في
وحدة التحكم الخاصة بك).
ثم يمكنك تسجيل الدخول كخادم موارد واسترداد تفاصيل الرمز:
$ uaac target http://localhost:8080/uaa
$ uaac token decode
يجب أن ترى اسم المستخدم الخاص بك ومعرف العميل لمنحة الرمز الأصلية على stdout، على سبيل المثال
exp: 1355348409
user_name: marissa
scope: cloud_controller.read openid password.write scim.userids tokens.read tokens.write
email: [email protected]
aud: scim tokens openid cloud_controller password
jti: ea2fac72-3f51-4c8f-a7a6-5ffc117af542
user_id: ba14fea0-9d87-4f0c-b59e-32aaa8eb1434
client_id: cf
$ ./gradlew -Dspring.profiles.active=default,mysql run
يفترض هذا الأمر وجود قاعدة بيانات MySQL متاحة بالإعدادات الافتراضية للوصول وسيستجيب لإعدادات JDBC التالية.
driver = 'org.mariadb.jdbc.Driver'
url = 'jdbc:mysql://localhost:3306/uaa'
user = 'root'
password = 'changeme'
schemas = ['uaa']
وبطريقة مماثلة، إذا نفذت الأمر
$ ./gradlew -Dspring.profiles.active=default,postgresql run
فإنه يستخدم الإعدادات المعرفة على النحو التالي
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql:uaa'
user = 'root'
password = 'changeme'
هذه الإعدادات مكررة في مكانين لتكامل Gradle. وهي معرّفة كقيم افتراضية في ملفات إعداد Spring XML كما هي معرّفة في ملف build.gradle الرئيسي. والسبب في وجودها في ملف بناء Gradle هو أنه أثناء تنفيذ Gradle يتم دائمًا تنفيذ مهمة flywayClean قبل تشغيل تطبيق UAA. إذا كنت لا ترغب في تنظيف قاعدة البيانات، يمكنك تعريف المتغير
-Dflyway.clean=false
كجزء من سطر الأوامر الخاص بك. يؤدي هذا إلى تعطيل مهمة flywayClean في سكربت gradle. طريقة أخرى لتعطيل flywayClean هي عدم تحديد ملفات التعريف spring في سطر الأوامر، ولكن تعيين ملفات التعريف في ملفي uaa.yml وlogin.yml.
يجب أن يعمل نفس مثال سطر الأوامر مع UAA قيد التشغيل على run.pivotal.io (باستثناء جزء فك ترميز الرمز لأنك لن تمتلك سر العميل). في هذه الحالة، لا حاجة لتشغيل خادم uaa محلي، لذا ببساطة اطلب من نقطة نهاية تسجيل الدخول الخارجية إخبارك عن النظام:
$ curl -H "Accept: application/json" login.run.pivotal.io
{
"prompts":{"username":["text","Username"],
"password":["password","Password"]
}
}
يمكنك بعد ذلك محاولة تسجيل الدخول باستخدام جوهرة UAA ruby. تأكد من تثبيت ruby 1.9، ثم
$ gem install cf-uaac
$ uaac target uaa.run.pivotal.io
$ uaac token get [yourusername] [yourpassword]
(أو اترك اسم المستخدم / كلمة المرور فارغين ليتم سؤالك عنهما).
يقوم هذا بمصادقتك والحصول على رمز وصول من الخادم باستخدام منحة OAuth2 الضمنية، نفس ما يستخدمه عميل مثل CF.
يمكنك تشغيل اختبارات التكامل باستخدام
$ ./gradlew integrationTest
سيؤدي ذلك إلى تشغيل اختبارات التكامل ضد خادم uaa يعمل في مثيل
Apache Tomcat محلي، لذلك على سبيل المثال يتم تعيين عنوان الخدمة إلى http://localhost:8080/uaa (افتراضيًا).
يمكنك توجيه CLOUD_FOUNDRY_CONFIG_PATH لالتقاط ملف
uaa.yml حيث يمكن تغيير عناوين URL
و(إذا كان مناسبًا) تعيين جذر السياق لتشغيل
الخادم (انظر أدناه لمزيد من التفاصيل حول ذلك).
لتعديل معاملات وقت التشغيل يمكنك توفير ملف uaa.yml، على سبيل المثال
$ cat > /tmp/config/uaa.yml
uaa:
host: uaa.appcloud21.dev.mozycloud
test:
username: [email protected] # defaults to [email protected]
password: changeme
email: [email protected]
ثم من uaa/uaa
$ CLOUD_FOUNDRY_CONFIG_PATH=/tmp/config ./gradlew test
يبحث تطبيق الويب عن محتوى Yaml في المواقع التالية (الإدخالات اللاحقة تتجاوز الإدخالات السابقة) عند بدء التشغيل.
classpath:uaa.yml
file:${CLOUD_FOUNDRY_CONFIG_PATH}/uaa.yml
file:${UAA_CONFIG_FILE}
${UAA_CONFIG_URL}
System.getEnv('UAA_CONFIG_YAML') -> متغير بيئة، إذا تم تعيينه يجب أن يحتوي على Yaml صالح
على سبيل المثال، لنشر UAA كتطبيق Cloud Foundry، يمكنك توفير manifest تطبيق مثل
---
applications:
- name: standalone-uaa-cf-war
memory: 512M
instances: 1
host: standalone-uaa
path: cloudfoundry-identity-uaa-3.0.0-SNAPSHOT.war
env:
JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '[enabled: false]'
JBP_CONFIG_TOMCAT: '{tomcat: { version: 7.0.+ }}'
SPRING_PROFILES_ACTIVE: hsqldb,default
UAA_CONFIG_YAML: |
uaa.url: http://standalone-uaa.cfapps.io
login.url: http://standalone-uaa.cfapps.io
smtp:
host: mail.server.host
port: 3535
أو كبديل، قم بتعيين إعداد yaml كسلسلة نصية لمتغير بيئة باستخدام أمر set-env
cf set-env sample-uaa-cf-war UAA_CONFIG_YAML '{ uaa.url: http://standalone-uaa.myapp.com, login.url: http://standalone-uaa.myapp.com, smtp: { host: mail.server.host, port: 3535 } }'
بالإضافة إلى ذلك، يمكن أيضًا توسيع أي خاصية من نوع بسيط يقرؤها UAA وقراءتها كمتغير بيئة نظام بحد ذاتها. لاحظ كيف يمكن تحويل uaa.url إلى متغير بيئة يسمى UAA_URL
---
applications:
- name: standalone-uaa-cf-war
memory: 512M
instances: 1
host: standalone-uaa
path: cloudfoundry-identity-uaa-3.0.0-SNAPSHOT.war
env:
JBP_CONFIG_SPRING_AUTO_RECONFIGURATION: '[enabled: false]'
JBP_CONFIG_TOMCAT: '{tomcat: { version: 7.0.+ }}'
SPRING_PROFILES_ACTIVE: hsqldb,default
UAA_URL: http://standalone-uaa.cfapps.io
LOGIN_URL: http://standalone-uaa.cfapps.io
UAA_CONFIG_YAML: |
smtp:
host: mail.server.host
port: 3535
تستخدم اختبارات uaa الوحدات الافتراضية (./gradlew test integrationTest) hsqldb.
لتشغيل الاختبارات الوحدات باستخدام postgresql:
$ ./gradlew -Dspring.profiles.active=default,postgresql test integrationTest
اختياريًا، يمكن تكوين ملف التعريف Spring في ملف uaa.yml
$ echo "spring_profiles: default,postgresql" > src/main/resources/uaa.yml
لتشغيل الاختبارات الوحدات باستخدام mysql:
$ ./gradlew -Dspring.profiles.active=default,mysql test integrationTest
يتم تعيين إعداد قاعدة البيانات لوحدتي common وscim افتراضيًا في
ملفات إعداد Spring XML.
يمكنك تغييرها عن طريق تكوينها في uaa.yml
القيم الافتراضية هي
PostgreSQL: User: root Password: changeme Database: uaa Host: localhost Port: 5432
MySQL: User: root Password: changeme Database: uaa Host: localhost Port: 3306
يوجد بالفعل عدة مشاريع هنا، تطبيق خادم uaa الرئيسي، ومكتبة عميل وبعض الأمثلة:
uaa مشروع WAR للنشر السهل
server مشروع JAR يحتوي على تنفيذ REST API الخاص بـ UAA (بما في ذلك SCIM) وواجهة المستخدم
model مشروع JAR يستخدم من قبل كل من مكتبة العميل والخادم
client-lib مشروع JAR يوفر Java client API
api (مثال) هي خدمة موارد OAuth2 تقوم بإرجاع قائمة وهمية بالتطبيقات المنشورة
app (مثال) هو تطبيق مستخدم يستخدم كلا ما سبق
بمصطلحات CloudFoundry
يوفر uaa خدمة مصادقة بالإضافة إلى تفويض مصرح به
للخدمات الخلفية والتطبيقات (عن طريق إصدار رموز وصول OAuth2).
api هي خدمة توفر موارد قد ترغب تطبيقات أخرى
في الوصول إليها نيابة عن مالك المورد (المستخدم النهائي).
app هو تطبيق ويب يحتاج إلى تسجيل دخول موحد ووصول إلى خدمة api
نيابة عن المستخدمين.
المشاريع منظمة في طبقات أفقية؛ client، model، server، إلخ. داخل كل هذه المشاريع، حزم java منظمة رأسيًا حول خدماتنا الداخلية؛ zones، providers، clients، إلخ.
خدمة المصادقة هي uaa. إنها تطبيق ويب Spring MVC عادي.
انشرها كالمعتاد في Tomcat أو الحاوية التي تختارها، أو نفذ
./gradlew run لتشغيلها مباشرة من دليل uaa في شجرة
المصدر. عند التشغيل باستخدام gradle، تستمع على المنفذ 8080 وعنوان URL هو
http://localhost:8080/uaa
يدعم خادم UAA واجهات API المحددة في مستند UAA-APIs. للتلخيص:
نقطتا نهاية OAuth2 /oauth/authorize و/oauth/token
نقطة نهاية /login_info للسماح بالاستعلام عن مطالبات تسجيل الدخول المطلوبة
نقطة نهاية /check_token، للسماح لخوادم الموارد بالحصول على معلومات حول رمز وصول مقدم من عميل OAuth2.
نقطة نهاية /token_key، للسماح لخوادم الموارد بالحصول على مفتاح التحقق للتحقق من توقيعات الرموز
نقطة نهاية توفير مستخدمي SCIM
نقاط نهاية OpenID connect لدعم المصادقة /userinfo. دعم OpenID جزئي.
يمكن إجراء المصادقة بواسطة عملاء سطر الأوامر عن طريق إرسال
بيانات الاعتماد مباشرة إلى نقطة نهاية /oauth/authorize (كما هو موضح في
مستند UAA-API). يوجد ImplicitAccessTokenProvider في Spring
Security OAuth يمكنه القيام بالعمل الشاق إذا كان عميلك بلغة Java.
افتراضيًا، سيتم تشغيل uaa بجذر سياق /uaa.
المصادقة
GET /login
واجهة تسجيل دخول نموذجية بسيطة.
الموافقة على منح رمز OAuth2
GET /oauth/authorize?client_id=app&response_type=code...
نقطة نهاية تفويض OAuth2 القياسية.
الحصول على رمز وصول
POST /oauth/token
نقطة نهاية تفويض OAuth2 القياسية.
يوجد ملفا إعداد، uaa.yml وlogin.yml، في التطبيق يوفران قيمًا افتراضية
للعناصر النائبة في Spring XML.
أينما ترى ${placeholder.name} في XML، هناك فرصة لتجاوزه
إما عن طريق توفير خاصية نظام (-D لـ JVM) بنفس
الاسم، أو ملف uaa.yml أو login.yml مخصص (كما هو موضح أعلاه).
يتم دمج uaa.yml وlogin.yml أثناء بدء التشغيل في إعداد واحد.
جميع كلمات المرور وأسرار العملاء في ملفات الإعداد هي نص عادي، ولكن سيتم إدراجها في قاعدة بيانات UAA مشفرة باستخدام BCrypt.
في المستقبل، ستتمكن من توفير كلمات المرور بتنسيق bcrypt لتجنب الحاجة إلى تحديد كلمات مرور نصية واضحة.
الوضع الافتراضي هو استخدام مخزن مستخدمين RDBMS في الذاكرة
ممتلئ مسبقًا بمستخدم اختبار واحد: marissa لديه كلمة المرور
koala.
لاستخدام Postgresql لبيانات المستخدم، قم بتنشيط ملف التعريف Spring postgresql.
يمكن تكوين ملفات التعريف النشطة في uaa.yml باستخدام
spring_profiles: postgresql,default
أو حدد PostgreSQL من سطر الأوامر:
$ ./gradlew -Dspring.profiles.active=default,postgresql run
تم تضمين تطبيقين مثالين مع UAA. وهما /api و/app
قم بتشغيلهما باستخدام ./gradlew run من المجلد الجذر لـ uaa
يتم نشر التطبيقات الثلاثة، /uaa و/api و/app،
في وقت واحد.
هذا تطبيق واجهة مستخدم (موجه بشكل أساسي للمتصفحات) يستخدم
OpenId Connect للمصادقة (أي SSO) وOAuth2 لمنح
الوصول. يقوم بمصادقة مع خدمة Auth، ثم يصل إلى
الموارد في خدمة API. قم بتشغيله باستخدام ./gradlew run من
المجلد الجذر لـ uaa.
يمكن للتطبيق العمل في ملفات تعريف متعددة مختلفة وفقًا
لموقع (ووجود) خادم UAA وتطبيق Login.
افتراضيًا، سيبحث عن UAA على
localhost:8080/uaa، ولكن يمكنك تغيير ذلك عن طريق تعيين
متغير بيئة (أو خاصية نظام) يسمى UAA_PROFILE. في
كود مصدر التطبيق (samples/app/src/main/resources) ستجد
ملفات خصائص متعددة مكوّنة مسبقًا بمواقع محتملة مختلفة
لتلك الخوادم. جميعها بالشكل
application-<UAA_PROFILE>.properties واصطلاح التسمية
المعتمد هو أن UAA_PROFILE يكون local للنشر على
localhost، وvcap لنشر vcap.me، وstaging لنشر
التدريج (داخل VPN الخاص بـ VMware)، إلخ. أسماء ملفات التعريف
مزدوجة (على سبيل المثال local-vcap عندما يكون خادم تسجيل الدخول في موقع
مختلف عن خادم UAA).
عرض جميع التطبيقات
GET /app/apps
يتم إعادة توجيه المتصفح عبر سلسلة من خطوات المصادقة ومنح الوصول (والتي يمكن تقليصها إلى خطوات ضمنية لا تتطلب المستخدم في وقت ما)، ثم يتم عرض قائمة التطبيقات.
عرض تفاصيل المستخدم المسجل حاليًا، وهي مجموعة من السمات الملتقطة من مزود open id
GET /app
فيما يلي بعض الطرق لمشاركتك في المجتمع:
