How to Bootstrap an OAuth2 Authorization Server With UAA
Leveraging Cloud Foundry's UAA project can help get you started with putting up an OAuth2 authorization server — one that's lightweight but still very scalable.
Join the DZone community and get the full member experience.
Join For FreeI will cover using the UAA in two posts. In this post, I will go over how to get a local UAA server running and populate it with some of the actors involved in an OAuth2 authorization_code flow (i.e., clients and users), and in a follow-up post, I will show how to use thisauthorization server with a sample client application and in securing a resource.
Starting Up the UAA
The repository for the UAA project is here. Downloading the project is simple. Just clone this repo:
git clone https://github.com/cloudfoundry/uaa
If you have a local JDK available, start it up using:
./gradlew run
This version of UAA uses an in-memory database, so the test data generated will be lost on restart of the application.
Populate Some Data
An awesome way to interact with UAA is its companion CLI application, UAAC. Assuming that you have the UAAC CLI downloaded and UAA started up on its default port of 8080, let us start by pointing the UAAC to the UAA application:
uaac target http://localhost:8080/uaa
Log into it using one of the canned client credentials (admin/adminsecret
):
uaac token client get admin -s adminsecret
Now that a client has logged in, the token can be explored using:
uaac context
This would display the details of the token issued by UAA along these lines:
[3]*[http://localhost:8080/uaa]
[2]*[admin]
client_id: admin
access_token: eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJkOTliMjg1MC1iZDQ1LTRlOTctODIyZS03NGE2MmUwN2Y0YzUiLCJzdWIiOiJhZG1pbiIsImF1dGhvcml0aWVzIjpbImNsaWVudHMucmVhZCIsImNsaWVudHMuc2VjcmV0IiwiY2xpZW50cy53cml0ZSIsInVhYS5hZG1pbiIsImNsaWVudHMuYWRtaW4iLCJzY2ltLndyaXRlIiwic2NpbS5yZWFkIl0sInNjb3BlIjpbImNsaWVudHMucmVhZCIsImNsaWVudHMuc2VjcmV0IiwiY2xpZW50cy53cml0ZSIsInVhYS5hZG1pbiIsImNsaWVudHMuYWRtaW4iLCJzY2ltLndyaXRlIiwic2NpbS5yZWFkIl0sImNsaWVudF9pZCI6ImFkbWluIiwiY2lkIjoiYWRtaW4iLCJhenAiOiJhZG1pbiIsImdyYW50X3R5cGUiOiJjbGllbnRfY3JlZGVudGlhbHMiLCJyZXZfc2lnIjoiZTc4YjAyMTMiLCJpYXQiOjE0ODcwMzk3NzYsImV4cCI6MTQ4NzA4Mjk3NiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3VhYS9vYXV0aC90b2tlbiIsInppZCI6InVhYSIsImF1ZCI6WyJhZG1pbiIsImNsaWVudHMiLCJ1YWEiLCJzY2ltIl19.B-RmeIvYttxJOMr_CX1Jsinsr6G_e8dVU-Fv-3Qq1ow
token_type: bearer
expires_in: 43199
scope: clients.read clients.secret clients.write uaa.admin clients.admin scim.write scim.read
jti: d99b2850-bd45-4e97-822e-74a62e07f4c5
To see a more readable and decoded form of the token, just run:
uaac token decode
Doing so should display a decoded form of the token:
jti: d99b2850-bd45-4e97-822e-74a62e07f4c5
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: e78b0213
iat: 1487039776
exp: 1487082976
iss: http://localhost:8080/uaa/oauth/token
zid: uaa
aud: admin clients uaa scim
Now, to create a brand new client (client1
), which I will be using in a follow-up post:
uaac client add client1 \
--name client1 --scope resource.read,resource.write \
--autoapprove ".*" \
-s client1 \
--authorized_grant_types authorization_code,refresh_token,client_credentials \
--authorities uaa.resource
This client is going to request a scope of resource.read
, resource.write
from users and will participate in authorization_code grant-type OAuth2 flows, creating a resource owner or a user of the system:
uaac user add user1 -p user1 --emails user1@user1.com
...and assigning this user a resource.read
scope:
uaac group add resource.read
uaac member add resource.read user1
Exercise a Test Flow
Now that we have a client and a resource owner, let us exercise a quick authorization_code flow, uaac provides a handy command line option that provides the necessary redirect hooks to capture auth code and transforms the auth_code to an access token.
uaac token authcode get -c client1 -s client1 --no-cf
Invoking the above command should open up a browser window and prompt for user creds:
Logging in with the user1
/user1
user that was created previously should respond with a message in the command line that the token has been successfully fetched. This can be explored once more using the following command:
uaac context
...with the output showing the details of the logged-in user:
jti: c8ddfdfc-9317-4f16-b3a9-808efa76684b
nonce: 43c8d9f7d6264fb347ede40c1b7b44ae
sub: 7fdd9a7e-5b92-42e7-ae75-839e21b932e1
scope: resource.read
client_id: client1
cid: client1
azp: client1
grant_type: authorization_code
user_id: 7fdd9a7e-5b92-42e7-ae75-839e21b932e1
origin: uaa
user_name: user1
email: user1@user1.com
auth_time: 1487040497
rev_sig: c107f5c0
iat: 1487040497
exp: 1487083697
iss: http://localhost:8080/uaa/oauth/token
zid: uaa
aud: resource client1
This concludes the whirlwind tour of setting up a local UAA and adding a couple of roles involved in an OAuth2 flow (a client and a user). I have not covered the OAuth2 flows itself; the article Digital Ocean Intro to OAuth2 is a very good primer on the flows.
I will follow this post with a post on how this infrastructure can be used for securing a sample resource and demonstrate a flow using Spring Security and Spring Boot.
Published at DZone with permission of Biju Kunjummen. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments