
CVE-2016-4468
El UAA es un servicio de gestión de identidades multi-inquilino, utilizado en Cloud Foundry, pero también disponible como un servidor OAuth2 independiente. Su función principal es la de proveedor OAuth2, emitiendo tokens para que las aplicaciones cliente los usen cuando actúan en nombre de los usuarios de Cloud Foundry. También puede autenticar usuarios con sus credenciales de Cloud Foundry, y puede actuar como un servicio SSO utilizando esas credenciales (u otras). Tiene endpoints para gestionar cuentas de usuario y para registrar clientes OAuth2, así como varias otras funciones de gestión.
Requisitos:
Si esto funciona, estás listo:
$ git clone git://github.com/cloudfoundry/uaa.git
$ cd uaa
$ ./gradlew run
Todas las aplicaciones funcionan juntas ejecutándose en el mismo puerto
(8080) como /uaa, /app y /api.
UAA registrará en un archivo llamado uaa.log que se puede encontrar usando el siguiente comando:
$ sudo find / -name uaa.log
que deberías encontrar bajo algo como:
/private/var/folders/7v/518b18d97_3f4c8fzxphy6f8zcm51c/T/cargo/conf/logs/
También puedes construir la aplicación y enviarla a Cloud Foundry, p.ej. Nuestra forma recomendada es usar un archivo de manifiesto, pero puedes hacer todo desde la línea de comandos.
$ ./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.<dominio>
$ cf set-env myuaa LOGIN_URL http://myuaa.<dominio>
$ 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
En los pasos anteriores, reemplaza:
myuaa con un nombre de aplicación único2.3.2-SNAPSHOT con la etiqueta de versión correspondiente de tu compilación<dominio> es el dominio de tu aplicación. En el futuro lo analizaremos desde el entorno del sistemaPrimero ejecuta el servidor UAA como se describió anteriormente:
$ ./gradlew run
Luego abre otro terminal y desde el directorio base del proyecto, pide al endpoint de inicio de sesión que te informe sobre el 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"]
}
}
Luego puedes intentar iniciar sesión con la gema ruby de UAA. Asegúrate de tener ruby 1.9, luego
$ gem install cf-uaac
$ uaac target http://localhost:8080/uaa
$ uaac token get marissa koala
(o omite el nombre de usuario/contraseña para que te lo soliciten).
Esto autentica y obtiene un token de acceso del servidor utilizando
la concesión implícita de OAuth2, similar al enfoque previsto para un
cliente como CF. El token se almacena en ~/.uaac.yml, así que revisa
ese archivo y extrae el token de acceso para tu destino cf (o usa
--verbose en la línea de comandos de inicio de sesión anterior para verlo registrado en tu
consola).
Luego puedes iniciar sesión como servidor de recursos y recuperar los detalles del token:
$ uaac target http://localhost:8080/uaa
$ uaac token decode
Deberías ver tu nombre de usuario y el id del cliente de la concesión original del token en la salida estándar, p.ej.
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
Este comando asumirá que hay una base de datos MySQL disponible con la configuración predeterminada para el acceso y responderá a la siguiente configuración JDBC.
driver = 'org.mariadb.jdbc.Driver'
url = 'jdbc:mysql://localhost:3306/uaa'
user = 'root'
password = 'changeme'
schemas = ['uaa']
De manera similar, si ejecutas el comando
$ ./gradlew -Dspring.profiles.active=default,postgresql run
Utiliza la configuración definida como
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql:uaa'
user = 'root'
password = 'changeme'
Esta configuración se duplica en dos lugares para la integración con Gradle. Se definen como valores predeterminados en los archivos de configuración XML de Spring y también se definen en el archivo build.gradle principal. La razón por la que están en el archivo de compilación de Gradle es para que Gradle ejecute siempre la tarea flywayClean antes de lanzar la aplicación UAA. Si no deseas limpiar la base de datos, puedes definir la variable
-Dflyway.clean=false
como parte de tu línea de comandos. Esto deshabilita la tarea flywayClean en el script de gradle. Otra forma de deshabilitar flywayClean es no especificar los perfiles de Spring en la línea de comandos, sino configurar los perfiles en los archivos uaa.yml y login.yml.
El mismo ejemplo de línea de comandos debería funcionar contra un UAA ejecutándose en run.pivotal.io (excepto por la parte de decodificación del token porque no tendrás el secreto del cliente). En este caso, no es necesario ejecutar un servidor uaa local, así que simplemente pide al endpoint externo de inicio de sesión que te informe sobre el sistema:
$ curl -H "Accept: application/json" login.run.pivotal.io
{
"prompts":{"username":["text","Username"],
"password":["password","Password"]
}
}
Luego puedes intentar iniciar sesión con la gema ruby de UAA. Asegúrate de tener ruby 1.9, luego
$ gem install cf-uaac
$ uaac target uaa.run.pivotal.io
$ uaac token get [tunombredeusuario] [tucontraseña]
(o omite el nombre de usuario/contraseña para que te los soliciten).
Esto autentica y obtiene un token de acceso del servidor utilizando la concesión implícita de OAuth2, la misma que usa un cliente como CF.
Puedes ejecutar las pruebas de integración con
$ ./gradlew integrationTest
ejecutará las pruebas de integración contra un servidor uaa ejecutándose en una
instancia local de Apache Tomcat, por lo que, por ejemplo, la URL del servicio se establece en http://localhost:8080/uaa (por
defecto).
Puedes apuntar a CLOUD_FOUNDRY_CONFIG_PATH para recoger un
uaa.yml donde se pueden cambiar las URLs
y (si es apropiado) establecer la raíz de contexto para ejecutar el
servidor (ver más abajo para más detalles sobre eso).
Para modificar los parámetros de ejecución puedes proporcionar un uaa.yml, p.ej.
$ cat > /tmp/config/uaa.yml
uaa:
host: uaa.appcloud21.dev.mozycloud
test:
username: [email protected] # defaults to [email protected]
password: changeme
email: [email protected]
luego desde uaa/uaa
$ CLOUD_FOUNDRY_CONFIG_PATH=/tmp/config ./gradlew test
La aplicación web busca contenido Yaml en las siguientes ubicaciones (las entradas posteriores sobrescriben las anteriores) cuando se inicia.
classpath:uaa.yml
file:${CLOUD_FOUNDRY_CONFIG_PATH}/uaa.yml
file:${UAA_CONFIG_FILE}
${UAA_CONFIG_URL}
System.getEnv('UAA_CONFIG_YAML') -> variable de entorno, si está establecida debe contener Yaml válido
Por ejemplo, para desplegar el UAA como una aplicación de Cloud Foundry, puedes proporcionar un manifiesto de aplicación como
---
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
O como alternativa, establece la configuración yaml como una cadena para una variable de entorno usando el 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 } }'
Además, cualquier propiedad de tipo simple que sea leída por el UAA también puede expandirse completamente y leerse como una variable de entorno del sistema. Observa cómo uaa.url se puede convertir en una variable de entorno llamada 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
Las pruebas unitarias predeterminadas de uaa (./gradlew test integrationTest) usan hsqldb.
Para ejecutar las pruebas unitarias usando postgresql:
$ ./gradlew -Dspring.profiles.active=default,postgresql test integrationTest
Opcionalmente, el perfil de Spring se puede configurar en el archivo uaa.yml
$ echo "spring_profiles: default,postgresql" > src/main/resources/uaa.yml
Para ejecutar las pruebas unitarias usando mysql:
$ ./gradlew -Dspring.profiles.active=default,mysql test integrationTest
La configuración de la base de datos para los módulos common y scim está predeterminada en
los archivos de configuración XML de Spring.
Puedes cambiarlos configurándolos en uaa.yml
Los valores predeterminados son
PostgreSQL: Usuario: root Contraseña: changeme Base de datos: uaa Host: localhost Puerto: 5432
MySQL: Usuario: root Contraseña: changeme Base de datos: uaa Host: localhost Puerto: 3306
En realidad hay varios proyectos aquí, la aplicación principal del servidor uaa, una biblioteca cliente y algunos ejemplos:
uaa un proyecto WAR para fácil despliegue
server un proyecto JAR que contiene la implementación de la API REST del UAA (incluyendo SCIM) y la interfaz de usuario
model un proyecto JAR utilizado tanto por la biblioteca cliente como por el servidor
client-lib un proyecto JAR que proporciona una API cliente Java
api (ejemplo) es un servicio de recursos OAuth2 que devuelve una lista simulada de aplicaciones desplegadas
app (ejemplo) es una aplicación de usuario que utiliza ambos anteriores
En términos de CloudFoundry
uaa proporciona un servicio de autenticación más delegación autorizada para
servicios y aplicaciones de back-end (mediante la emisión de tokens de acceso OAuth2).
api es un servicio que proporciona recursos a los que otras aplicaciones pueden
desear acceder en nombre del propietario del recurso (el usuario final).
app es una aplicación web que necesita inicio de sesión único y acceso al servicio api
en nombre de los usuarios.
Los proyectos están organizados en capas horizontales; cliente, modelo, servidor, etc. Dentro de todos estos proyectos, los paquetes Java están organizados verticalmente en torno a nuestros servicios internos; zonas, proveedores, clientes, etc.
El servicio de autenticación es uaa. Es una aplicación web Spring MVC simple.
Despliega como de costumbre en Tomcat o en tu contenedor preferido, o ejecuta
./gradlew run para ejecutarlo directamente desde el directorio uaa en el árbol
de fuentes. Cuando se ejecuta con gradle, escucha en el puerto 8080 y la URL es
http://localhost:8080/uaa
El Servidor UAA soporta las APIs definidas en el documento UAA-APIs. En resumen:
Los endpoints OAuth2 /oauth/authorize y /oauth/token
Un endpoint /login_info para permitir consultar los mensajes de inicio de sesión requeridos
Un endpoint /check_token, para permitir que los servidores de recursos obtengan información sobre un token de acceso enviado por un cliente OAuth2.
Un endpoint /token_key, para permitir que los servidores de recursos obtengan la clave de verificación para verificar firmas de tokens
Endpoint de aprovisionamiento de usuarios SCIM
Endpoints de OpenID Connect para soportar autenticación /userinfo. Soporte parcial de OpenID.
La autenticación puede ser realizada por clientes de línea de comandos enviando
credenciales directamente al endpoint /oauth/authorize (como se describe en el
documento UAA-API). Hay un ImplicitAccessTokenProvider en Spring
Security OAuth que puede hacer el trabajo pesado si tu cliente es Java.
Por defecto, uaa se iniciará con una raíz de contexto /uaa.
Autenticar
GET /login
Una interfaz de inicio de sesión de formulario básica.
Aprobar concesión de token OAuth2
GET /oauth/authorize?client_id=app&response_type=code...
Endpoint de Autorización OAuth2 estándar.
Obtener token de acceso
POST /oauth/token
Endpoint de Autorización OAuth2 estándar.
Hay dos archivos de configuración, uaa.yml y login.yml, en la aplicación que proporcionan valores predeterminados para los
marcadores de posición en el XML de Spring.
Dondequiera que veas ${placeholder.name} en el XML, hay una oportunidad de sobrescribirlo
ya sea proporcionando una propiedad del Sistema (-D a JVM) con el mismo
nombre, o un uaa.yml o login.yml personalizado (como se describió anteriormente).
El uaa.yml y login.yml se fusionan durante el inicio en una sola configuración.
Todas las contraseñas y secretos de cliente en los archivos de configuración están en texto plano, pero se insertarán en la base de datos del UAA cifrados con BCrypt.
En el futuro, podrás proporcionar contraseñas en formato bcrypt para evitar tener que especificar contraseñas en texto claro.
El valor predeterminado es usar un almacén de usuarios RDBMS en memoria que está
prepoblado con un solo usuario de prueba: marissa tiene contraseña
koala.
Para usar Postgresql para los datos de usuario, activa el perfil de Spring postgresql.
Los perfiles activos se pueden configurar en uaa.yml usando
spring_profiles: postgresql,default
O especifica PostgreSQL en la línea de comandos:
$ ./gradlew -Dspring.profiles.active=default,postgresql run
Se incluyen dos aplicaciones de ejemplo con el UAA. Son /api y /app
Ejecútala usando ./gradlew run desde el directorio raíz uaa
Las tres aplicaciones, /uaa, /api y /app se despliegan
simultáneamente.
Esta es una aplicación de interfaz de usuario (dirigida principalmente a navegadores) que utiliza
OpenId Connect para autenticación (es decir, SSO) y OAuth2 para concesiones
de acceso. Se autentica con el servicio de autenticación, y luego accede a
recursos en el servicio API. Ejecútala con ./gradlew run desde el
directorio raíz uaa.
La aplicación puede operar en múltiples perfiles diferentes según
la ubicación (y presencia) del servidor UAA y la aplicación
Login. Por defecto, buscará un UAA en
localhost:8080/uaa, pero puedes cambiar esto estableciendo una
variable de entorno (o propiedad del Sistema) llamada UAA_PROFILE. En
el código fuente de la aplicación (samples/app/src/main/resources) encontrarás
múltiples archivos de propiedades preconfigurados con diferentes ubicaciones
probables para esos servidores. Todos tienen el formato
application-<UAA_PROFILE>.properties y la convención de nomenclatura
adoptada es que el UAA_PROFILE es local para el despliegue en
localhost, vcap para un despliegue en vcap.me, staging para un despliegue
de staging (dentro de la VPN de VMware), etc. Los nombres de perfil son dobles
(p. ej., local-vcap cuando el servidor de inicio de sesión está en una ubicación
diferente del servidor UAA).
Ver todas las aplicaciones
GET /app/apps
el navegador es redirigido a través de una serie de pasos de autenticación y concesión de acceso (que podrían reducirse a pasos implícitos que no requieran al usuario en algún momento), y luego se muestra la lista de aplicaciones.
Ver los detalles del usuario actualmente conectado, un conjunto de atributos obtenidos del proveedor open id
GET /app
Aquí hay algunas formas en las que puedes involucrarte en la comunidad:
