I 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 - clients and users, and in a follow up post I will show how to use this Authorization server with a sample client application and in securing a resource.
Starting up the UAA
The repository for the UAA project is at https://github.com/cloudfoundry/uaaDownloading 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 called uaac, available here. Assuming that you have the uaac cli downloaded and UAA started up at its default port of 8080, let us start by pointing the uaac to the uaa application:uaac target http://localhost:8080/uaa
and 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 token, just run:
uaac token decodewhich 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(called client1), which I will be using in a follow on post:
uaac client add client1 \ --name client1 --scope resource.read,resource.write \ --autoapprove true \ -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 a OAuth2 flow - a client and a user. I have not covered the OAuth2 flows itself, the 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.
Nicely written guide! Keep it up mate!
ReplyDeleteNice guide, there is a small bug when creating a client you also have to add a redirect_uri like
ReplyDeleteuaac client add client1 \
--name client1 \
--scope resource.read,resource.write \
-s client1 \
--authorized_grant_types authorization_code,refresh_token,client_credentials \
--authorities uaa.resource \
--redirect_uri http://localhost:8888/** <---here
Thanks Giuseppe, yes, appears to have changed with more recent UAA versions, will update the post.
DeleteAnd you also need to specify the port on the `uaac token authcode get` line:
Deleteuaac token authcode get -c client1 -s client1 --no-cf --port 8888
hi. Nice post. I followed the same steps but when i tried to login in the UI, nothing happens, it returns to the same login page.
DeleteBut if enter a wrong credentials there is an error though
Hi Murugappan, yes, it looks like `uaac token authcode get -c client1 -s client1 --no-cf` won't work anymore as it internally validates the redirect_uri before redirecting. So this flow will have to be tried with a real application.
DeleteThank you. Looking forward to your post for how to get the access token from UAA. I couldn't find any examples. Tried the api's from cf documents. No luck.
ReplyDeleteHere is a sample Murugappan - https://github.com/bijukunjummen/oauth2-boot2
DeleteThank you sir. When i click the access secure page link it takes me to uaa login page. When I try to login with user1/user1 nothing happens am redirected uaa login page again. Do I need add some config on uaa server. I am just cloning uaa repo and generating key and starting.
DeleteStrange, it should have redirected you to the app at that point!
ReplyDeleteIt looks like a problem with uaa server. Is there a way I can test the uaa server just by hitting the server manually and getting access token. Appreciate your help on this
DeleteFor some reason doesnt work in chrome for me but worked on safari. Thanks a lot
ReplyDelete