Slack #uaa
The UAA is a multi tenant identity management service, used in Cloud Foundry, but also available as a stand alone OAuth2 server. Its primary role is as an OAuth2 provider, issuing tokens for client applications to use when they act on behalf of Cloud Foundry users. It can also 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.
The authentication service is uaa
. It's a plain Spring MVC webapp.
Deploy as normal in Tomcat or your container of choice, or execute
./gradlew run
to run it directly from 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 summarise:
The OAuth2 /oauth/authorize and /oauth/token endpoints
A /login_info endpoint to allow querying for required login prompts
A /check_token endpoint, to allow resource servers to obtain information about an access token submitted by an OAuth2 client.
A /token_key endpoint, to allow resource servers to obtain the verification key to verify token signatures
SCIM user provisioning endpoint
OpenID connect endpoints to support authentication /userinfo. Partial OpenID support.
Authentication can be performed by command line clients by submitting
credentials directly to the /oauth/authorize
endpoint (as described in
UAA-API doc). There is an ImplicitAccessTokenProvider
in Spring
Security OAuth that can do the heavy lifting if your client is Java.
Authenticate
GET /login
A basic form login interface.
Approve OAuth2 token grant
GET /oauth/authorize?client_id=app&response_type=code...
Standard OAuth2 Authorization Endpoint.
Obtain access token
POST /oauth/token
Standard OAuth2 Authorization Endpoint.
Requirements:
If this works you are in business:
$ git clone git://github.com/cloudfoundry/uaa.git
$ cd uaa
$ ./gradlew run
The apps all work together with the apps running on the same port
(8080) as /uaa
, /app
and /api
.
UAA will log to a file called uaa.log
which can be found using the following command:-
$ sudo lsof | grep uaa.log
which you should find under something like:-
$TMPDIR/cargo/conf/logs/
First run the UAA server as described above:
$ ./gradlew run
From another terminal you can use curl to verify that UAA has started by requesting system information:
$ curl --silent --show-error --head localhost:8080/uaa/login | head -1
HTTP/1.1 200
For complex requests it is more convenient to interact with UAA using
uaac
, the UAA Command Line Client.
To load JDWP agent for UAA jvm debugging, start the server as follows:
./gradlew run -Dxdebug=true
or
./gradlew -Dspring.profiles.active=default,hsqldb,debug run
You can then attach your debugger to port 5005 of the jvm process.
To suspend the server start-up until the debugger is attached (useful for debugging start-up code), start the server as follows:
./gradlew run -Dxdebugs=true
or
./gradlew -Dspring.profiles.active=default,hsqldb,debugs run
./gradlew run
runs the UAA server with hsqldb database by default.
% docker run --name mysql1 -e MYSQL_ROOT_PASSWORD=changeme -d -p3306:3306 mysql
uaa
database (e.g. in mysql interactive session)
% mysql -h 127.0.0.1 -u root -p
...
mysql> create database uaa;
% ./gradlew -Dspring.profiles.active=mysql,default run
docker run --name postgres1 -p 5432:5432 -e POSTGRES_PASSWORD=mysecretpassword -d postgres
uaa
database (e.g. in psql interactive session)
% psql -h 127.0.0.1 -U postgres
create database uaa;
create user root with superuser password 'changeme';
% ./gradlew -Dspring.profiles.active=postgresql,default run
\c uaa
psql (14.5 (Homebrew), server 15.0 (Debian 15.0-1.pgdg110+1))
WARNING: psql major version 14, server major version 15.
Some psql features might not work.
You are now connected to database "uaa" as user "postgres".
\d
List of relations
Schema | Name | Type | Owner
--------+-------------------------------+----------+-------
public | authz_approvals | table | root
public | expiring_code_store | table | root
public | external_group_mapping | table | root
public | external_group_mapping_id_seq | sequence | root
public | group_membership | table | root
public | group_membership_id_seq | sequence | root
public | groups | table | root
public | identity_provider | table | root
public | identity_zone | table | root
public | oauth_client_details | table | root
public | oauth_code | table | root
public | oauth_code_id_seq | sequence | root
public | revocable_tokens | table | root
public | schema_version | table | root
public | sec_audit | table | root
public | sec_audit_id_seq | sequence | root
public | spring_session | table | root
public | spring_session_attributes | table | root
public | user_info | table | root
public | users | table | root
(23 rows)
You can run the integration tests with docker
$ run-integration-tests.sh <dbtype>
will create a docker container running uaa + ldap + database whereby integration tests are run against.
The default uaa unit tests (./gradlew test integrationTest) use hsqldb.
To run the unit tests with docker:
$ run-unit-tests.sh <dbtype>
The default uaa unit tests (./gradlew test
) use hsqldb.
Start by finding out which gradle project your test belongs to. You can find all project by running
$ ./gradlew projects
To run a specific test class, you can specify the module and the test class.
$ ./gradlew :<project name>:test --tests <TestClass>.<MethodName>
In this example, it's running only the JdbcScimGroupMembershipManagerTests tests in the cloudfoundry-identity-server module:
$ ./gradlew :cloudfoundry-identity-server:test \
--tests "org.cloudfoundry.identity.uaa.scim.jdbc.JdbcScimGroupMembershipManagerTests"
or to run all tests in a Class
$ ./gradlew :<project name>:test --tests <TestClass>
You might want to use the full gradle command found at the bottom of
the scripts/unit-tests.sh
script by prepending the project name to
the test
command and adding the --tests
option.
$ ./gradlew :clean :assemble -Pversion=${UAA_VERSION}
There are actually several projects here, the main uaa
server application, a client library and some samples:
uaa
a WAR project for easy deployment
server
a JAR project containing the implementation of UAA's REST API (including SCIM) and UI
model
a JAR project used by both the client library and server
api
(sample) is an OAuth2 resource service which returns a mock list of deployed apps
app
(sample) is a user application that uses both of the above
In CloudFoundry terms
uaa
provides an authentication service plus authorized delegation for
back-end services and apps (by issuing OAuth2 access tokens).
api
is a service that provides resources that other applications may
wish to access on behalf of the resource owner (the end user).
app
is a webapp that needs single sign on and access to the api
service on behalf of users.
Prerequisites
The Kubernetes deployment is in active development. You should expect frequent (and possibly breaking) changes. This section will be updated as progress is made on this feature set. As of now:
The K8s directory contains ytt
templates that can be rendered and applied to a K8s cluster.
In development, this Makefile can be used for common rendering and deployment activities.
In production, you'll most likely want to use ytt directly. Something like this should get you going:
$ ytt -f templates -f values/default-values.yml | kubectl apply -f -
If you'd like to overide some of those values, you can do so by taking advantage of YTT's overlay functionality.
$ ytt -f templates -f values/default-values.yml -f your-dir/production-values.yml | kubectl apply -f -
Of course, you can always abandon the default values altogether and provide your own values file.
Here are some ways for you to get involved in the community:
Requirements:
To debug UAA and LDAP integrations, we use an OpenLdap docker image from VMWare's Bitnami project
uaa/src/main/resources/uaa.yml
and enable LDAP by uncommenting line 7, spring_profiles: ldap,default,hsqldb
docker-compose up
from directory scripts/ldap
scripts/ldap
verify connectivity to running OpenLdap container by running docker-confirm-ldapquery.sh
./gradlew run
/uaa
and log in with LDAP user user01
and password password1
Use below command to clean-up container and volume:
docker-compose down --volumes