For authenticate the users, we need two things: user account records and an OAuth2 compatible authentication provider (server). There are many commercial OAuth2 authentication providers out there, but in this blog, I’m going to with open-source Cloud Foundry’s User Account & Authentication Server.
Spring Cloud Gateway can forward OAuth2 access tokens to the services it is proxying. In addition to logging in the user and grabbing a token, a filter extracts the access token for the authenticated user and puts it into a request header for downstream requests.”
The gateway will coordinate authentication with the single sign-on server on our behalf and ensure that downstream applications get a copy of the users access token when they need it.
In order to configure this feature, the first thing of note is the OAuth2 configuration in our gateway’s application.yml
file.
security:
oauth2:
client:
registration:
gateway:
provider: uaa
client-id: gateway
client-secret: secret
authorization-grant-type: authorization_code
redirect-uri-template: "{baseUrl}/login/oauth2/code/{registrationId}"
scope: openid,profile,email,resource.read
provider:
uaa:
authorization-uri: http://localhost:8181/uaa/oauth/authorize
token-uri: http://uaa:8181/uaa/oauth/token
user-info-uri: http://uaa:8181/uaa/userinfo
user-name-attribute: sub
jwk-set-uri: http://uaa:8181/uaa/token_keys
UAA OAuth2 provider
The primary role of User Account and Authentication (UAA) is as an OAuth2 provider, that’s issuing tokens for client apps to use when they act on behalf of Cloud Foundry users. In collaboration with the login server, UAA can authenticate users with their Cloud Foundry credentials, and can act as an SSO service using those, or other, credentials.
UAA has endpoints for managing user accounts and for registering OAuth2 clients, as well as various other management functions.
Deploy UAA on locally
Deploy and run UAA as locally:
- In a terminal window, clone the UAA GitHub repository by running:
>>git clone git://github.com/cloudfoundry/uaa.git
- Navigate to the directory where you cloned the UAA GitHub repository
- To build and run all the components that comprise UAA and the example programs
uaa
,samples/api
, andsamples/app
, run:>> ./gradlew run
- If successful, the three apps run together on a single instance of Tomcat listening on port 8080, with endpoints
/uaa
,/app
, and/api
.
Use UAA as local
To access and use a locally-deployed UAA server:
1. Open another terminal window. From the project base directory, run following commands and confirm the UAA is running
>> curl localhost:8080/uaa/info -H "Accept: application/json"
We can see basic information about the system.
For example:
$ curl localhost:8080/uaa/info -H "Accept: application/json" { "app": { "version": "4.19.0" }, "links": { "uaa": "http://localhost:8080/uaa", "passwd": "/forgot_password", "login": "http://localhost:8080/uaa", "register": "/create_account" }, "zone_name": "uaa", "entityID": "cloudfoundry-saml-login", "commit_id": "", "idpDefinitions": {}, "prompts": { "username": [ "text", "Email" ], "password": [ "password", "Password" ] }, "timestamp": "2022-02-25T03:34:14-0230" }
2. Install the Cloud Foundry UAA via Command Line Client (UAAC) Ruby gem, run:
>> gem install cf-uaac
3. To target the local UAA server endpoint, run:
>> uaac target http://localhost:8080/uaa
4. Run uaac token client get CLIENT_NAME -s CLIENT_SECRET
to obtain an access token. Replace CLIENT_NAME
and CLIENT_SECRET
with actual values.
For example, when starting up the UAA locally for development, there should be a predefined admin client you can use:uaac token client get admin -s adminsecret
If you run the command without -s CLIENT_SECRET
, UAAC shows an interactive prompt where you must create the client secret value. The uaac token client get
command requests an access token from the server using the OAuth2 client credentials grant type.
5. Your can View UAAC token context. When UAAC obtains a token, the token and other metadata is stored in the ~/.uaac.yml
file on local machine. To show the token we have obtained, run uaac context
.
For example:
$ uaac context
[0]*[http://localhost:8080/uaa]
[0]*[admin]
client_id: admin
access_token: <TOKEN>
token_type: bearer
expires_in: --
scope: clients.read clients.secret clients.write uaa.admin clients.admin scim.write scim.read
jti:
1c425e2a4a9f7f50eb166ceb2a9c
Run uaac token decode ACCESS-TOKEN-VALUE
to view information in the token, which is encoded using the JSON Web Token (JWT) format. Replace ACCESS-TOKEN-VALUE
with your access token, copied from the uaac context
output. The UAAC should display all the claims inside the token body. For example:
$ uaac token decode <TOKEN> Note: no key given to validate token signature jti: 7f5016e4411e6ca9cc4eb2ace89f25d4 sub: admin authorities: clients.read clients.secret clients.write uaa.admin clients.admin scim.write scim.read scope: clients.read clients.secret clients.write uaa.admin clients.admin scim.write scim.read client_id: admin cid: admin azp: admin grant_type: client_credentials rev_sig: ye287e83 iat: -- exp: -- iss: http://localhost:8080/uaa/oauth/token zid: uaa aud: scim clients uaa admin