
CVE-2016-4468
Le serveur UAA est un service de gestion d'identité multi-tenant, utilisé dans Cloud Foundry, mais également disponible en tant que serveur OAuth2 autonome. Son rôle principal est de fournir un serveur OAuth2, en émettant des jetons pour les applications clientes à utiliser lorsqu'elles agissent au nom des utilisateurs de Cloud Foundry. Il peut également authentifier les utilisateurs avec leurs identifiants Cloud Foundry, et peut agir comme un service SSO utilisant ces identifiants (ou d'autres). Il dispose de points de terminaison pour gérer les comptes d'utilisateurs et pour enregistrer les clients OAuth2, ainsi que diverses autres fonctions de gestion.
Prérequis :
Si cela fonctionne, c'est gagné :
$ git clone git://github.com/cloudfoundry/uaa.git
$ cd uaa
$ ./gradlew run
Toutes les applications fonctionnent ensemble, les applications tournant sur le même port
(8080) sous /uaa, /app et /api.
Le serveur UAA écrira un journal dans un fichier appelé uaa.log que vous pouvez trouver à l'aide de la commande suivante :
$ sudo find / -name uaa.log
que vous devriez trouver sous un chemin ressemblant à :
/private/var/folders/7v/518b18d97_3f4c8fzxphy6f8zcm51c/T/cargo/conf/logs/
Vous pouvez également compiler l'application et la pousser vers Cloud Foundry, par exemple. Notre méthode recommandée est d'utiliser un fichier de manifeste, mais vous pouvez tout faire en ligne de commande.
$ ./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
Dans les étapes ci-dessus, remplacez :
myuaa par un nom d'application unique2.3.2-SNAPSHOT par le label de version approprié de votre compilation<domain> : c'est le domaine de votre application. Nous analyserons cela à partir de l'environnement système à l'avenir.Exécutez d'abord le serveur UAA comme décrit ci-dessus :
$ ./gradlew run
Ensuite, ouvrez un autre terminal et, depuis le répertoire de base du projet, demandez au point de terminaison de connexion de vous informer sur le système :
$ 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"]
}
}
Vous pouvez alors essayer de vous connecter avec la gem ruby UAA. Assurez-vous d'avoir ruby 1.9, puis
$ gem install cf-uaac
$ uaac target http://localhost:8080/uaa
$ uaac token get marissa koala
(ou omettez le nom d'utilisateur / mot de passe pour être invité à les saisir).
Cette opération authentifie et obtient un jeton d'accès du serveur en utilisant l'octroi implicite OAuth2, similaire à l'approche prévue pour un client comme CF. Le jeton est stocké dans ~/.uaac.yml. Fouillez donc ce fichier et extrayez le jeton d'accès pour votre cible cf (ou utilisez l'option --verbose sur la ligne de commande de connexion ci-dessus pour le voir consigné dans votre console).
Vous pouvez ensuite vous connecter en tant que serveur de ressources et récupérer les détails du jeton :
$ uaac target http://localhost:8080/uaa
$ uaac token decode
Vous devriez voir votre nom d'utilisateur et l'identifiant client de l'octroi de jeton d'origine sur stdout, par exemple :
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
Cette commande suppose qu'une base de données MySQL est disponible avec les paramètres d'accès par défaut et répondra aux paramètres JDBC suivants.
driver = 'org.mariadb.jdbc.Driver'
url = 'jdbc:mysql://localhost:3306/uaa'
user = 'root'
password = 'changeme'
schemas = ['uaa']
De la même manière, si vous exécutez la commande
$ ./gradlew -Dspring.profiles.active=default,postgresql run
elle utilise les paramètres définis comme suit :
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql:uaa'
user = 'root'
password = 'changeme'
Ces paramètres sont dupliqués à deux endroits pour l'intégration Gradle. Ils sont définis comme valeurs par défaut dans les fichiers de configuration Spring XML et dans le fichier build.gradle principal. La raison pour laquelle ils se trouvent dans le fichier de build Gradle est que Gradle exécute toujours la tâche flywayClean avant de lancer l'application UAA. Si vous ne souhaitez pas nettoyer la base de données, vous pouvez définir la variable
-Dflyway.clean=false
dans votre ligne de commande. Cela désactive la tâche flywayClean dans le script Gradle. Une autre façon de désactiver flywayClean est de ne pas spécifier les profils Spring en ligne de commande, mais de définir les profils dans les fichiers uaa.yml et login.yml.
Le même exemple en ligne de commande devrait fonctionner avec un serveur UAA exécuté sur run.pivotal.io (sauf pour la partie décodage du jeton, car vous n'aurez pas le secret client). Dans ce cas, il n'est pas nécessaire d'exécuter un serveur uaa local, il suffit donc de demander au point de terminaison de connexion externe de vous informer sur le système :
$ curl -H "Accept: application/json" login.run.pivotal.io
{
"prompts":{"username":["text","Username"],
"password":["password","Password"]
}
}
Vous pouvez alors essayer de vous connecter avec la gem ruby UAA. Assurez-vous d'avoir ruby 1.9, puis
$ gem install cf-uaac
$ uaac target uaa.run.pivotal.io
$ uaac token get [yourusername] [yourpassword]
(ou omettez le nom d'utilisateur / mot de passe pour être invité à les saisir).
Cette opération authentifie et obtient un jeton d'accès du serveur en utilisant l'octroi implicite OAuth2, de la même manière qu'un client comme CF.
Vous pouvez exécuter les tests d'intégration avec
$ ./gradlew integrationTest
cela exécutera les tests d'intégration contre un serveur uaa tournant dans une instance Apache Tomcat locale,
donc par exemple l'URL du service est définie sur http://localhost:8080/uaa (par défaut).
Vous pouvez définir CLOUD_FOUNDRY_CONFIG_PATH pour récupérer un fichier uaa.yml où les URL peuvent être modifiées
et, le cas échéant, définir la racine de contexte pour exécuter le serveur (voir plus bas pour plus de détails).
Pour modifier les paramètres d'exécution, vous pouvez fournir un fichier uaa.yml, par exemple :
$ cat > /tmp/config/uaa.yml
uaa:
host: uaa.appcloud21.dev.mozycloud
test:
username: [email protected] # defaults to [email protected]
password: changeme
email: [email protected]
puis, depuis uaa/uaa
$ CLOUD_FOUNDRY_CONFIG_PATH=/tmp/config ./gradlew test
L'application web recherche le contenu Yaml aux emplacements suivants (les entrées ultérieures remplacent les précédentes) lors de son démarrage.
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
Par exemple, pour déployer le serveur UAA comme application Cloud Foundry, vous pouvez fournir un manifeste d'application tel que :
---
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
Ou, en alternative, définissez la configuration yaml comme une chaîne pour une variable d'environnement à l'aide de la commande 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 } }'
De plus, toute propriété de type simple lue par le serveur UAA peut également être entièrement développée et lue comme variable d'environnement système. Remarquez comment uaa.url peut être converti en une variable d'environnement appelée 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
Les tests unitaires uaa par défaut (./gradlew test integrationTest) utilisent hsqldb.
Pour exécuter les tests unitaires avec PostgreSQL :
$ ./gradlew -Dspring.profiles.active=default,postgresql test integrationTest
En option, le profil Spring peut être configuré dans le fichier uaa.yml
$ echo "spring_profiles: default,postgresql" > src/main/resources/uaa.yml
Pour exécuter les tests unitaires avec MySQL :
$ ./gradlew -Dspring.profiles.active=default,mysql test integrationTest
La configuration de la base de données pour les modules common et scim est définie par défaut dans
les fichiers de configuration Spring XML.
Vous pouvez les modifier en les configurant dans uaa.yml
Les valeurs par défaut sont
PostgreSQL: User: root Password: changeme Database: uaa Host: localhost Port: 5432
MySQL: User: root Password: changeme Database: uaa Host: localhost Port: 3306
Il y a en réalité plusieurs projets ici : l'application serveur principale uaa, une bibliothèque cliente et quelques exemples :
uaa un projet WAR pour un déploiement facile
server un projet JAR contenant l'implémentation de l'API REST de l'UAA (y compris SCIM) et l'interface utilisateur
model un projet JAR utilisé à la fois par la bibliothèque cliente et le serveur
client-lib un projet JAR qui fournit une API cliente Java
api (exemple) est un service de ressources OAuth2 qui renvoie une liste simulée d'applications déployées
app (exemple) est une application utilisateur qui utilise les deux ci-dessus
En termes CloudFoundry
uaa fournit un service d'authentification ainsi qu'une délégation autorisée pour les services et applications backend (en émettant des jetons d'accès OAuth2).
api est un service qui fournit des ressources que d'autres applications peuvent souhaiter accéder au nom du propriétaire de la ressource (l'utilisateur final).
app est une application web qui nécessite l'authentification unique et l'accès au service api au nom des utilisateurs.
Les projets sont organisés en couches horizontales ; client, modèle, serveur, etc. Dans tous ces projets, les paquets Java sont organisés verticalement autour de nos services internes ; zones, fournisseurs, clients, etc.
Le service d'authentification est uaa. C'est une application web Spring MVC simple.
Déployez-la normalement dans Tomcat ou le conteneur de votre choix, ou exécutez
./gradlew run pour la lancer directement depuis le répertoire uaa de l'arborescence source. Lorsqu'elle est exécutée avec Gradle, elle écoute sur le port 8080 et l'URL est http://localhost:8080/uaa
Le serveur UAA prend en charge les API définies dans le document UAA-APIs. Pour résumer :
Les points de terminaison OAuth2 /oauth/authorize et /oauth/token
Un point de terminaison /login_info pour permettre d'interroger les invites de connexion requises
Un point de terminaison /check_token pour permettre aux serveurs de ressources d'obtenir des informations sur un jeton d'accès soumis par un client OAuth2.
Un point de terminaison /token_key pour permettre aux serveurs de ressources d'obtenir la clé de vérification pour vérifier les signatures de jetons
Le point de terminaison d'approvisionnement des utilisateurs SCIM
Les points de terminaison OpenID Connect pour prendre en charge l'authentification /userinfo. Support partiel d'OpenID.
L'authentification peut être effectuée par des clients en ligne de commande en soumettant leurs identifiants directement au point de terminaison /oauth/authorize (comme décrit dans la documentation UAA-API). Il existe un ImplicitAccessTokenProvider dans Spring Security OAuth qui peut faire le gros du travail si votre client est en Java.
Par défaut, uaa démarrera avec une racine de contexte /uaa.
Authentification
GET /login
Une interface de connexion de base sous forme de formulaire.
Approuver l'octroi de jeton OAuth2
GET /oauth/authorize?client_id=app&response_type=code...
Point de terminaison d'autorisation OAuth2 standard.
Obtenir un jeton d'accès
POST /oauth/token
Point de terminaison d'autorisation OAuth2 standard.
Il y a deux fichiers de configuration, uaa.yml et login.yml, dans l'application, qui fournissent des valeurs par défaut aux espaces réservés du XML Spring.
Partout où vous voyez ${placeholder.name} dans le XML, vous avez la possibilité de le remplacer en fournissant une propriété système (-D à la JVM) portant le même nom, ou un fichier uaa.yml ou login.yml personnalisé (comme décrit ci-dessus).
Les fichiers uaa.yml et login.yml sont fusionnés au démarrage en une seule configuration.
Tous les mots de passe et secrets clients dans les fichiers de configuration sont en texte clair, mais ils seront insérés dans la base de données UAA chiffrés avec BCrypt.
À l'avenir, vous pourrez fournir les mots de passe au format bcrypt pour éviter d'avoir à spécifier des mots de passe en clair.
Par défaut, un magasin d'utilisateurs RDBMS en mémoire est utilisé, pré-rempli avec un seul utilisateur de test : marissa a pour mot de passe koala.
Pour utiliser PostgreSQL pour les données utilisateur, activez le profil Spring postgresql.
Les profils actifs peuvent être configurés dans uaa.yml en utilisant :
spring_profiles: postgresql,default
Ou spécifiez PostgreSQL en ligne de commande :
$ ./gradlew -Dspring.profiles.active=default,postgresql run
Deux applications exemples sont incluses avec le serveur UAA. Les applications /api et /app.
Exécutez-les avec ./gradlew run depuis le répertoire racine uaa.
Les trois applications /uaa, /api et /app sont déployées simultanément.
C'est une application d'interface utilisateur (principalement destinée aux navigateurs) qui utilise OpenId Connect pour l'authentification (c'est-à-dire SSO) et OAuth2 pour les octrois d'accès. Elle s'authentifie auprès du service Auth, puis accède aux ressources du service API. Exécutez-la avec ./gradlew run depuis le répertoire racine uaa.
L'application peut fonctionner selon plusieurs profils différents en fonction de l'emplacement (et de la présence) du serveur UAA et de l'application Login. Par défaut, elle recherche un serveur UAA sur localhost:8080/uaa, mais vous pouvez modifier cela en définissant une variable d'environnement (ou propriété système) appelée UAA_PROFILE. Dans le code source de l'application (samples/app/src/main/resources), vous trouverez plusieurs fichiers de propriétés pré-configurés avec différents emplacements probables pour ces serveurs. Ils sont tous de la forme application-<UAA_PROFILE>.properties et la convention de nommage adoptée est que UAA_PROFILE vaut local pour le déploiement en localhost, vcap pour un déploiement vcap.me, staging pour un déploiement de préproduction (dans le VPN VMware), etc. Les noms de profils sont composés (par exemple local-vcap lorsque le serveur de connexion se trouve dans un emplacement différent de celui du serveur UAA).
Voir toutes les applications
GET /app/apps
le navigateur est redirigé à travers une série d'étapes d'authentification et d'octroi d'accès (qui pourraient être réduites à des étapes implicites ne nécessitant pas l'utilisateur à un moment donné), puis la liste des applications est affichée.
Voir les détails de l'utilisateur actuellement connecté, un ensemble d'attributs récupérés auprès du fournisseur OpenID
GET /app
Voici quelques façons de vous impliquer dans la communauté :
