User Account and Authentication (UAA) Server
Page last updated: June 30, 2015
The UAA is the identity management service for Cloud Foundry. Its primary role is as an OAuth2 provider, issuing tokens for client applications to use when they act on behalf of Cloud Foundry users. In collaboration with the login server, it can authenticate users with their Cloud Foundry credentials, and can act as an SSO service using those credentials (or others). It has endpoints for managing user accounts and for registering OAuth2 clients, as well as various other management functions.
Quick Start
Deploy Locally
To start, fetch the UAA from Git, then build and run all of the components that comprise the UAA and the example programs (uaa, samples/api, and samples/app) with a single invocation of gradle:
$ git clone git://github.com/cloudfoundry/uaa.git $ cd uaa $ ./gradlew run
If successful, the three apps will run together on a single instance of Tomcat
listening on port 8080, with endpoints /uaa
, /app
, and /api
.
Deploy to Cloud Foundry
You can also build the app and push it to Cloud Foundry:
$ ./gradlew :cloudfoundry-identity-uaa:war $ cf push MYUAA -m 512M -p uaa/build/libs/cloudfoundry-identity-uaa-1.8.0.war --no-start $ cf set-env MYUAA SPRING_PROFILES_ACTIVE default $ cf start MYUAA
In the steps above, replace the following:
MYUAA
with a unique application name1.8.0
with the appropriate version label from your build
Local Command Line Usage
Run the UAA server as described above:
$ cd uaa $ ./gradlew run
Start another terminal. From the project base directory, query the login endpoint about the system:
$ curl -H "Accept: application/json" localhost:8080/uaa/login { "timestamp":"2012-03-28T18:25:49+0100", "app" : {"version":"1.8.3"}, "commit_id":"cba0958", "prompts":{"username":["text","Email"], "password":["password","Password"] } }
Log in with the UAA Ruby gem:
$ gem install cf-uaac $ uaac target http://localhost:8080/uaa $ uaac token get marissa koala
If you do not specify username and password, you will be prompted to supply them.
This authenticates and obtains an access token from the server using the OAuth2 implicit grant, similar to the approach intended for a standalone client like the
cf
CLI. The token is stored in~/.uaac.yml
. Open~/.uaac.yml
to obtain the access token for yourcf
target, or use--verbose
on the login command line above to see it in the command shell.Log in as a resource server and retrieve the token details:
$ uaac target http://localhost:8080/uaa $ uaac token decode [token-value-from-above]
You should see your username and the client id of the original token grant on STDOUT:
jti: e3a7d065-8514-43c2-b1f8-f8ab761791e2 sub: f796d1a2-eca3-4079-a317-f3224f8f7832 scope: scim.userids password.write openid cloud_controller.write cloud_controller.read client_id: cf cid: cf user_id: f796d1a2-eca3-4079-a317-f3224f8f7832 user_name: marissa email: [email protected] iat: 1413495264 exp: 1413538464 iss: http://localhost:8080/uaa/oauth/token aud: scim openid cloud_controller password
Remote Command Line Usage
The command line example in the previous section should work against the UAA, although token encoding is unnecessary as you will not have the client secret.
In this case, there is no need to run a local uaa server. Query the external login endpoint about the system:
$ curl -H "Accept: application/json" uaa.run.pivotal.io/login { "timestamp":"2014-09-15T18:25:04+0000", "app":{"version":"1.8.3"}, "commit_id":"git-metadata-not-found", "prompts":{"username":["text","Email"], "password":["password","Password"] } }
You can then try logging in with the UAA Ruby gem. Make sure you have Ruby 1.9, then:
$ gem install cf-uaac # If you have not already installed cf-uaac $ uaac target uaa.run.pivotal.io $ uaac token get [yourusername] [yourpassword]
If you do not specify a username and password, you will be prompted to supply them.
This authenticates and obtains an access token from the server using the OAuth2 implicit grant, which is the same grant that a client like the cf
CLI uses.
Integration Tests
Run the integration tests with the following command:
$ ./gradlew integrationTest
This starts a uaa server running in a local Apache Tomcat instance. By default, the service URL is set to http://localhost:8080/uaa
.
You can set the environment variable CLOUD_FOUNDRY_CONFIG_PATH
to a directory containing a uaa.yml
file in which the various URLs used in the tests are changed, and the uaa server context root may be set.
Custom YAML Configuration
To modify the runtime parameters you can provide a uaa.yml
, as shown in the following example:
$ cat > /tmp/uaa.yml uaa: host: uaa.appcloud21.dev.mozycloud test: username: [email protected] # defaults to [email protected] password: changeme email: [email protected]
Then from uaa/uaa
:
$ CLOUD_FOUNDRY_CONFIG_PATH=/tmp ./gradlew test
The webapp looks for a YAML file in the following locations (later entries override earlier ones) when it starts up.
classpath:uaa.yml
file:${CLOUD_FOUNDRY_CONFIG_PATH}/uaa.yml
file:${UAA_CONFIG_FILE}
${UAA_CONFIG_URL}
Test with PostgreSQL or MySQL
The default UAA unit tests (./gradlew test
) use hsqldb.
To run the unit tests using PostgreSQL:
$ echo "spring_profiles: default,postgresql" > src/main/resources/uaa.yml $ ./gradlew test integrationTest
To run the unit tests using MySQL:
$ echo "spring_profiles: default,mysql" > src/main/resources/uaa.yml $ ./gradlew test integrationTest
The database configuration for the common and scim modules is located at common/src/test/resources/(mysql|postgresql).properties
and scim/src/test/resources/(mysql|postgresql).properties
.
UAA Projects
There are several projects: the main uaa
server application, and some samples:
common
is a module containing a JAR with all the business logic. It is used in the webapps below.uaa
is the UAA server.uaa
provides an authentication service plus authorized delegation for back-end services and apps by issuing OAuth2 access tokens.api
(sample) is an OAuth2 resource service which returns a mock list of deployed apps.api
is a service that provides resources that other applications might want to access on behalf of the resource owner.app
(sample) is a user application that uses both of the above.app
is a webapp that needs single sign-on and access to theapi
service on behalf of users.scim
is the SCIM user management module used by UAA.
UAA Server
The authentication service is uaa
. It is a plain Spring MVC webapp.
Deploy as normal in Tomcat or your container of choice, or execute ./gradlew run
to run it directly from the uaa
directory in the source tree. When running with Gradle, it listens on port 8080 and the URL is http://localhost:8080/uaa
.
The UAA Server supports the APIs defined in the UAA-APIs document. To summarize:
The OAuth2
/authorize
and/token
endpointsA
/login_info
endpoint to allow querying for required login promptsA
/check_token
endpoint, to allow resource servers to obtain information about an access token submitted by an OAuth2 client.SCIM user provisioning endpoint
OpenID connect endpoints to support authentication
/userinfo
and/check_id
(todo). Implemented roughly enough to get it working (so/app
authenticates here), but not to meet the spec.
Command line clients can perform authentication by submitting credentials directly to the /authorize
endpoint.
There is an ImplicitAccessTokenProvider
in Spring Security OAuth that can do the heavy lifting if your client is Java.
By default, uaa
will launch with a context root /uaa
.
Configuration
There is a uaa.yml
file in the application which provides defaults to the placeholders in the Spring XML.
Wherever you see ${placeholder.name}
in the XML, there is an opportunity to override it either by providing a System property (-D
to JVM) with the same name, or a custom uaa.yml
(as described above).
All passwords and client secrets in the config files are plain text, but they will be inserted into the UAA database encrypted with BCrypt.
User Account Data
The default is to use an in-memory RDBMS user store that is pre-populated with a single test user: marissa
with password koala
.
To use Postgresql for user data, activate the Spring profile postgresql
.
You can configure the active profiles in uaa.yml
using:
spring_profiles: postgresql,default
To use PostgreSQL instead of HSQL:
$ echo "spring_profiles: postgresql,default" > src/main/resources/uaa.yml $ ./gradlew run
To bootstrap a microcloud-type environment, you need an admin client; there is a database initializer component that inserts one.
If the default profile is active (i.e. not postgresql
), there is also a cf
CLI client so that the gem login works out of the box.
You can override the default settings and add additional clients in uaa.yml
:
oauth:
clients:
admin:
authorized-grant-types: client_credentials
scope: read,write,password
authorities: ROLE_CLIENT,ROLE_ADIN
id: admin
secret: adminclientsecret
resource-ids: clients
You can use the admin client to create additional clients.
You will need a client with read/write access to the scim
resource to create user accounts.
The integration tests take care of this automatically by inserting client and user accounts as necessary to make the tests work.
Sample Applications
Two sample applications are included with the UAA: /api
and /app
.
Run them with ./gradlew run
from the uaa
root directory. All three apps, /uaa
, /api
, and /app
get deployed simultaneously.
The API Sample Application
An example resource server.
It hosts a service that returns a list of mock applications under /apps
.
The App Sample Application
This is a user interface app (primarily aimed at browsers) that uses OpenId Connect for authentication (i.e. SSO) and OAuth2 for access grants.
It authenticates with the Auth service, then accesses resources in the API service.
Run it with ./gradlew run
from the uaa
root directory.
The application can operate in multiple different profiles according to the location (and presence) of the UAA server and the Login application.
By default, the application looks for a UAA on localhost:8080/uaa
, but you can change this by setting an environment variable (or System property) called UAA_PROFILE
.
In the application source code (samples/app/src/main/resources
), you will find multiple properties files pre-configured with different likely locations for those servers.
They are all in the form application-UAA_PROFILE.properties
.
The naming convention adopted is that the UAA_PROFILE
is local
for the localhost deployment, vcap
for a vcap.me
deployment, and staging
for a staging deployment.
The profile names are double-barreled (e.g. local-vcap
when the login server is in a different location than the UAA server).
Use Cases
See all apps
GET /app/apps
Browser is redirected through a series of authentication and access grant steps (which could be slimmed down to implicit steps not requiring user at some point), and then the photos are shown.
See the currently logged in user details, a bag of attributes grabbed from the open id provider
GET /app
Login Application
A user interface for authentication. The UAA can also authenticate user accounts, but only if it manages them itself, and it only provides a basic UI. You can brand and customize the login app for non-native authentication and for more complicated UI flows, like user registration and password reset.
The login application is itself an OAuth2 endpoint provider, but delegates those features to the UAA server.
Therefore, configuration for the login application consists of locating the UAA through its OAuth2 endpoint URLs and registering the login application itself as a client of the UAA.
There is a login.yml
for the UAA locations, such as for a local vcap
instance:
uaa:
url: http://uaa.vcap.me
token:
url: http://uaa.vcap.me/oauth/token
login:
url: http://uaa.vcap.me/login.do
There is also an environment variable (or Java System property), LOGIN_SECRET
, for the client secret that the app uses when it authenticates itself with the UAA.
The login app is registered by default in the UAA only if there are no active Spring profiles.
In the UAA, the registration is located in the oauth-clients.xml
config file:
id: login
secret: loginsecret
authorized-grant-types: client_credentials
authorities: ROLE_LOGIN
resource-ids: oauth
Use Cases
Authenticate
GET /login
The sample app presents a form login interface for the backend UAA, and also an OpenID widget so the user can authenticate using Google credentials or others.
Approve OAuth2 token grant
GET /oauth/authorize?client_id=app&response_type=code...
Standard OAuth2 Authorization Endpoint. The UAA handles client credentials and all other features in the back end, and the login application is used to render the UI (see
access_confirmation.jsp
).Obtain access token
POST /oauth/token
Standard OAuth2 Authorization Endpoint passed through to the UAA.