
CVE-2016-4468
Der UAA ist ein Multi-Tenant-Identity-Management-Dienst, der in Cloud Foundry verwendet wird, aber auch als eigenständiger OAuth2-Server verfügbar ist. Seine Hauptaufgabe ist als OAuth2-Anbieter, der Token für Client-Anwendungen ausstellt, wenn diese im Namen von Cloud Foundry-Benutzern handeln. Er kann Benutzer auch mit ihren Cloud Foundry-Anmeldedaten authentifizieren und als SSO-Dienst mit diesen (oder anderen) Anmeldedaten fungieren. Er hat Endpunkte zur Verwaltung von Benutzerkonten und zur Registrierung von OAuth2-Clients sowie verschiedene andere Verwaltungsfunktionen.
Voraussetzungen:
Wenn dies funktioniert, sind Sie startklar:
$ git clone git://github.com/cloudfoundry/uaa.git
$ cd uaa
$ ./gradlew run
Alle Apps arbeiten zusammen, wobei die Apps auf demselben Port (8080) als /uaa, /app und /api laufen.
UAA loggt in eine Datei namens uaa.log, die mit folgendem Befehl gefunden werden kann:
$ sudo find / -name uaa.log
die Sie in etwa unter folgendem Pfad finden sollten:
/private/var/folders/7v/518b18d97_3f4c8fzxphy6f8zcm51c/T/cargo/conf/logs/
Sie können die App auch erstellen und in Cloud Foundry pushen, z. B. Unsere empfohlene Methode ist die Verwendung einer Manifestdatei, aber Sie können alles über die Befehlszeile erledigen.
$ ./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
Ersetzen Sie in den obigen Schritten:
myuaa durch einen eindeutigen Anwendungsnamen2.3.2-SNAPSHOT durch die entsprechende Versionsbezeichnung aus Ihrem Build<domain> durch Ihre App-Domain. Wir werden dies in Zukunft aus der Systemumgebung parsen.UAA_CONFIG_YAML die vollständige Konfiguration als YAML enthält.Führen Sie zuerst den UAA-Server wie oben beschrieben aus:
$ ./gradlew run
Starten Sie dann ein weiteres Terminal und fragen Sie vom Projektverzeichnis aus den Login-Endpunkt nach Informationen über das System:
$ 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"]
}
}
Dann können Sie versuchen, sich mit dem UAA Ruby-Gem anzumelden. Stellen Sie sicher, dass Sie Ruby 1.9 haben, dann
$ gem install cf-uaac
$ uaac target http://localhost:8080/uaa
$ uaac token get marissa koala
(oder lassen Sie Benutzername / Passwort weg, um dazu aufgefordert zu werden).
Dies authentifiziert und erhält ein Zugriffstoken vom Server mithilfe des OAuth2-Implicit-Grant, ähnlich dem Ansatz, der für einen Client wie CF vorgesehen ist. Das Token wird in ~/.uaac.yml gespeichert. Schauen Sie in diese Datei und extrahieren Sie das Zugriffstoken für Ihr cf-Ziel (oder verwenden Sie --verbose in der obigen Login-Befehlszeile, um es auf Ihrer Konsole zu protokollieren).
Dann können Sie sich als Ressourcenserver anmelden und die Token-Details abrufen:
$ uaac target http://localhost:8080/uaa
$ uaac token decode
Sie sollten Ihren Benutzernamen und die Client-ID der ursprünglichen Token-Gewährung auf stdout sehen, z. B.
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
Dieser Befehl geht davon aus, dass eine MySQL-Datenbank mit den Standardzugriffseinstellungen verfügbar ist und auf die folgenden JDBC-Einstellungen reagiert.
driver = 'org.mariadb.jdbc.Driver'
url = 'jdbc:mysql://localhost:3306/uaa'
user = 'root'
password = 'changeme'
schemas = ['uaa']
In ähnlicher Weise, wenn Sie den Befehl ausführen
$ ./gradlew -Dspring.profiles.active=default,postgresql run
verwendet er die folgenden Einstellungen:
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql:uaa'
user = 'root'
password = 'changeme'
Diese Einstellungen sind an zwei Stellen für die Gradle-Integration dupliziert.
Sie sind als Standardeinstellungen in den Spring-XML-Konfigurationsdateien definiert und in der Hauptdatei build.gradle. Der Grund, warum sie in der Gradle-Build-Datei stehen, ist, dass Gradle vor dem Start der UAA-Anwendung immer die FlywayClean-Aufgabe ausführt. Wenn Sie die Datenbank nicht bereinigen möchten, können Sie die Variable
-Dflyway.clean=false
als Teil Ihrer Befehlszeile definieren. Dies deaktiviert die FlywayClean-Aufgabe im Gradle-Skript.
Eine andere Möglichkeit, FlywayClean zu deaktivieren, besteht darin, die Spring-Profile nicht über die Befehlszeile anzugeben, sondern die Profile in den Dateien uaa.yml und login.yml zu setzen.
Das gleiche Befehlszeilenbeispiel sollte auch gegen eine UAA funktionieren, die auf run.pivotal.io läuft (mit Ausnahme des Token-Decodierungsteils, da Sie das Client-Secret nicht haben). In diesem Fall muss kein lokaler UAA-Server laufen. Fragen Sie einfach den externen Login-Endpunkt nach Informationen über das System:
$ curl -H "Accept: application/json" login.run.pivotal.io
{
"prompts":{"username":["text","Username"],
"password":["password","Password"]
}
}
Sie können dann versuchen, sich mit dem UAA Ruby-Gem anzumelden. Stellen Sie sicher, dass Sie Ruby 1.9 haben, dann
$ gem install cf-uaac
$ uaac target uaa.run.pivotal.io
$ uaac token get [yourusername] [yourpassword]
(oder lassen Sie Benutzername / Passwort weg, um dazu aufgefordert zu werden).
Dies authentifiziert und erhält ein Zugriffstoken vom Server mithilfe des OAuth2-Implicit-Grant, der gleiche, der auch von einem Client wie CF verwendet wird.
Sie können die Integrationstests mit folgendem Befehl ausführen:
$ ./gradlew integrationTest
Dies führt die Integrationstests gegen einen UAA-Server aus, der in einer lokalen
Apache Tomcat-Instanz läuft, sodass die Service-URL beispielsweise auf http://localhost:8080/uaa gesetzt ist (standardmäßig).
Sie können CLOUD_FOUNDRY_CONFIG_PATH setzen, um eine
uaa.yml zu verwenden, in der URLs geändert werden können
und (falls zutreffend) den Kontext-Pfad für den laufenden Server festlegen
(siehe unten für weitere Details).
Um die Laufzeitparameter zu ändern, können Sie eine uaa.yml bereitstellen, z. B.
$ cat > /tmp/config/uaa.yml
uaa:
host: uaa.appcloud21.dev.mozycloud
test:
username: [email protected] # standardmäßig [email protected]
password: changeme
email: [email protected]
dann von uaa/uaa aus
$ CLOUD_FOUNDRY_CONFIG_PATH=/tmp/config ./gradlew test
Die Webapplikation sucht nach YAML-Inhalten an folgenden Stellen (spätere Einträge überschreiben frühere) beim Start.
classpath:uaa.yml
file:${CLOUD_FOUNDRY_CONFIG_PATH}/uaa.yml
file:${UAA_CONFIG_FILE}
${UAA_CONFIG_URL}
System.getEnv('UAA_CONFIG_YAML') -> Umgebungsvariable, falls gesetzt, muss gültiges YAML enthalten
Um die UAA beispielsweise als Cloud Foundry-Anwendung bereitzustellen, können Sie ein Anwendungsmanifest wie folgt bereitstellen:
---
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
Oder setzen Sie alternativ die YAML-Konfiguration als Zeichenfolge für eine Umgebungsvariable mit dem Befehl 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 } }'
Darüber hinaus kann jede einfache Eigenschaft, die von der UAA gelesen wird, auch vollständig erweitert und selbst als Systemumgebungsvariable gelesen werden.
Beachten Sie, wie uaa.url in eine Umgebungsvariable namens UAA_URL umgewandelt werden kann.
---
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
Die standardmäßigen UAA-Unit-Tests (./gradlew test integrationTest) verwenden HSQLDB.
So führen Sie die Unit-Tests mit PostgreSQL aus:
$ ./gradlew -Dspring.profiles.active=default,postgresql test integrationTest
Optional kann das Spring-Profil in der Datei uaa.yml konfiguriert werden:
$ echo "spring_profiles: default,postgresql" > src/main/resources/uaa.yml
So führen Sie die Unit-Tests mit MySQL aus:
$ ./gradlew -Dspring.profiles.active=default,mysql test integrationTest
Die Datenbankkonfiguration für die Module common und scim ist in den
Spring-XML-Konfigurationsdateien voreingestellt.
Sie können sie durch Konfiguration in uaa.yml ändern.
Die Standardeinstellungen sind:
PostgreSQL: Benutzer: root Passwort: changeme Datenbank: uaa Host: localhost Port: 5432
MySQL: Benutzer: root Passwort: changeme Datenbank: uaa Host: localhost Port: 3306
Es gibt hier tatsächlich mehrere Projekte: die Haupt-UAA-Serveranwendung, eine Client-Bibliothek und einige Beispiele:
uaa ein WAR-Projekt für einfache Bereitstellung
server ein JAR-Projekt, das die Implementierung der UAA REST API (einschließlich SCIM) und UI enthält
model ein JAR-Projekt, das sowohl von der Client-Bibliothek als auch vom Server verwendet wird
client-lib ein JAR-Projekt, das eine Java-Client-API bereitstellt
api (Beispiel) ist ein OAuth2-Ressourcendienst, der eine Mock-Liste bereitgestellter Apps zurückgibt
app (Beispiel) ist eine Benutzeranwendung, die beide oben genannten verwendet
In CloudFoundry-Begriffen
uaa bietet einen Authentifizierungsdienst plus autorisierte Delegierung für
Backend-Dienste und Apps (durch Ausstellen von OAuth2-Zugriffstoken).
api ist ein Dienst, der Ressourcen bereitstellt, auf die andere Anwendungen
im Namen des Ressourcenbesitzers (des Endbenutzers) zugreifen möchten.
app ist eine Webanwendung, die Single Sign-On und Zugriff auf den api-Dienst
im Namen von Benutzern benötigt.
Die Projekte sind in horizontale Schichten organisiert: Client, Model, Server usw. Innerhalb all dieser Projekte sind die Java-Pakete vertikal um unsere internen Dienste organisiert: Zonen, Provider, Clients usw.
Der Authentifizierungsdienst ist uaa. Es ist eine einfache Spring MVC-Webanwendung.
Bereitstellung wie gewohnt in Tomcat oder Ihrem Container Ihrer Wahl, oder führen Sie
./gradlew run aus, um es direkt aus dem uaa-Verzeichnis im Quellbaum auszuführen. Bei der Ausführung mit Gradle hört es auf Port 8080 und die URL ist http://localhost:8080/uaa.
Der UAA-Server unterstützt die in den UAA-APIs definierten APIs. Zusammenfassung:
Die OAuth2-Endpunkte /oauth/authorize und /oauth/token
Ein /login_info-Endpunkt, um Abfragen nach erforderlichen Login-Eingabeaufforderungen zu ermöglichen
Ein /check_token-Endpunkt, damit Ressourcenserver Informationen über ein von einem OAuth2-Client übermitteltes Zugriffstoken erhalten können.
Ein /token_key-Endpunkt, damit Ressourcenserver den Verifikationsschlüssel zur Überprüfung von Tokensignaturen erhalten können
SCIM-Benutzerbereitstellungsendpunkt
OpenID Connect-Endpunkte zur Unterstützung der Authentifizierung /userinfo. Teilweise OpenID-Unterstützung.
Die Authentifizierung kann von Befehlszeilenclients durchgeführt werden, indem Anmeldedaten
direkt an den /oauth/authorize-Endpunkt übermittelt werden (wie in der
UAA-API-Dokumentation beschrieben). Es gibt einen ImplicitAccessTokenProvider in Spring
Security OAuth, der die schwere Arbeit erledigen kann, wenn Ihr Client Java ist.
Standardmäßig startet uaa mit einem Kontext-Pfad /uaa.
Authentifizieren
GET /login
Eine einfache Formular-Login-Oberfläche.
OAuth2-Token-Genehmigung
GET /oauth/authorize?client_id=app&response_type=code...
Standard OAuth2-Autorisierungsendpunkt.
Zugriffstoken erhalten
POST /oauth/token
Standard OAuth2-Autorisierungsendpunkt.
Es gibt zwei Konfigurationsdateien, uaa.yml und login.yml, in der Anwendung, die Standardwerte für die Platzhalter in den Spring-XML-Dateien bereitstellen.
Wo immer Sie ${placeholder.name} im XML sehen, haben Sie die Möglichkeit, es zu überschreiben, indem Sie entweder eine Systemeigenschaft (-D an JVM) mit demselben Namen oder eine benutzerdefinierte uaa.yml oder login.yml bereitstellen (wie oben beschrieben).
Die uaa.yml und login.yml werden beim Start zu einer Konfiguration zusammengeführt.
Alle Passwörter und Client-Secrets in den Konfigurationsdateien sind Klartext, werden jedoch beim Einfügen in die UAA-Datenbank mit BCrypt verschlüsselt.
In Zukunft können Sie Passwörter im BCrypt-Format angeben, um die Angabe von Klartext-Passwörtern zu vermeiden.
Standardmäßig wird ein In-Memory-RDBMS-Benutzerspeicher verwendet, der
mit einem einzelnen Testbenutzer vorbelegt ist: marissa hat das Passwort koala.
Um PostgreSQL für Benutzerdaten zu verwenden, aktivieren Sie das Spring-Profil postgresql.
Die aktiven Profile können in uaa.yml wie folgt konfiguriert werden:
spring_profiles: postgresql,default
Oder geben Sie PostgreSQL in der Befehlszeile an:
$ ./gradlew -Dspring.profiles.active=default,postgresql run
Zwei Beispielanwendungen sind im UAA enthalten. Die /api und /app
Führen Sie sie mit ./gradlew run aus dem uaa-Stammverzeichnis aus.
Alle drei Apps, /uaa, /api und /app, werden gleichzeitig bereitgestellt.
Dies ist eine Benutzeroberflächen-App (hauptsächlich für Browser gedacht), die
OpenId Connect für die Authentifizierung (d. h. SSO) und OAuth2 für Zugriffsgenehmigungen verwendet. Sie authentifiziert sich beim Auth-Dienst und greift dann auf Ressourcen im API-Dienst zu. Führen Sie sie mit ./gradlew run aus dem uaa-Stammverzeichnis aus.
Die Anwendung kann in mehreren unterschiedlichen Profilen arbeiten, je nach
Standort (und Vorhandensein) des UAA-Servers und der Login-Anwendung. Standardmäßig sucht sie einen UAA auf
localhost:8080/uaa, aber Sie können dies ändern, indem Sie eine Umgebungsvariable (oder Systemeigenschaft) namens UAA_PROFILE setzen. Im Quellcode der Anwendung (samples/app/src/main/resources) finden Sie mehrere Eigenschaftsdateien, die mit verschiedenen wahrscheinlichen Standorten für diese Server vorkonfiguriert sind. Sie sind alle im Format application-<UAA_PROFILE>.properties und die Namenskonvention ist, dass UAA_PROFILE für die lokale Bereitstellung local, für eine vcap.me-Bereitstellung vcap, für eine Staging-Bereitstellung (innerhalb des VMware-VPN) staging usw. ist. Die Profilnamen sind doppelläufig (z. B. local-vcap, wenn der Login-Server sich an einem anderen Ort als der UAA-Server befindet).
Alle Apps anzeigen
GET /app/apps
Der Browser wird durch eine Reihe von Authentifizierungs- und Zugriffsgenehmigungsschritten umgeleitet (die in Zukunft auf implizite Schritte reduziert werden könnten, die keinen Benutzer erfordern), und dann wird die Liste der Apps angezeigt.
Details des aktuell angemeldeten Benutzers anzeigen, eine Reihe von Attributen, die vom OpenID-Provider abgerufen werden
GET /app
Hier sind einige Möglichkeiten, wie Sie sich in der Community engagieren können:
