
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, например. Рекомендуемый способ — использовать манифест, но вы можете сделать всё из командной строки.
$ ./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"]
}
}
Затем вы можете попробовать войти в систему с помощью ruby-gem'а UAA. Убедитесь, что у вас есть 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 вы должны увидеть ваше имя пользователя и client id исходного предоставления токена, например:
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. Они определены как значения по умолчанию в XML-файлах конфигурации Spring, а также в основном файле 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"]
}
}
Затем вы можете попробовать войти в систему с помощью ruby-gem'а UAA. Убедитесь, что у вас есть 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, так что, например, URL-адрес сервиса установлен на 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') -> environment variable, if set must contain valid Yaml
Например, чтобы развернуть UAA как приложение Cloud Foundry, вы можете предоставить манифест приложения, подобный этому:
---
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 по умолчанию задана в
XML-файлах конфигурации Spring.
Вы можете изменить их, настроив в 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-клиентский 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).
В Spring Security OAuth есть ImplicitAccessTokenProvider, который может выполнить всю тяжелую работу, если ваш клиент написан на 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
браузер перенаправляется через серию шагов аутентификации и предоставления доступа (которые в какой-то момент могут быть сокращены до неявных шагов, не требующих участия пользователя), а затем отображается список приложений.
Просмотр сведений о текущем вошедшем пользователе — набора атрибутов, полученных от OpenID-провайдера
GET /app
Вот несколько способов принять участие в жизни сообщества:
