
CVE-2016-4468
UAA è un servizio di gestione delle identità multi-tenant, utilizzato in Cloud Foundry, ma disponibile anche come server OAuth2 autonomo. Il suo ruolo principale è quello di provider OAuth2, emettendo token che le applicazioni client utilizzano quando agiscono per conto degli utenti di Cloud Foundry. Può anche autenticare gli utenti con le loro credenziali Cloud Foundry e può fungere da servizio SSO usando quelle credenziali (o altre). Dispone di endpoint per la gestione degli account utente, per la registrazione di client OAuth2 e per varie altre funzioni di gestione.
Requisiti:
Se funziona, sei a posto:
$ git clone git://github.com/cloudfoundry/uaa.git
$ cd uaa
$ ./gradlew run
Tutte le app funzionano insieme, con le applicazioni in esecuzione sulla stessa porta (8080) come /uaa, /app e /api.
UAA registrerà un log in un file chiamato uaa.log, che può essere trovato usando il seguente comando:-
$ sudo find / -name uaa.log
che dovresti trovare in un percorso simile a:-
/private/var/folders/7v/518b18d97_3f4c8fzxphy6f8zcm51c/T/cargo/conf/logs/
Puoi anche compilare l'app e caricarla su Cloud Foundry, ad esempio. Il nostro metodo consigliato è usare un file manifest, ma puoi fare tutto dalla riga di comando.
$ ./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
Nei passaggi precedenti, sostituisci:
myuaa con un nome applicazione univoco2.3.2-SNAPSHOT con l'etichetta di versione appropriata dalla tua build<domain> è il dominio della tua app. In futuro lo leggeremo dall'ambiente di sistema.Prima esegui il server UAA come descritto sopra:
$ ./gradlew run
Poi apri un altro terminale e, dalla directory base del progetto, chiedi all'endpoint di login di fornirti informazioni sul sistema:
$ 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"]
}
}
Poi puoi provare ad accedere con la gemma ruby di UAA. Assicurati di avere ruby 1.9, quindi
$ gem install cf-uaac
$ uaac target http://localhost:8080/uaa
$ uaac token get marissa koala
(oppure ometti nome utente / password per ricevere il prompt).
Questo autentica e ottiene un token di accesso dal server usando la concessione implicita OAuth2, simile all'approccio previsto per un client come CF. Il token viene salvato in ~/.uaac.yml, quindi esamina quel file ed estrai il token di accesso per il tuo target cf (oppure usa --verbose nella riga di comando di login sopra per vederlo registrato nella tua console).
Poi puoi accedere come resource server e recuperare i dettagli del token:
$ uaac target http://localhost:8080/uaa
$ uaac token decode
Dovresti vedere il tuo nome utente e il client id della concessione del token originale su stdout, ad esempio:
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
Questo comando presuppone che sia disponibile un database MySQL con le impostazioni di accesso predefinite e risponde alle seguenti impostazioni JDBC.
driver = 'org.mariadb.jdbc.Driver'
url = 'jdbc:mysql://localhost:3306/uaa'
user = 'root'
password = 'changeme'
schemas = ['uaa']
In modo simile, se esegui il comando
$ ./gradlew -Dspring.profiles.active=default,postgresql run
Vengono usate le impostazioni definite come
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql:uaa'
user = 'root'
password = 'changeme'
Queste impostazioni sono duplicate in due punti per l'integrazione con Gradle. Sono definite come predefinite nei file di configurazione Spring XML e nel file principale build.gradle. Il motivo per cui si trovano nel file di build Gradle è che Gradle esegua sempre l'attività flywayClean prima di avviare l'applicazione UAA. Se non vuoi pulire il database, puoi definire la variabile
-Dflyway.clean=false
come parte della riga di comando. Questo disabilita l'attività flywayClean nello script gradle. Un altro modo per disabilitare flywayClean è non specificare i profili spring nella riga di comando, ma impostare i profili nei file uaa.yml e login.yml.
Lo stesso esempio da riga di comando dovrebbe funzionare con un UAA in esecuzione su run.pivotal.io (tranne per la decodifica del token, perché non avrai il client secret). In questo caso non è necessario eseguire un server uaa locale: basta chiedere all'endpoint di login esterno di fornire informazioni sul sistema:
$ curl -H "Accept: application/json" login.run.pivotal.io
{
"prompts":{"username":["text","Username"],
"password":["password","Password"]
}
}
Puoi quindi provare ad accedere con la gemma ruby di UAA. Assicurati di avere ruby 1.9, quindi
$ gem install cf-uaac
$ uaac target uaa.run.pivotal.io
$ uaac token get [yourusername] [yourpassword]
(oppure ometti nome utente / password per ricevere il prompt).
Questo autentica e ottiene un token di accesso dal server usando la concessione implicita OAuth2, la stessa usata da un client come CF.
Puoi eseguire i test di integrazione con
$ ./gradlew integrationTest
Il comando eseguirà i test di integrazione contro un server uaa in esecuzione in un'istanza locale di Apache Tomcat, quindi, ad esempio, l'URL del servizio è impostato su http://localhost:8080/uaa (per impostazione predefinita).
Puoi puntare CLOUD_FOUNDRY_CONFIG_PATH per caricare un uaa.yml in cui è possibile modificare gli URL e, se appropriato, impostare il context root per l'esecuzione del server (vedi sotto per maggiori dettagli).
Per modificare i parametri di runtime puoi fornire un uaa.yml, ad esempio:
$ cat > /tmp/config/uaa.yml
uaa:
host: uaa.appcloud21.dev.mozycloud
test:
username: [email protected] # defaults to [email protected]
password: changeme
email: [email protected]
poi da uaa/uaa
$ CLOUD_FOUNDRY_CONFIG_PATH=/tmp/config ./gradlew test
Quando si avvia, la webapp cerca il contenuto Yaml nelle seguenti posizioni (le voci successive sovrascrivono quelle precedenti).
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
Ad esempio, per distribuire l'UAA come applicazione Cloud Foundry, puoi fornire un manifest dell'applicazione come questo:
---
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
In alternativa, imposta la configurazione yaml come stringa per una variabile d'ambiente usando il comando 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 } }'
Inoltre, qualsiasi proprietà di tipo semplice letta dall'UAA può essere espansa e letta anche come variabile d'ambiente di sistema. Nota come uaa.url può essere convertito in una variabile d'ambiente chiamata 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
I test unitari predefiniti di uaa (./gradlew test integrationTest) usano hsqldb.
Per eseguire i test unitari usando PostgreSQL:
$ ./gradlew -Dspring.profiles.active=default,postgresql test integrationTest
Facoltativamente, il profilo Spring può essere configurato nel file uaa.yml:
$ echo "spring_profiles: default,postgresql" > src/main/resources/uaa.yml
Per eseguire i test unitari usando MySQL:
$ ./gradlew -Dspring.profiles.active=default,mysql test integrationTest
La configurazione del database per i moduli common e scim è predefinita nei file di configurazione Spring XML. Puoi modificarla configurandola in uaa.yml
I valori predefiniti sono
PostgreSQL: User: root Password: changeme Database: uaa Host: localhost Port: 5432
MySQL: User: root Password: changeme Database: uaa Host: localhost Port: 3306
In realtà ci sono diversi progetti qui: l'applicazione server principale uaa, una libreria client e alcuni esempi:
uaa un progetto WAR per una facile distribuzione
server un progetto JAR contenente l'implementazione dell'API REST di UAA (incluso SCIM) e dell'interfaccia utente
model un progetto JAR usato sia dalla libreria client che dal server
client-lib un progetto JAR che fornisce un'API client Java
api (esempio) è un servizio di risorse OAuth2 che restituisce una lista fittizia di app distribuite
app (esempio) è un'applicazione utente che usa entrambe le precedenti
In termini CloudFoundry:
uaa fornisce un servizio di autenticazione e delega autorizzata per servizi e app di back-end (emettendo token di accesso OAuth2).
api è un servizio che fornisce risorse a cui altre applicazioni potrebbero voler accedere per conto del proprietario della risorsa (l'utente finale).
app è una webapp che necessita di single sign-on e accesso al servizio api per conto degli utenti.
I progetti sono organizzati in livelli orizzontali: client, model, server, ecc. In tutti questi progetti, i pacchetti java sono organizzati verticalmente attorno ai nostri servizi interni: zone, provider, client, ecc.
Il servizio di autenticazione è uaa. È una semplice webapp Spring MVC. Distribuiscila normalmente in Tomcat o nel contenitore che preferisci, oppure esegui ./gradlew run per avviarla direttamente dalla directory uaa nell'albero del sorgente. Quando viene eseguita con Gradle, ascolta sulla porta 8080 e l'URL è http://localhost:8080/uaa
Il server UAA supporta le API definite nel documento UAA-APIs. In sintesi:
Gli endpoint OAuth2 /oauth/authorize e /oauth/token
Un endpoint /login_info per consentire di interrogare i prompt di login richiesti
Un endpoint /check_token, per consentire ai resource server di ottenere informazioni su un token di accesso inviato da un client OAuth2.
Un endpoint /token_key, per consentire ai resource server di ottenere la chiave di verifica per verificare le firme dei token
Endpoint di provisioning utenti SCIM
Endpoint OpenID Connect per supportare l'autenticazione /userinfo. Supporto OpenID parziale.
L'autenticazione può essere eseguita da client da riga di comando inviando le credenziali direttamente all'endpoint /oauth/authorize (come descritto nel documento UAA-API). In Spring Security OAuth è disponibile un ImplicitAccessTokenProvider che può fare il lavoro pesante se il tuo client è in Java.
Per impostazione predefinita, uaa viene avviato con un context root /uaa.
Autenticati
GET /login
Un'interfaccia di login basata su un semplice modulo.
Approva la concessione del token OAuth2
GET /oauth/authorize?client_id=app&response_type=code...
Endpoint di autorizzazione OAuth2 standard.
Ottieni il token di accesso
POST /oauth/token
Endpoint di autorizzazione OAuth2 standard.
Nell'applicazione ci sono due file di configurazione, uaa.yml e login.yml, che forniscono i valori predefiniti per i placeholder nel Spring XML.
Ogni volta che vedi ${placeholder.name} nell'XML hai la possibilità di sovrascriverlo fornendo una proprietà di sistema (-D alla JVM) con lo stesso nome, oppure un uaa.yml o login.yml personalizzato (come descritto sopra).
uaa.yml e login.yml vengono uniti in un'unica configurazione all'avvio.
Tutte le password e i client secret nei file di configurazione sono in testo semplice, ma verranno inseriti nel database UAA crittografati con BCrypt.
In futuro sarà possibile fornire le password in formato bcrypt per evitare di dover specificare password in testo chiaro.
L'impostazione predefinita è l'uso di un archivio utenti RDBMS in memoria, pre-popolato con un singolo utente di test: marissa ha password koala.
Per usare PostgreSQL per i dati utente, attiva il profilo Spring postgresql.
I profili attivi possono essere configurati in uaa.yml usando:
spring_profiles: postgresql,default
Oppure specifica PostgreSQL dalla riga di comando:
$ ./gradlew -Dspring.profiles.active=default,postgresql run
Con l'UAA sono incluse due applicazioni di esempio: /api e /app.
Eseguile usando ./gradlew run dalla directory principale uaa.
Tutte e tre le app, /uaa, /api e /app, vengono distribuite simultaneamente.
Questa è un'app di interfaccia utente (rivolta principalmente ai browser) che usa OpenID Connect per l'autenticazione (cioè SSO) e OAuth2 per le concessioni di accesso. Si autentica con il servizio Auth e poi accede alle risorse del servizio API. Eseguila con ./gradlew run dalla directory principale uaa.
L'applicazione può operare con diversi profili in base alla posizione (e alla presenza) del server UAA e dell'applicazione Login. Per impostazione predefinita cerca un UAA su localhost:8080/uaa, ma puoi modificare questo comportamento impostando una variabile d'ambiente (o proprietà di sistema) chiamata UAA_PROFILE. Nel codice sorgente dell'applicazione (samples/app/src/main/resources) troverai più file di properties preconfigurati con diverse possibili posizioni per questi server. Hanno tutti la forma application-<UAA_PROFILE>.properties e la convenzione di denominazione adottata prevede che UAA_PROFILE sia local per la distribuzione su localhost, vcap per una distribuzione su vcap.me, staging per una distribuzione di staging (all'interno della VPN VMware), ecc. I nomi dei profili sono doppi (ad esempio local-vcap quando il server di login si trova in una posizione diversa dal server UAA).
Visualizza tutte le app
GET /app/apps
il browser viene reindirizzato attraverso una serie di passaggi di autenticazione e concessione dell'accesso (che potrebbero essere ridotti a passaggi impliciti che non richiedono l'utente a un certo punto), quindi viene mostrato l'elenco delle app.
Visualizza i dettagli dell'utente attualmente connesso, un insieme di attributi recuperati dal provider OpenID
GET /app
Ecco alcuni modi per partecipare alla community:
YourKit supporta i progetti open source con il suo Java Profiler completo. YourKit, LLC è il creatore di YourKit Java Profiler e YourKit .NET Profiler, strumenti innovativi e intelligenti per il profiling di applicazioni Java e .NET.
