
CVE-2016-4468
O UAA é um serviço de gerenciamento de identidade multi-inquilino, usado no Cloud Foundry, mas também disponível como um servidor OAuth2 independente. Sua função principal é como um provedor OAuth2, emitindo tokens para aplicações cliente usarem quando agem em nome de usuários do Cloud Foundry. Ele também pode autenticar usuários com suas credenciais do Cloud Foundry e pode atuar como um serviço SSO usando essas credenciais (ou outras). Possui endpoints para gerenciamento de contas de usuário e para registro de clientes OAuth2, bem como várias outras funções de gerenciamento.
Requisitos:
Se isso funcionar, você está no caminho certo:
$ git clone git://github.com/cloudfoundry/uaa.git
$ cd uaa
$ ./gradlew run
Os aplicativos funcionam juntos com os aplicativos rodando na mesma porta (8080) como /uaa, /app e /api.
O UAA registrará em um arquivo chamado uaa.log, que pode ser encontrado usando o seguinte comando:-
$ sudo find / -name uaa.log
que você deve encontrar em algo como:-
/private/var/folders/7v/518b18d97_3f4c8fzxphy6f8zcm51c/T/cargo/conf/logs/
Você também pode construir o aplicativo e enviá-lo para o Cloud Foundry, por exemplo. Nossa maneira recomendada é usar um arquivo de manifesto, mas você pode fazer tudo na linha de 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
Nas etapas acima, substitua:
myuaa por um nome de aplicativo único2.3.2-SNAPSHOT pelo rótulo de versão apropriado da sua compilação<domain> pelo domínio do seu aplicativo. No futuro, faremos o parsing disso a partir do ambiente do sistema.Primeiro execute o servidor UAA conforme descrito acima:
$ ./gradlew run
Em seguida, inicie outro terminal e, a partir do diretório base do projeto, peça ao endpoint de login para informá-lo sobre o 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"]
}
}
Então você pode tentar fazer login com a gem ruby UAA. Certifique-se de ter ruby 1.9, então
$ gem install cf-uaac
$ uaac target http://localhost:8080/uaa
$ uaac token get marissa koala
(ou omita o nome de usuário / senha para ser solicitado).
Isso autentica e obtém um token de acesso do servidor usando a concessão implícita OAuth2, semelhante à abordagem destinada a um cliente como o CF. O token é armazenado em ~/.uaac.yml, então examine esse arquivo e retire o token de acesso para o seu destino cf (ou use --verbose na linha de comando de login acima para vê-lo registrado no seu console).
Então você pode fazer login como um servidor de recursos e recuperar os detalhes do token:
$ uaac target http://localhost:8080/uaa
$ uaac token decode
Você deve ver seu nome de usuário e o id do cliente da concessão original do token no stdout, por exemplo:
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 assume que existe um banco de dados MySQL disponível com as configurações padrão de acesso e responderá às seguintes configurações JDBC.
driver = 'org.mariadb.jdbc.Driver'
url = 'jdbc:mysql://localhost:3306/uaa'
user = 'root'
password = 'changeme'
schemas = ['uaa']
De maneira semelhante, se você executar o comando
$ ./gradlew -Dspring.profiles.active=default,postgresql run
Ele usa as configurações definidas como
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql:uaa'
user = 'root'
password = 'changeme'
Essas configurações são duplicadas em dois lugares para a integração Gradle. Elas são definidas como padrão nos arquivos de configuração Spring XML e são definidas no arquivo build.gradle principal. A razão pela qual estão no arquivo de compilação Gradle é para que, durante a execução, o Gradle execute sempre a tarefa flywayClean antes de iniciar o aplicativo UAA. Se você não quiser limpar o banco de dados, pode definir a variável
-Dflyway.clean=false
como parte da sua linha de comando. Isso desabilita a tarefa flywayClean no script gradle. Outra maneira de desabilitar o flywayClean é não especificar os perfis Spring na linha de comando, mas definir os perfis nos arquivos uaa.yml e login.yml.
O mesmo exemplo de linha de comando deve funcionar contra um UAA rodando no run.pivotal.io (exceto pela parte de decodificação do token, pois você não terá o segredo do cliente). Neste caso, não há necessidade de executar um servidor uaa local, então simplesmente peça ao endpoint de login externo para informá-lo sobre o sistema:
$ curl -H "Accept: application/json" login.run.pivotal.io
{
"prompts":{"username":["text","Username"],
"password":["password","Password"]
}
}
Então você pode tentar fazer login com a gem ruby UAA. Certifique-se de ter ruby 1.9, então
$ gem install cf-uaac
$ uaac target uaa.run.pivotal.io
$ uaac token get [yourusername] [yourpassword]
(ou omita o nome de usuário / senha para ser solicitado).
Isso autentica e obtém um token de acesso do servidor usando a concessão implícita OAuth2, a mesma usada por um cliente como o CF.
Você pode executar os testes de integração com
$ ./gradlew integrationTest
executará os testes de integração contra um servidor uaa rodando em uma instância local do Apache Tomcat, então, por exemplo, a URL do serviço é definida como http://localhost:8080/uaa (por padrão).
Você pode apontar CLOUD_FOUNDRY_CONFIG_PATH para pegar um uaa.yml onde as URLs podem ser alteradas e (se apropriado) definir o contexto raiz para executar o servidor (veja abaixo mais detalhes sobre isso).
Para modificar os parâmetros de tempo de execução, você pode fornecer um uaa.yml, por exemplo:
$ cat > /tmp/config/uaa.yml
uaa:
host: uaa.appcloud21.dev.mozycloud
test:
username: [email protected] # defaults to [email protected]
password: changeme
email: [email protected]
então a partir de uaa/uaa
$ CLOUD_FOUNDRY_CONFIG_PATH=/tmp/config ./gradlew test
O webapp procura por conteúdo Yaml nos seguintes locais (entradas posteriores substituem as anteriores) quando inicia.
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
Por exemplo, para implantar o UAA como um aplicativo Cloud Foundry, você pode fornecer um manifesto de aplicativo 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
Ou como alternativa, defina a configuração yaml como uma string para uma variável de ambiente usando o 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 } }'
Além disso, qualquer propriedade de tipo simples lida pelo UAA também pode ser totalmente expandida e lida como uma variável de ambiente do sistema. Observe como uaa.url pode ser convertido em uma variável de ambiente chamada 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
Os testes de unidade padrão do uaa (./gradlew test integrationTest) usam hsqldb.
Para executar os testes de unidade usando PostgreSQL:
$ ./gradlew -Dspring.profiles.active=default,postgresql test integrationTest
Opcionalmente, o perfil Spring pode ser configurado no arquivo uaa.yml
$ echo "spring_profiles: default,postgresql" > src/main/resources/uaa.yml
Para executar os testes de unidade usando MySQL:
$ ./gradlew -Dspring.profiles.active=default,mysql test integrationTest
A configuração do banco de dados para os módulos common e scim é definida por padrão nos
Arquivos de configuração Spring XML.
Você pode alterá-los configurando-os em uaa.yml
Os padrões são
PostgreSQL: User: root Password: changeme Database: uaa Host: localhost Port: 5432
MySQL: User: root Password: changeme Database: uaa Host: localhost Port: 3306
Na verdade, existem vários projetos aqui: o aplicativo servidor uaa principal, uma biblioteca cliente e algumas amostras:
uaa um projeto WAR para implantação fácil
server um projeto JAR contendo a implementação da API REST do UAA (incluindo SCIM) e interface do usuário
model um projeto JAR usado tanto pela biblioteca cliente quanto pelo servidor
client-lib um projeto JAR que fornece uma API cliente Java
api (amostra) é um serviço de recursos OAuth2 que retorna uma lista simulada de aplicativos implantados
app (amostra) é um aplicativo de usuário que usa ambos acima
Em termos do CloudFoundry
uaa fornece um serviço de autenticação mais delegação autorizada para serviços e aplicativos de back-end (emitindo tokens de acesso OAuth2).
api é um serviço que fornece recursos que outros aplicativos podem desejar acessar em nome do proprietário do recurso (o usuário final).
app é um webapp que precisa de logon único e acesso ao serviço api em nome dos usuários.
Os projetos são organizados em camadas horizontais: cliente, modelo, servidor, etc. Dentro de todos esses projetos, os pacotes Java são organizados verticalmente em torno de nossos serviços internos: zonas, provedores, clientes, etc.
O serviço de autenticação é uaa. É um webapp Spring MVC simples. Implante normalmente no Tomcat ou em seu contêiner de escolha, ou execute ./gradlew run para executá-lo diretamente do diretório uaa na árvore de código-fonte. Quando executado com gradle, ele escuta na porta 8080 e a URL é http://localhost:8080/uaa
O Servidor UAA suporta as APIs definidas no documento UAA-APIs. Para resumir:
Os endpoints OAuth2 /oauth/authorize e /oauth/token
Um endpoint /login_info para permitir consultas para prompts de login obrigatórios
Um endpoint /check_token, para permitir que servidores de recursos obtenham informações sobre um token de acesso enviado por um cliente OAuth2.
Um endpoint /token_key, para permitir que servidores de recursos obtenham a chave de verificação para verificar assinaturas de tokens
Endpoint de provisionamento de usuário SCIM
Endpoints OpenID Connect para suportar autenticação /userinfo. Suporte parcial ao OpenID.
A autenticação pode ser realizada por clientes de linha de comando enviando credenciais diretamente ao endpoint /oauth/authorize (conforme descrito no documento UAA-API). Existe um ImplicitAccessTokenProvider no Spring Security OAuth que pode fazer o trabalho pesado se seu cliente for Java.
Por padrão, uaa iniciará com um contexto raiz /uaa.
Autenticar
GET /login
Uma interface de login básica em formulário.
Aprovar concessão de token OAuth2
GET /oauth/authorize?client_id=app&response_type=code...
Endpoint de Autorização OAuth2 padrão.
Obter token de acesso
POST /oauth/token
Endpoint de Autorização OAuth2 padrão.
Existem dois arquivos de configuração, uaa.yml e login.yml, no aplicativo que fornecem padrões para os placeholders no Spring XML.
Onde quer que você veja ${placeholder.name} no XML, há uma oportunidade de substituí-lo fornecendo uma propriedade de Sistema (-D para JVM) com o mesmo nome, ou um uaa.yml ou login.yml personalizado (conforme descrito acima).
O uaa.yml e o login.yml são mesclados durante a inicialização em uma única configuração.
Todas as senhas e segredos de cliente nos arquivos de configuração estão em texto simples, mas serão inseridos no banco de dados UAA criptografados com BCrypt.
No futuro, você poderá fornecer senhas no formato bcrypt para evitar ter que especificar senhas em texto simples.
O padrão é usar um armazenamento de usuário RDBMS em memória que é pré-povoado com um único usuário de teste: marissa tem a senha koala.
Para usar PostgreSQL para dados de usuário, ative o perfil Spring postgresql.
Os perfis ativos podem ser configurados em uaa.yml usando
spring_profiles: postgresql,default
Ou especifique PostgreSQL na linha de comando:
$ ./gradlew -Dspring.profiles.active=default,postgresql run
Duas aplicações de exemplo estão incluídas com o UAA. O /api e o /app
Execute-o usando ./gradlew run a partir do diretório raiz uaa.
Os três aplicativos, /uaa, /api e /app, são implantados simultaneamente.
Este é um aplicativo de interface do usuário (principalmente voltado para navegadores) que usa OpenId Connect para autenticação (ou seja, SSO) e OAuth2 para concessões de acesso. Ele se autentica com o serviço de autenticação e depois acessa recursos no serviço de API. Execute-o com ./gradlew run a partir do diretório raiz uaa.
O aplicativo pode operar em vários perfis diferentes de acordo com a localização (e presença) do servidor UAA e do aplicativo de Login. Por padrão, ele procurará um UAA em localhost:8080/uaa, mas você pode alterar isso definindo uma variável de ambiente (ou propriedade de Sistema) chamada UAA_PROFILE. No código-fonte do aplicativo (samples/app/src/main/resources) você encontrará vários arquivos de propriedades pré-configurados com diferentes localizações prováveis para esses servidores. Eles estão todos no formato application-<UAA_PROFILE>.properties e a convenção de nomenclatura adotada é que o UAA_PROFILE é local para a implantação localhost, vcap para uma implantação vcap.me, staging para uma implantação de staging (dentro da VPN VMware), etc. Os nomes de perfil são duplos (por exemplo, local-vcap quando o servidor de login está em um local diferente do servidor UAA).
Ver todos os aplicativos
GET /app/apps
o navegador é redirecionado através de uma série de etapas de autenticação e concessão de acesso (que poderiam ser reduzidas a etapas implícitas que não exigem o usuário em algum momento), e então a lista de aplicativos é mostrada.
Ver os detalhes do usuário atualmente logado, uma sacola de atributos obtidos do provedor open id
GET /app
Aqui estão algumas maneiras de você se envolver na comunidade:
