You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It is the responsibility of a Resource Server to extract information
about the user and client application from the access token and make
an access decision based on that information.
This guide will help
authors of resource Servers and maintainers of client and user account
data to understand the range of information available and the kinds of
decisions that can be taken.
The UAA itself is a Resource Server, so
the access decisions taken by the UAA are used as an example.
User accounts are either of type "user" or type "admin" (using the
SCIM type field from the core schema). These translate into granted
authorities, [uaa.user] or [uaa.admin,uaa.user] respectively, for
the purposes of access decisions within the UAA (i.e. admin users also
have the user role). Granted authorities are not directly visible to
Resource Servers, but they show up as scopes in the access tokens.
Resource Servers may choose to use this information as part of an
access decision, and this may be good enough for simple use cases
(e.g. users belong to a small number of relatively static roles), but
in general they will need to maintain their own acess decision data
since roles on UAA don't necessarily correspond to the same thing on a
Resource Server.
Support for SCIM groups is currently provided only through the
authorities attribute of the user object. Resource Servers that are
also SCIM clients can modify this attribute themselves, but it might
be better (and safer) if the data don't change much to have an admin
user or client do the role assignments. In any case it is recommended
that Resource Servers have sensible defaults for new users that have
not yet been assigned a role.
Bootstrap
There are 2 distinct scenarios:
Demo or test with vanilla code and no special environment. A UAA
service started with no active Spring profile will initialize a single
user account (marissa/koala).
A vcap environment: integration testing or in production. If the
service starts with any active Spring profile, by default it will not
touch the user database. The SCIM endpoints can be used to provision
user accounts, once a client with the correct privileges has been
registered.
In either case, additional user accounts and client registrations can
be bootstrapped at start up by providing some data in uaa.yml.
Example users:
The format for the user is
username|password|email|first_name|last_name(|comma-separated-authorities).
Remember that authorities are represented as groups in SCIM.
Account lockout policy
In its default configuration, the UAA does not lock accounts permanently
when a user repeatedly fails authentication. Instead it temporarily locks a
user out for a short period (5 minutes by default) after 5 failed logins
within the previous hour. The failure count is reset when a user
successfully authenticates.
Client applicationmeta data can be used
by Resource Servers to make an access decision, and
by the Authorization Server (the UAA itself) to decide whether to grant an access token.
Scope values are arbitrary strings, but are a contract between a
Client Application and a Resource Server, so in cases where UAA acts as a Resource
Server there are some "standard" values (scim.read, scim.write,
passsword.write, openid, etc.) whose usage and meaning is
described below.
Scopes
are used by the Authorization Server to deny a token requested for a scope not on the list, and
should be used by a Resource Server to deny access to a resource if the token has insufficient scope.
UAA client applications have the following meta data (some are
optional, but to prevent mistakes it is usually better to use a
default value):
authorized-grant-types: a comma-separated list of OAuth2 grant
types, as defined in the spec: choose from client_credentials,
password, implicit, refresh_token, authorization_code. Used
by the Authorization Server to deny a token grant if it is not on
the list. If in doubt use authorization_code and refresh_token.
scope: a list of permitted scopes for this client to obtain on
behalf of a user (so not relevant to client_credentials grants).
Also used as the default scopes for a token where the client does
not explicitly specify scopes in the authorization request.
authorities: a list of granted authorities for the client
(e.g. uaa.admin or any valid scope value). The authorities are
used to define the default scopes that are assigned to a token in a
client_credentials grant, and to limit the legal values if
explicit scopes are requested in that case.
secret: the shared secret used to authenticate token grant requests
and token decoding operations (not revealed to Resource Server).
resource-ids: white list of resource ids to be included in the
decoded tokens granted to this client. The UAA does not store any
data here (it should be none for all clients), but instead creates
a list of resource ids dynamically from the scope values when a
token is granted. The resource id is extracted from a scope using a
period separator (the last occurrence in the string) except for some
standard values (e.g. openid) that are not controlled by the UAA
or its own resources. So a scope of cloud_controller.read is
assigned a resource id of cloud_controller, for instance.
Bootstrap
Client registration can be initialized by adding client details data
to uua.yml. The UAA always starts with a registered admin client.
There are 2 typical scenarios for additional client registration
bootstraps:
Demo or test with vanilla code and no custom uaa.yml. A UAA
service started with no active Spring profile will start with some
client registrations (used in samples to make the out-of-the box
experience for new users as convenient as possible). More clients and
user accounts will be created by the integration tests.
A vcap environment: integration testing or in production. By
default no clients are created if any Spring profile is active, but
client registrations can be configured in uaa.yml and in some
well-known situations clients this will happen. In particular, the
dev_setup environment and the CF.com deployment job both start up
with additional client registrations that are needed by the basic
Cloud Foundry use cases (vmc and cloud_controller). If the
vcap Spring profile is active in the integration tests, no additional
accounts will be created.
Clients are bootstrapped from config if they are not present in the
backend when the system starts up (i.e. once the system has started up
once, config changes will not affect the client registrations for
existing clients). Certain fields (e.g. secret) can be reset if the
bootstrap component is configured to do so (it is not by default).
The admin client has the following properties (in the default
uaa.yml always present on the classpath but overriddable by
specifying all the values again in a custom config file):
The admin client can be used to bootstrap the system by adding
additional clients. In particular, user accounts cannot be
provisioned until a client with access to the scim resource is
added.
Demo Environment
The default Spring profile initializes 3 clients in addition to the
admin client, e.g. if the server is started from the command line
after a fresh clone from github for demo purposes:
The cloud controller secret is generated during the setup. The same
clients are initialized in CF.com, but the secret is different.
Additional clients can be added during start up using uaa.yml, e.g.
When a client application asks for a new access token it can
optionally provide a set of requested scopes (space separated,
e.g. scope=openid cloud_controller.read). The UAA will use that set
if provided and that will be the scope of the token if
granted. Otherwise, if no explicit value is requested, defaults will
be supplied according to what the client and user are allowed to do.
The rules governing the defaults and what is allowed are described
next.
User Tokens
A token granted on behalf of a user (grant type anything except
client_credentials) takes its default scopes from the scope field
of the client registration. Whether or not the default values are
used, the requested scopes are then validated:
The user's authorities (SCIM groups) are augmented with some static
values, configurable but defaulting to
[openid, cloud_controller.read, cloud_controller.write]
Allowed scopes consist of the intersection of the client scope and
the augmented user authorities.
Disallowed scopes are removed from the request.
If all the requested scopes are disallowed then clients get a 400
response with a JSON error message indicating the allowed values (for
implicit grants it should be a 302 according to the OAuth2 spec, but
that change hasn't been implemented yet). The exception to that rule
is for clients with no registered scopes (no error in that case), but
there shouldn't be any such clients in a production system.
Note that the filtering of scopes by user authorities might mean that
a client gets a narrower-scoped token than it originally asked for,
e.g. if it asks for no scope=dash.admin dash.user openid, the token
might come back with only dash.user openid. Tokens are opaque to
client applications, so they have to be prepared for resource servers
to deny access to some resources based on the scope of the token when
it is presented.
Client Tokens
A token issued on a client_credentials grant has default and allowed
scopes equal to the client authorities. Requesting a disallowed scope
will result in a 400 reponse and an error message that indicates the
allowed scopes. A client would normally take the default scopes when
acting on its own behalf - since no approval is necessary there is no
point narrowing the scope.
All OAuth2 protected resource have an id (as listed individually).
Any request whose token does not have a matching resource id (aud
field in decoded token) will be rejected. Resources that are not
OAuth2 protected resources do not have a resource id (e.g. those with
simple HTTP Basic authentication).
Token Management
Resource ID = tokens. Rules:
Revoke user token:
Token has scope uaa.admin, or
If token represents user, user is authenticated and is the owner
of the token to be revoked, and token has scope tokens.write
List user tokens:
Token has scope uaa.admin or
If token represents user, user is authenticated and is the owner
of the token to be read, and token has scope tokens.read
Revoke client token:
Token has scope uaa.admin or
Token represents the client in the token to be revoked, and token
has scope tokens.write
List client tokens:
Token has scope uaa.admin or
Token represents the client in the token to be revoked, and token
has scope tokens.read
Client Registration
Resource ID = clients. Rules:
Remove, update or add client registration
Token has scope clients.write
Inspect client registration
Token has scope clients.read
Client Secret Mangagement
Resource ID null (so all clients can change their password). Rule:
Change secret
Token has scope clients.secret
Either token has scope uaa.admin or client can only change its own secret
Either token has scope uaa.admin or client provides the old secret
Even if token has scope uaa.admin client must provide the old value to change its own secret
Password Change
Resource ID = password. Rules:
Change password
Token has scope password.write
If token represents a client, scope includes uaa.admin
If token represents a user, either scope includes uaa.admin or user provides the old password
User Account Management
Resource ID = scim. Rules:
List or search users
Token with scope scim.read provides read/query access to ALL users in the UAA
Delete, add user account
Token has scope scim.write
Update existing user account
Token with scope scim.write lets you update ANY user's information in the UAA
In addition, a User Token obtained by a client with authorities scim.me (eg. token from authorization_code
or password grant flow) provides read/query/update access to that particular user's account.
Username from ID Queries
Resource ID = scim. Rules:
Obtain username information via /ids/Users
filter parameter must be supplied
Only attributes userName and id are returned (and can be queried on)
User Profiles
Used for Single Sign On ( OpenID Connect lite ). Resource ID = openid. Rules:
The UAA is the identity management service for Cloud Foundry. It's
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.
Quick Start
If this works you are in business:
$ git clone git://github.com/cloudfoundry/uaa.git
$ cd uaa
$ mvn install
Each module has a mvn tomcat:run target to run individually, or you
could import them as projects into STS (use 2.8.0 or better if you
can). The apps all work together the apps running on the same port
(8080) as /uaa, /app and /api.
You will need Maven 3.0.4 or newer.
Deploy to Cloud Foundry
You can also build the app and push it to Cloud Foundry, e.g.
(or leave out the username / password to be prompted).
This authenticates and obtains an access token from the server using
the OAuth2 implicit grant, similar to the approach intended for a
client like VMC. The token is stored in ~/.uaac.yml, so dig into
that file and pull out the access token for your vmc target (or use
--verbose on the login command line above to see it logged to your
console).
Then you can login as a resource server and retrieve the token
details:
The same command line example should work against a UAA running on
cloudfoundry.com (except for the token decoding bit because you won't
have the client secret). In this case, there is no need to run a local
uaa server, so simply ask the external login endpoint to tell you
about the system:
(or leave out the username / password to be prompted).
This authenticates and obtains an access token from the server using the OAuth2 implicit
grant, the same as used by a client like VMC.
Integration tests
With all apps deployed into a running server on port 8080 the tests
will include integration tests (a check is done before each test that
the app is running). You can deploy them in your IDE or using the
command line with mvn tomcat:run and then run the tests as normal.
For individual modules, or for the whole project, you can also run
integration tests and the server from the command line in one go with
$ mvn test -P integration
(This might require an initial mvn install from the parent directory
to get the wars in your local repo first.)
To make the tests work in various environments you can modify the
configuration of the server and the tests (e.g. the admin client)
using a variety of mechanisms. The simplest is to provide additional
Maven profiles on the command line, e.g.
$ (cd uaa; mvn test -P vcap)
will run the integration tests against a uaa server running in a local
vcap, so for example the service URL is set to uaa.vcap.me (by
default). There are several Maven profiles to play with, and they can
be used to run the server, or the tests or both:
local: runs the server on the ROOT context http://localhost:8080/
vcap: also runs the server on the ROOT context and points the
tests at uaa.vcap.me.
devuaa: points the tests at http://devuaa.cloudfoundry.com (an
instance of UAA deployed on cloudfoundry).
All these profiles set the CLOUD_FOUNDRY_CONFIG_PATH to pick up a
uaa.yml and (if appropriate) set the context root for running the
server (see below for more detail on that).
BVTs
There is a really simple cucumber feature spec (--tag @uaa) to
verify that the UAA server is there. There is also a rake task to
launch the integration tests from the uaa submodule in vcap.
Typical usage for a local (uaa.vcap.me) instance:
$ cd vcap/tests
$ rake bvt:run_uaa
You can change the most common important settings with environment
variables (see below), or with a custom uaa.yml. N.B. MAVEN_OPTS
cannot be used to set JVM system properties for the tests, but it can
be used to set memory limits for the process etc.
Custom YAML Configuration
To modify the runtime parameters you can provide a uaa.yml, e.g.
The integration tests look for a Yaml file in the following locations
(later entries override earlier ones), and the webapp does the same
when it starts up so you can use the same config file for both:
To test against a vcap instance use the Maven profile vcap (it
switches off some of the tests that create random client and user
accounts):
$ (cd uaa; mvn test -P vcap)
To change the target server it should suffice to set
VCAP_BVT_TARGET (the tests prefix it with uaa. to form the
server url), e.g.
$ VCAP_BVT_TARGET=appcloud21.dev.mozycloud mvn test -P vcap
You can also override some of the other most important default
settings using environment variables. The defaults as usual come from
uaa.yml but tests will search first in an environment variable:
UAA_ADMIN_CLIENT_ID the client id for bootstrapping client
registrations needed for the rest of the tests.
UAA_ADMIN_CLIENT_SECRET the client secret for bootstrapping client
registrations
All other settings from uaa.yml can be overridden individually as
system properties. Running in an IDE this is easy just using whatever
features allow you to modify the JVM in test runs, but using Maven you
have to use the argLine property to get settings passed onto the
test JVM, e.g.
$ mvn -DargLine=-Duaa.test.username=foo test
will create an account with userName=foo for testing (instead using
the default setting from uaa.yml).
If you prefer environment variables to system properties you can use a
custom uaa.yml with placeholders for your environment variables,
e.g.
uaa:
test:
username: ${UAA_TEST_USERNAME:marissa}
will look for an environment variable (or system property)
UAA_TEST_USERNAME before defaulting to marissa. This is the trick
used to expose UAA_ADMIN_CLIENT_SECRET etc. in the standard
configuration.
Using Maven with to test with postgresql or mysql
The default uaa unit tests (mvn test) use hsqldb.
To run the unit tests using postgresql:
$ SET SPRING_PROFILES_ACTIVE=test,postgresql
& SET CLOUD_FOUNDRY_CONFIG_PATH=src/test/resources/test/profiles/postgresql
& mvn test
To run the unit tests using mysql:
$ SET SPRING_PROFILES_ACTIVE=test,mysql
$ SET CLOUD_FOUNDRY_CONFIG_PATH=src/test/resources/test/profiles/mysql
& mvn test
The database configuration for the common and scim modules is located at:
common/src/test/resources/(mysql|postgresql).properties
scim/src/test/resources/(mysql|postgresql).properties
Inventory
There are actually several projects here, 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 actual UAA server
gem is a ruby gem (cf-uaa-client) for interacting with the UAA 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
login (sample) is an application that performs authentication for the UAA acting as a back end service
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.
login is where Cloud Foundry administrators set up their
authentication sources, e.g. LDAP/AD, SAML, OpenID (Google etc.) or
social. The cloudfoundry.com platform uses a different
implementation of the
login server.
UAA Server
The authentication service is uaa. It's a plain Spring MVC webapp.
Deploy as normal in Tomcat or your container of choice, or execute
mvn tomcat:run to run it directly from uaa directory in the source
tree (make sure the common jar is installed first using mvn install
from the common subdirectory or from the top level directory). When
running with maven it listens on port 8080.
The UAA Server supports the APIs defined in the UAA-APIs document. To summarise:
The OAuth2 /authorize and /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.
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.
Authentication can be performed by command line clients by submitting
credentials directly to the /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.
By default uaa will launch with a context root /uaa. There is a
Maven profile local to launch with context root /, and another
called vcap to launch at / with a postgresql backend.
Configuration
There is a uaa.yml 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 users: marissa has password
koala.
To use Postgresql for user data, activate one of the Spring profiles
hsqldb or postgresql.
The active profiles can be configured in uaa.yml using
spring_profiles: postgresql
or by passing the spring.profiles.active parameter to the JVM. For,
example to run with an embedded HSQL database:
To bootstrap a microcloud type environment you need an admin client.
For this there is a database initializer component that inserts an
admin client. If the default profile is active (i.e. not
postgresql) there is also a vmc client so that the gem login works
out of the box. You can override the default settings and add
additional clients in uaa.yml:
The admin client can be used to create additional clients (but not to
do anything much else). A client with read/write access to the scim
resource will be needed to create user accounts. The integration
tests take care of this automatically, inserting client and user
accounts as necessary to make the tests work.
The API Application
An example resource server. It hosts a service which returns
a list of mock applications under /apps.
Run it using mvn tomcat:run from the api directory (once all other
tomcat processes have been shutdown). This will deploy the app to a
Tomcat manager on port 8080.
The App 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, and then accesses
resources in the API service. Run it with mvn tomcat:run from the
app directory (once all other tomcat processes have been shutdown).
The application can operate in multiple different profiles according
to the location (and presence) of the UAA server and the Login
application. By default it will look 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 (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 and the naming convention
adopted is that the UAA_PROFILE is local for the localhost
deployment, vcap for a vcap.me deployment, staging for a staging
deployment (inside VMware VPN), etc. The profile names are double
barrelled (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
The 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. The Login app can be branded and customized for
non-native authentication and for more complicate UI flows, like user
registration and password reset.
The login application is actually itself an OAuth2 endpoint provider,
but delegates those features to the UAA server. Configuration for the
login application therefore 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,
e.g. for a local vcap instance:
and there is 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 (so not
at all in vcap). In the UAA you can find the registration in the
oauth-clients.xml config file. Here's a summary:
The sample app presents a form login interface for the backend
UAA, and also an OpenID widget so the user can authenticate using
Google etc. credentials.
Approve OAuth2 token grant
GET /oauth/authorize?client_id=app&response_type=code...
Standard OAuth2 Authorization Endpoint. Client credentials and
all other features are handled by the UAA 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.
Handles authentication on cloudfoundry.com and delegates all other
identity management tasks to the UAA. Also provides OAuth2 endpoints
issuing tokens to client apps for cloudfoundry.com (the tokens come
from the UAA and no data are stored locally).
Running and Testing the Login Server
The Login Server is a standard JEE servlet application, and you can
build a war file and deploy it to any container you like (mvn package and look in the target directory). For convenience there
is also a Maven profile that will run the Login Server, the UAA and
some sample apps all in the same container from the command line
(assuming you have the UAA and Login Server cloned in separate
directories with a common parent):
(Note that the tomcat7 plugin at the moment does not support running
multiple apps in the same container - it's a bug that is fixed but not
released as of September 2012.)
You can run the Login Server integration tests using the command line
as well (as long as the UAA project is built and installed first as
above):
is separate from the UAA but needs to be connected to one via HTTP(S)
provides SSO for web applications in the Cloud Foundry platform
manages and provides a branded HTML UI for authentication and OAuth
approval
provides some other features via JSON APIs
Login Form: GET /login
Request: GET /login?error={error}
Response Body: form with all the relevant prompts
Response Codes: 200 - Success
Form Login: POST /login.do
Browser POSTs to /login.do with user credentials (same as UAA).
Login Server returns a cookie that can be used to authenticate future
requests (until the session expires or the user logs out).
Logout: GET /logout.do
The Login Server is a Single Sign On server for the Cloud Foundry
platform (and possibly user apps as well), so if a user logs out he
logs out of all the apps. Users need to be reminded of the
consequences of their actions, so the recommendation for application
authors is to
provide a local logout feature specific to the client application
and use that to clear state in the client
on the success page for that logout provide a link to the Login
Server logout endpoint with a message telling the user what will
happen if he clicks it
provide a redirect in the link to the logout endpoint (see below) so
that the user come back to a familiar place when logged out,
otherwise he will just get the logged out success page from the
Login Server
Request: GET /logout.do?redirect=http://myclient/loggedout
Request Headers: Cookie: JSESSIONID=8765FDUAYSFT7897
Response Codes:
200 - OK (if no redirect supplied)
302 - FOUND (if redirect supplied)
OAuth2 Endpoints
The standard authorize and token endpoints are available on the Login
Server. They are passed through the request to the UAA, getting JSON
responses from the UAA and re-rendering them if the user requested
HTML.
Start Authorization: GET /oauth/authorize
Client applications usually send a redirect to User's browser with the
request URI appropriate to the Client. Exactly the same as the UAA,
but the response is rendered differently.
Request: example
GET /oauth/authorize?response_type=code&
redirect_uri=https://myclient/callback&
client_id=myclient&
state=RANDOM
The request must be authenticated as a user, so usually a session
cookie (JSESSIONID) is required, having been obtained previously
through the Login page.
Obtain Authorization Code: POST /oauth/authorize
Exactly the same as the UAA. When user approves the browser sends
user_oauth_approval=true (or false) and the Login Server sends back
an authorization code (if one was previously requested).
Token Endpoint: POST /oauth/token
Obtain an access token, typically either with an authorization code or
client credentials. Exactly the same as the UAA.
Login Info: GET /login
Reports basic information about the build (version and git commit id)
and also passes through the information about prompts from the UAA.
Unauthenticated.
Healthz: GET /healthz
Returns "ok" in the response body if the server is up and running
Varz: GET /varz
Reports basic management information about the Login Server and the
JVM it runs in (memory usage etc.). Secured with HTTP Basic
authentication using credentials that are advertised on NATS in Cloud
Foundry (for a standalone instance the default is
varz:varzclientsecret).
For user-facing account management UIs (e.g. portal) that need to set
or reset users' passwords it is convenient to be able to log them in
immediately, rather than waiting for them to come back to the Login
Server and enter the new password explicitly.
Client POSTs user credentials to /autologin
Login Server responds with autologin code (short-lived, one-time)
Client builds redirect URI to Login Server /authorize endpoint
(normal OAuth2 auth code flow) appending the code
Client sends redirect to User
User's browser initiates auth code flow
Login Server redeems autologin code and exchanges it for an
authenticated user (as if the user had authenticated with the Login
Server manually)
User's browser now has SSO cookie for Login Server, and remains
logged in for the duration of that session.
Obtain Autologin Code: POST /autologin
Gets a short-lived code that can be exchanged for an authentication at
the Login Server /oauth/authorize UI. The client authenticates
itself with its secret using an HTTP Basic header.
Request: POST /autologin
Request Body: Form encoded user credentials
username=<username>&password=<password>
Request Headers:
Authorization: Basic <...>
Response Body:
{ "code"="aiuynklj", "path"="/oauth/authorize" }
By default the password is required and is checked using the
login.do endpoint at the UAA, but could be made optional or changed
to other authentication credentials with a configuration change in the
Login Server (by adding a different AuthenticationManager to the
AutologinController).
The client keeps track of the browser through a cookie to track its
http(s) session. The refresh and access tokens are kept private and not
shared directly with the browser.
This flow takes place after the authentication flow above. The browser
can now make a request to the portal. The portal looks up the
appropriate token from the session and uses it to make the request.
The login server component is separate from UAA so it can present an
appropriate visual rendering of the login page and authentication
interfaces.
The login server also has additional logic to support the autologin
flow. This is to allow a client to sign in on behalf of the user using
the client’s own credentials. This is needed when a user needs to be
signed in after resetting his password.
These apply if you are developing identity integration in your own
application, outside a bosh deployment scenario.
Requirements:
maven 3.0.4
java >= 1.6
Older versions of maven will likely appear to work at first but
eventually fail with an unhelpful error. Be sure mvn -v reports 3.0.4.
It’s best if you only have one version installed.
Clone, build UAA server:
git clone [email protected]:cloudfoundry/uaa.git
cd uaa
mvn clean install
Note the version number that you just built (e.g. look in the pom or in
uaa/target for the version label on the WAR file).
Clone, build login-server:
git clone [email protected]:cloudfoundry/login-server.git
cd login-server
mvn clean install
Run Servers (using the UAA version <X> from above):
cd login-server && mvn tomcat:run -P integration
You can add -Didentity.version=<X> if you need to match a specific UAA build.
uaa.yml drives uaa behavior. There is a default file in the WAR that
you should not touch. Overrides and additions can come from an external
location, the most convenient way to specify that is through an
environment variable (or system property in the JVM):
$CLOUDFOUNDRY_CONFIG_PATH/uaa.yml.
UAA will use an in-memory database that is torn down between runs unless
you choose a spring profile or a specific database configuration as a
toplevel setting in uaa.yml. An example connecting to a postgres
database:
Specify autoapprove in the client section when the user should not be
asked to approve a token grant expicitly. This
avoids redundant and annoying requests to grant permission when there is
not a reasonable need to ever deny them.
Override defaults to false; when true, the client settings in this
section can override client settings saved if you have a persistent
database. It’s recommended to have this property present and set to
true; declare it as false only if you need the db to take precedence.
uaa.yml entries can used to set up users for development. This is not
suitable for staging or production but useful in testing. If you specified
a persistent db above and the
user account exists, it may not be updated with a new password.
Group membership will be updated automatically in a future release.
scim is a toplevel attribute in uaa.yml. Login, password, and groups can
be defined on the new user.
A scope cannot be added to a token granted by the UAA unless the user is
in the corresponding group with the same name (some default groups are
always available and do not need to be explicitly populated: openid,
password.write, cloud_controller.read, cloud_controller.write,
tokens.read, tokens.write).
You should examine the steps of the flow you are expecting and find
the point at which it misbehaves. If any one point in the flow is broken, for example an
endpoint misconfigured or an identity test failing, you will see the
flow break down at that point.
vms to look at are uaa, login, and the vm with your client application.
Go the uaa machine to monitor logs with:
bosh ssh uaa 0
tail -f /var/vcap/sys/log/uaa/uaa.log
You can watch headers to confirm the kind of flow you want with tcpdump,
for example if you ssh into the login server:
bosh ssh login 0
sudo tcpdump 'tcp port 80 and host uaa.cf116.dev.las01.vcsops.com' -i any -A
uaac and vmc can take a --trace option which shows each online interaction.
"uaa target" your uaa if you haven't already.
"uaac token decode" functions can be used to examine tokens.
Make sure attributes like scopes match what you expect.
This function can take a verification key to make sure the token is signed as you expect.
"uaac signing key" can be used to get the signing key the uaa server is using. Pass -c and -s
for a client to retrieve a symmetric key.
vmc and uaac each need a target. vmc points to a cloud controller and uaac to a uaa instance.
vmc target api.cf116.dev.las01.vcsops.com
uaac target uaa.cf116.dev.las01.vcsops.com # dev deployment
uaac target uaa.cfpartners.cloudfoundry.com # production
uaac target localhost:8080/uaa # local dev
uaac context will contain clients or an end user id. These are added to
your context after authenticating.
uaac token client get admin # default pass adminsecret
uaac token client get vmc
uaac token client get dashboard # get dashboard context
Learn about your context
uaac contexts # show your target and all contexts with it
You see scopes granted through this token. jti is a token identifier,
used for operations like deleting a token.
The vmc client can be used for user registrations:
vmc add-user --email [email protected] # prompts for new password
uaac users # examine all users
uaac user ids # look up user ids -- only works outside production
Tokens are signed by the UAA. Signatures are checked for validity. Get the configuration
of the UAA signing key if you are dealing with invalid token errors.
This will print the public key without requiring a password if using
public key verification:
uaac signing key
if access is denied, use client credentials that allow access to the symmetric key:
It is the responsibility of a Resource Server to extract information
about the user and client application from the access token and make
an access decision based on that information. This guide will help
authors of resource Servers and maintainers of client and user account
data to understand the range of information available and the kinds of
decisions that can be taken. The UAA itself is a Resource Server, so
the access decisions taken by the UAA are used as an example.
User accounts are either of type "user" or type "admin" (using the
SCIM type field from the core schema). These translate into granted
authorities, [uaa.user] or [uaa.admin,uaa.user] respectively, for
the purposes of access decisions within the UAA (i.e. admin users also
have the user role). Granted authorities are not directly visible to
Resource Servers, but they show up as scopes in the access tokens.
Resource Servers may choose to use this information as part of an
access decision, and this may be good enough for simple use cases
(e.g. users belong to a small number of relatively static roles), but
in general they will need to maintain their own acess decision data
since roles on UAA don't necessarily correspond to the same thing on a
Resource Server.
Support for SCIM groups is currently provided only through the
authorities attribute of the user object. Resource Servers that are
also SCIM clients can modify this attribute themselves, but it might
be better (and safer) if the data don't change much to have an admin
user or client do the role assignments. In any case it is recommended
that Resource Servers have sensible defaults for new users that have
not yet been assigned a role.
Bootstrap
There are 2 distinct scenarios:
Demo or test with vanilla code and no special environment. A UAA
service started with no active Spring profile will initialize a single
user account (marissa/koala).
A vcap environment: integration testing or in production. If the
service starts with any active Spring profile by default it will not
touch the user database. The SCIM endpoints can be used to provision
user accounts, once a client with the correct privileges has been
registered.
In either case additional user accounts and client registrations can
be bootstrapped at start up by providing some data in uaa.yml.
Example users:
The format for the user is
username|password|email|first_name|last_name(|comma-separated-authorities).
Remember that authorities are represented as groups in SCIM.
Account lockout policy
In its default configuration, the UAA does not lock accounts permanently
when a user repeatedly fails authentication. Instead it temporarily locks a
user out for a short period (5 minutes by default) after 5 failed logins
within the previous hour. The failure count is reset when a user
successfully authenticates.
OAuth Client Applications
Security Metadata
Client application meta data can be used by Resource Servers to make
an access decision, and by the Authorization Server (the UAA itself)
to decide whether to grant an access token.
Scope values are arbitrary strings, but are a contract between a
client and a Resource Server, so in cases where UAA acts as a Resource
Server there are some "standard" values (scim.read, scim.write,
passsword.write, openid, etc.) whose usage and meaning is
described below. Scopes are used by the Authorization Server to deny
a token requested for a scope not on the list, and should be used by a
Resource Server to deny access to a resource if the token has
insufficient scope.
UAA client applications have the following meta data (some are
optional, but to prevent mistakes it is usually better to use a
default value):
authorized-grant-types: a comma-separated list of OAuth2 grant
types, as defined in the spec: choose from client_credentials,
password, implicit, refresh_token, authorization_code. Used
by the Authorization Server to deny a token grant if it is not on
the list. If in doubt use authorization_code and refresh_token.
scope: a list of permitted scopes for this client to obtain on
behalf of a user (so not relevant to client_credentials grants).
Also used as the default scopes for a token where the client does
not explicitly specify scopes in the authorization request.
authorities: a list of granted authorities for the client
(e.g. uaa.admin or any valid scope value). The authorities are
used to define the default scopes that are assigned to a token in a
client_credentials grant, and to limit the legal values if
explicit scopes are requested in that case.
secret: the shared secret used to authenticate token grant requests
and token decoding operations (not revealed to Resource Server).
resource-ids: white list of resource ids to be included in the
decoded tokens granted to this client. The UAA does not store any
data here (it should be none for all clients), but instead creates
a list of resource ids dynamically from the scope values when a
token is granted. The resource id is extracted from a scope using a
period separator (the last occurrence in the string) except for some
standard values (e.g. openid) that are not controlled by the UAA
or its own resources. So a scope of cloud_controller.read is
assigned a resource id of cloud_controller, for instance.
Bootstrap
Client registration can be initialized by adding client details data
to uua.yml. The UAA always starts with a registered admin client.
There are 2 typical scenarios for additional client registration
bootstraps:
Demo or test with vanilla code and no custom uaa.yml. A UAA
service started with no active Spring profile will start with some
client registrations (used in samples to make the out-of-the box
experience for new users as convenient as possible). More clients and
user accounts will be created by the integration tests.
A vcap environment: integration testing or in production. By
default no clients are created if any Spring profile is active, but
client registrations can be configured in uaa.yml and in some
well-known situations clients this will happen. In particular, the
dev_setup environment and the CF.com deployment job both start up
with additional client registrations that are needed by the basic
Cloud Foundry use cases (vmc and cloud_controller). If the vcap
Spring profile is active in the integration tests, no additional
accounts will be created.
Clients are bootstrapped from config if they are not present in the
backend when the system starts up (i.e. once the system has started up
once config changes will not affect the client registrations for
existing clients). Certain fields (e.g. secret) can be reset if the
bootstrap component is configured to do so (it is not by default).
The admin client has the following properties (in the default
uaa.yml always present on the classpath but overriddable by
specifying all the values again in a custom config file):
The admin client can be used to bootstrap the system by adding
additional clients. In particular, user accounts cannot be
provisioned until a client with access to the scim resource is
added.
Demo Environment
The default Spring profile initializes 3 clients in addition to the
admin client, e.g. if the server is started from the command line
after a fresh clone from github for demo purposes:
The cloud controller secret is generated during the setup. The same
clients are initialized in CF.com, but the secret is different.
Additional clients can be added during start up using uaa.yml, e.g.
When a client application asks for a new access token it can
optionally provide a set of requested scopes (space separated,
e.g. scope=openid cloud_controller.read). The UAA will use that set
if provided and that will be the scope of the token if
granted. Otherwise, if no explicit value is requested, defaults will
be supplied according to what the client and user are allowed to do.
The rules governing the defaults and what is allowed are described
next.
User Tokens
A token granted on behalf of a user (grant type anything except
client_credentials) takes its default scopes from the scope field
of the client registration. Whether or not the default values are
used, the requested scopes are then validated:
The user's authorities (SCIM groups) are augmented with some static
values, configurable but defaulting to
[openid, cloud_controller.read, cloud_controller.write]
Allowed scopes consist of the intersection of the client scope and
the augmented user authorities.
Disallowed scopes are removed from the request.
If all the requested scopes are disallowed then clients get a 400
response with a JSON error message indicating the allowed values (for
implicit grants it should be a 302 according to the OAuth2 spec, but
that change hasn't been implemented yet). The exception to that rule
is for clients with no registered scopes (no error in that case), but
there shouldn't be any such clients in a production system.
Note that the filtering of scopes by user authorities might mean that
a client gets a narrower-scoped token than it originally asked for,
e.g. if it asks for no scope=dash.admin dash.user openid, the token
might come back with only dash.user openid. Tokens are opaque to
client applications, so they have to be prepared for resource servers
to deny access to some resources based on the scope of the token when
it is presented.
Client Tokens
A token issued on a client_credentials grant has default and allowed
scopes equal to the client authorities. Requesting a disallowed scope
will result in a 400 reponse and an error message that indicates the
allowed scopes. A client would normally take the default scopes when
acting on its own behalf - since no approval is necessary there is no
point narrowing the scope.
UAA Resources
All OAuth2 protected resource have an id (as listed individually).
Any request whose token does not have a matching resource id (aud
field in decoded token) will be rejected. Resources that are not
OAuth2 protected resources do not have a resource id (e.g. those with
simple HTTP Basic authentication).
Token Management
Resource ID = tokens. Rules:
Revoke user token:
Token has scope uaa.admin, or
If token represents user, user is authenticated and is the owner
of the token to be revoked, and token has scope tokens.write
List user tokens:
Token has scope uaa.admin or
If token represents user, user is authenticated and is the owner
of the token to be read, and token has scope tokens.read
Revoke client token:
Token has scope uaa.admin or
Token represents the client in the token to be revoked, and token
has scope tokens.write
List client tokens:
Token has scope uaa.admin or
Token represents the client in the token to be revoked, and token
has scope tokens.read
Client Registration
Resource ID = clients. Rules:
Remove, update or add client registration
Token has scope clients.write
Inspect client registration
Token has scope clients.read
Client Secret Mangagement
Resource ID null (so all clients can change their password). Rule:
Change secret
Token has scope clients.secret
Either token has scope uaa.admin or client can only change its own secret
Either token has scope uaa.admin or client provides the old secret
Even if token has scope uaa.admin client must provide the old value to change its own secret
Password Change
Resource ID = password. Rules:
Change password
Token has scope password.write
If token represents a client, scope includes uaa.admin
If token represents a user, either scope includes uaa.admin or user provides the old password
User Account Management
Resource ID = scim. Rules:
List or search users
Token with scope scim.read provides read/query access to ALL users in the UAA
Delete, add user account
Token has scope scim.write
Update existing user account
Token with scope scim.write lets you update ANY user's information in the UAA
In addition, a User Token obtained by a client with authorities scim.me (eg. token from authorization_code
or password grant flow) provides read/query/update access to that particular user's account.
Username from ID Queries
Resource ID = scim. Rules:
Obtain username information via /ids/Users
filter parameter must be supplied
Only attributes userName and id are returned (and can be queried on)
User Profiles
Used for Single Sign On (OpenID Connect lite). Resource ID = openid. Rules:
Obtain user profile data
Token has scope openid
Groups & Membership Management
Resource ID = scim. Rules:
List or Search groups
Token has scope scim.read
Delete or Add groups
Token has scope scim.write
Update group name or add/remove members
Token has either scim.write OR groups.update
In addition, a User Token obtained by a client with authorities scim.me (eg. token from authorization_code
or password grant flow) provides the following access:
List or Search groups
Response contains the group(s) that lists the user as a reader.
Update group name or add/remove members
The user is listed as a writer in the group being updated.
Token Resources for Providers
The UAA uses HTTP Basic authentication for these resources, so they
are no OAuth2 protected resources, but to simplify the security data
client registrations are used, so only registered clients can access
them. The caller must have a secret (so vmc and other implicit
grant clients need not apply).
Obtain access token at /oauth/token
Client is authenticated
If grant type is authorization_code client must have the code
Inspect access token at /check_token
Client is authenticated
Client has authority uaa.resource
Obtain token key (for decoding JWT tokens locally) at /token_key
Client is authenticated
Client has authority uaa.resource
Management Information
The /varz endpoint is protected by HTTP Basic authentication with
credentials that are externalized via uaa.yml. They have defaults
(varz:varzclientsecret) and can also be overridden via System
properties.
Login Prompts
The login endpoint is unsecured. Any client can ask it and it will
respond with some information about the system and the login prompts
required to authenticate.
The User Account and Authentication Service (UAA):
is a separate application from the Cloud Controller
owns the user accounts and authentication sources
is called via JSON APIs
supports standard protocols to provide single sign-on and delegated authorization to web applications in addition to JSON APIs to support the Cloud Controller and team features of Cloud Foundry
supports APIs and a basic login/approval UI for web client apps
supports APIs for user account management for an external web UI (i.e. www.cloudfoundry.com)
Rather than trigger arguments about how RESTful these APIs are we'll just refer to them as JSON APIs. Most of them are defined by the specs for the OAuth2, OpenID Connect, and SCIM standards.
Several modes of operation and other optional features can be set in configuration files. Settings for a handful of standard scenarios can be externalized and switched using environment variables or system properties.
Internal username/password authentication source
The UAA manages a user account database. These accounts can be used for password based authentication similar to existing Cloud Foundry user accounts. The UAA accounts can be configured with password policy such as length, accepted/required character types, expiration times, reset policy, etc.
Other Authentication sources
Other standard external authentication sources can also be used. The most common and therefore the expected starting point are LDAP server, or an external OpenID provider (e.g. Google). Another expected authentication source would be Horizon Application Manager either through OAuth2 (preferred), or SAML protocols. General SAML2 support is not currently planned but could be added and would provide capabilities similar to OpenID and OAuth.
This section deals with machine interactions, not with browsers, although some of them may have browsable content for authenticated users. All machine requests have accept headers indicating JSON (or a derived media type perhaps).
The /userinfo, /check_id, and /token endpoints are specified in the OpenID Connect and OAuth2 standards and should be used by web applications on a cloud foundry instance such as micro, www, support, but will not be used by flows from vmc.
The OAuth2 spec includes a scope parameter as part of the token granting request which contains a set of scope values. The spec leaves the business content of the scope up to the participants in the protocol - i.e. the scope values are completely arbitrary and can in principle be chosen by any Resource Server using the tokens. Clients of the Resource Server have to ask for a valid scope to get a token, but the Authorization Server itself attaches no meaning to the scope - it just passes the value through to the Resource Server. The UAA implementation of the Authorization Server has a couple of extra scope-related features (by virtue of being implemented in Spring Security where the features originate).
There is an optional step in client registration, where a client declares which scopes it will ask for, or alternatively where the Authorization Server can limit the scopes it can ask for. The Authorization Server can then check that token requests contain a valid scope (i.e. one of the set provided on registration).
The Resource Servers can each have a unique ID (e.g. a URI). And another optional part of a client registration is to provide a set of allowed resource ids for the client in question. The Authorization Server binds the allowed resource ids to the token and then provides the information via the /check_token endpoint (in the aud claim), so that a Resource Server can check that its own ID is on the allowed list for the token before serving a resource.
Resource IDs have some of the character of a scope, except that the clients themselves don't need to know about them - it is information exchanged between the Authorization and Resource Servers. The examples in this document use a scope parameter that indicates a resource server, e.g. a Cloud Controller instance. This is a suggested usage, but whether it is adopted by the real Cloud Controller is not crucial to the system. Similarly any Resource Server that wants to can check the allowed resource IDs if there are any, but it is not mandatory to do so.
Request Body: some parameters specified by the spec, appended to the query component using the application/x-www-form-urlencoded format,
response_type=code
client_id=www
scope=read write password
redirect_uri is optional because it can be pre-registered
Request Header:
Cookie: JSESSIONID=ADHGFKHDSJGFGF; Path / - the authentication cookie for the client with UAA. If there is no cookie user's browser is redirected to /login, and will eventually come back to /oauth/authorize.
Response Header: location as defined in the spec includes access_token if successful:
HTTP/1.1 302 Found
Location: https://www.cloudfoundry.example.com?code=F45jH
If the client asks for a JSON response (with an Accept header), and
the user has not approved the grant yet, the UAA sends a JSON object
with some useful information that can be rendered for a user to read
and explicitly approve the grant:
{
"message":"To confirm or deny access POST to the following locations with the parameters requested.",
"scopes":[
{"text":"Access your data with scope 'openid'","code":"scope.openid"},
{"text":"Access your 'cloud_controller' resources with scope 'read'","code":"scope.cloud_controller.read"},
...],
...,
"client_id":"idtestapp",
"redirect_uri":"http://nowhere.com",
"options":{
"deny":{"location":"https://uaa.cloudfoundry.com/oauth/authorize","value":"false","path":"/oauth/authorize","key":"user_oauth_approval"},
"confirm":{"location":"https://uaa.cloudfoundry.com/oauth/authorize","value":"true","path":"/oauth/authorize","key":"user_oauth_approval"}
}
}
The most useful information for constructing a user approval page is
the list of requested scopes, the client id and the requested redirect
URI.
An OAuth2 defined endpoint to provide various tokens and authorization codes.
For the vmc flows, we use the OAuth2 Implicit grant type (to avoid a second round trip to /token and so vmc does not need to securely store a client secret or user refresh tokens). The authentication method for the user is undefined by OAuth2 but a POST to this endpoint is acceptable, although a GET must also be supported (see OAuth2 section 3.1).
Effectively this means that the endpoint is used to authenticate and obtain an access token in the same request. Note the correspondence with the UI endpoints (this is similar to the /login endpoint with a different representation).
Note
A GET mothod is used in the relevant section of the spec that talks about the implicit grant, but a POST is explicitly allowed in the section on the /oauth/authorize endpoint (see OAuth2 section 3.1).
All requests to this endpoint MUST be over SSL.
Request: POST /oauth/authorize
Request query component: some parameters specified by the spec, appended to the query component using the "application/x-www-form-urlencoded" format,
response_type=token
client_id=vmc
scope=read write
redirect_uri - optional because it can be pre-registered, but a dummy is still needed where vmc is concerned (it doesn't redirect) and must be pre-registered, see Client Registration Administration APIs.
Request body: contains the required information in JSON as returned from the login information API, e.g. username/password for internal authentication, or for LDAP, and others as needed for other authentication types. For example:
This works similarly to the previous section, but does not require the credentials to be POSTed as is needed for browser flows.
The browser redirects to the /oauth/authorize endpoint with parameters in the query component as per the previous section.
The UAA presents the UI to authenticate the user and approve the scopes.
If the user authorizes the scopes for the requesting client, the UAA will redirect the browser to the redirect_uri provided (and pre-registered) by the client.
Since the reply parameters are encoded in the location fragment, the client application must get the access token in the reply fragment from user's browser -- typically by returning a page to the browser with some javascript which will post the access token to the client app.
In addition to the normal authentication of the /oauth/authorize endpoint described above (cookie-based for browser app and special case for vmc) the UAA offers a special channel whereby a trusted client app can authenticate itself and then use the /oauth/authorize endpoint by providing minimal information about the user account (but not the password). This channel is provided so that authentication can be abstracted into a separate "Login" server. The default client id for the trusted app is login, and this client is registered in the default profile (but not in any other):
To authenticate the /oauth/authorize endpoint using this channel the Login Server has to provide a standard OAuth2 bearer token header _and_ some additional parameters to identify the user: source=login is mandatory, as is username, plus optionally [email, given_name, family_name]. The UAA will lookup the user in its internal database and if it is found the request is authenticated. The UAA can be configured to automatically register authenicated users that are missing from its database, but this will only work if all the fields are provided. The response from the UAA (if the Login Server asks for JSON content) has enough information to get approval from the user and pass the response back to the UAA.
Using this trusted channel a Login Server can obtain authorization (or tokens directly in the implicit grant) from the UAA, and also have complete control over authentication of the user, and the UI for logging in and approving token grants.
An authorization code grant has two steps (as normal), but instead of a UI response the UAA sends JSON:
Request body: empty (or form encoded parameters as above)
Response header will include a cookie. This needs to be sent back in the second step (if required) so that the UAA can retrive the state from this request.
Response body if successful, and user approval is required (example):
HTTP/1.1 200 OK
{
"message":"To confirm or deny access POST to the following locations with the parames rqstd.",
"scopes":[
{"text":"Access your data with scope 'openid'","code":"scope.openid"},
{"text":"Access your 'password' resources with scope 'write'","code":"scope.password.write"},
...
],
"auth_request":{...}, // The authorization request
"client": {
"scope":[...],
"client_id":"app",
"authorized_grant_types":["authorization_code"],
"authorities":[...]
},
"redirect_uri": "http://app.cloudfoundry.com",
"options":{
"deny":{"value":"false","key":"user_oauth_approval",...},
"confirm":{"value":"true","key":"user_oauth_approval",...}
}
}
the response body contains useful information for rendering to a user for approval, e.g. each scope that was requested (prepended with "scope." to facilitate i18n lookups) including a default message text in English describing it.
Response Codes:
200 - OK
403 - FORBIDDEN (if the user has denied approval)
302 - FOUND (if the grant is already approved)
An endpoint that allows a resource server such as the cloud controller to validate an access token. Interactions between the resource server and the authorization provider are not specified in OAuth2, so we are adding this endpoint. The request should be over SSL and use basic auth with the shared secret between the UAA and the resource server (which is stored as a client app registration). The POST body should be the access token and the response includes the userID, user_name and scope of the token in json format. The client (not the user) is authenticated via basic auth for this call.
OAuth2 access tokens are opaque to clients, but can be decoded by resource servers to obtain all needed information such as userID, scope(s), lifetime, user attributes. If the token is encrypted witha shared sceret between the UAA are resource server it can be decoded without contacting the UAA. However, it may be useful -- at least during development -- for the UAA to specify a short, opaque token and then provide a way for the resource server to return it to the UAA to validate and open. That is what this endpoint does. It does not return general user account information like the /userinfo endpoint, it is specifically to validate and return the information represented by access token that the user presented to the resource server.
This endpoint mirrors the OpenID Connect /check_id endpoint, so not very RESTful, but we want to make it look and feel like the others. The endpoint is not part of any spec, but it is a useful tool to have for anyone implementing an OAuth2 Resource Server.
Request: uses basic authorization with base64(resource_server:shared_secret) assuming the caller (a resource server) is actually also a registered client:
The user_name is the same as you get from the OpenID Connect/userinfo endpoint. The user_id field is the same as you would use to get the full user profile from /Users.
Many of the fields in the response are a courtesy, allowing the caller to avoid further round trip queries to pick up the same information (e.g. via the /Users endpoint).
The aud claim is the resource ids that are the audience for the token. A Resource Server should check that it is on this list or else reject the token.
The client_id data represent the client that the token was granted for, not the caller. The value can be used by the caller, for example, to verify that the client has been granted permission to access a resource.
An OAuth2 defined endpoint which accepts authorization code or refresh tokens and provides access_tokens. The access_tokens can then be used to gain access to resources within a resource server.
An OpenID Connect defined endpoint. It accepts an id_token, which contains claims about the authentication event. It validates the token and returns information contained in the token in JSON format. Basically makes it so that clients do not need to have full token handling implementations.
An OAuth2 protected resource and an OpenID Connect endpoint. Given an appropriate access_token, returns information about a user. Defined fields include various standard user profile fields. The response may include other user information such as group membership.
An endpoint which returns login information, e.g prompts for authorization codes or one-time passwords. This allows vmc to determine what login information it should collect from the user.
UAA supports the SCIM standard for
these APIs and endpoints. These endpoints are themselves secured by OAuth2, and access decision is done based on the 'scope' and 'aud' fields of the JWT OAuth2 token.
The userName is unique in the UAA, but is allowed to change. Each user also has a fixed primary key which is a UUID (stored in the id field of the core schema).
200 - Updated successfully
400 - Bad Request
401 - Unauthorized
404 - Not found
Note
SCIM specifies that a password change is a PATCH, but since this isn't supported by many clients, we have used PUT. SCIM offers the option to use POST with a header override - if clients want to send X-HTTP-Method-Override they can ask us to add support for that.
Get information about a user. This is needed by to convert names and email addresses to immutable ids, and immutable ids to display names. The implementation provides the core schema from the specification, but not all attributes are handled in the back end at present (e.g. only one email address per account).
Filters: note that, per the specification, attribute values are comma separated and the filter expressions can be combined with boolean keywords ("or" and "and").
Request: GET /Users?attributes={requestedAttributes}&filter={filter}
Request Headers: Authorization header containing an OAuth2 bearer token with:
scope = scim.read
aud = scim
Response Body (for GET /Users?attributes=id&filter=emails.value eq [email protected]):
Authorization header containing an OAuth2 bearer token with:
scope = scim.write
aud = scim
If-Match the ETag (version id) for the value to delete
Request Body: Empty
Response Body: Empty
Response Codes:
200 - Success
401 - Unauthorized
404 - Not found
Deleting accounts is handled in the back end logically using the active flag, so to see a list of deleted users you can filter on that attribute (filters by default have it set to true), e.g.
Request: GET /Users?attributes=id,userName&filter=userName co 'bjensen' and active eq false
There is a SCIM-like endpoint for converting usernames to names, with the same filter and attribute syntax as /Users. It must be supplied with a filter parameter. It is a special purpose endpoint for use as a user id/name translation api, and is should be disabled in production sites by setting scim.userids_enabled=false in the UAA configuration. It will be used by vmc so it has to be quite restricted in function (i.e. it's not a general purpose groups or users endpoint). Otherwise the API is the same as /Users.
The password strength API is not part of SCIM but is provided as a service to allow user management applications to use the same password quality
checking mechanism as the UAA itself. Rather than specifying a set of rules based on the included character types (upper and lower case, digits, symbols etc), the UAA
exposes this API which accepts a candidate password and returns a JSON message containing a simple numeric score (between 0 and 10) and a required score
(one which is acceptable to the UAA). The score is based on a calculation using the ideas from the zxcvbn project.
The use of this API does not guarantee that a password is strong (it is currently limited to English dictionary searches, for example), but it will protect against some of
the worst choices that people make and will not unnecessarily penalise strong passwords. In addition to the password parameter itself, the client can pass a
comma-separated list of user-specific data in the userData parameter. This can be used to pass things like the username, email or other biographical
information known to the client which should result in a low score if it is used as part of the password.
Request: POST /password/score
POST /password/score HTTP/1.1
Host: uaa.example.com
Content-Type: application/x-www-form-encoded
In addition to SCIM users, UAA also supports/implements SCIM_groups for managing group-membership of users. These endpoints too are secured by OAuth2 bearer tokens.
The displayName is unique in the UAA, but is allowed to change. Each group also has a fixed primary key which is a UUID (stored in the id field of the core schema).
As for create operation, returns the entire, updated record, with the Location header pointing to the resource.
Response Codes:
200 - Updated successfully
400 - Bad Request
401 - Unauthorized
404 - Not found
As with the create operation, members.value sub-attributes MUST refer to a valid SCIM resource id in the UAA, i.e the UUID of a an existing SCIM user or group.
Note: SCIM also optionally supports partial update using PATCH, but UAA does not currently implement it.
Get information about a group, including its members and what roles they hold within the group itself, i.e which members are group admins vs. which members are just members, and so on.
Filters: note that, per the specification, attribute values are comma separated and the filter expressions can be combined with boolean keywords ("or" and "and").
Request: GET /Groups?attributes={requestedAttributes}&filter={filter}
Request Headers: Authorization header containing an OAuth2 bearer token with:
scope = scim.read
aud = scim
Response Body (for GET /Groups?attributes=id&filter=displayName eq uaa.admin):
OAuth2 protected resources which deal with listing and revoking access tokens. To revoke a token with DELETE clients need to provide a jti (token identifier, not the token value) which can be obtained from the token list via the corresponding GET. This is to prevent token values from being logged in the server (DELETE does not have a body).
An endpoint which returns the JWT token key, used by the UAA to sign JWT access tokens, and to be used by authorized clients to verify that a token came from the UAA.
This call is authenticated with client credentials using the HTTP Basic method.
Request
GET /token_key
Request body
empty
Response body
example
HTTP/1.1 200 OK
Content-Type: text/plain
{alg:HMACSHA256, value:FYSDKJHfgdUydsFJSHDFKAJHDSF}
The algorithm ("alg") tells the caller how to use the value (it is the
result of algorithm method in the Signer implementation used in the
token endpoint). In this case it is an HMAC (symmetric) key, but you
might also see an asymmetric RSA public key with algorithm
"SHA256withRSA").
Web app clients need UI endpoints for the OAuth2 and OpenID
redirects. Clients that do not ask for a JSON content type will get
HTML. Note that these UIs are whitelabeled and the branded versions
used in Cloud Foundry are deployed in a separate component (the Login Server).
The UAA can act as a Single Sign On server for the Cloud Foundry
platform (and possibly user apps as well), so if a user logs out he
logs out of all the apps.
Authentication is via HTTP basic using credentials that are configured
via varz.username and varz.password. The /varz endpoint pulls
data out of the JMX MBeanServer, exposing selected nuggets directly
for ease of use, and providing links to more detailed metrics.
More detailed metrics can be obtained from the links in /varz. All
except the env link (the OS env vars) are just the top-level domains
in the JMX MBeanServer. In the case of Catalina there are some
known cycles in the object graph which we avoid by restricting the
result to the most interesting areas to do with request processing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters