Home » Software Development » Bootstrapping an OAuth2 Authorization server using UAA

About Biju Kunjummen

Biju Kunjummen

Bootstrapping an OAuth2 Authorization server using UAA

A quick way to get a robust OAuth2 server running in your local machine is to use the excellent Cloud Foundry UAA project. UAA is used as the underlying OAUth2 authorization server in Cloud Foundry deployments and can scale massively, but is still small enough that it can be booted up on modest hardware.

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/uaa

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 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 decode

which 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 ".*"  \
  -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 [email protected]

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: [email protected]
  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.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

 

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

 

and many more ....

 

Receive Java & Developer job alerts in your Area from our partners over at ZipRecruiter

 

4 comments

  1. Good Information. Thanks.

    Facing the following issue (any help is appreciated):

    With gradlew run

    :assemble
    :assemble took 0ms
    :cleanCargoConfDir UP-TO-DATE
    :cleanCargoConfDir took 0ms
    :cargoRunLocal
    Press Ctrl-C to stop the container…
    Building 97% > :cargoRunLocal

    With clean assemble run –info

    Tomcat 8.x started on port [8080]
    [ant:cargo] Press Ctrl-C to stop the container…

    java version is 8

    curl -H “Accept: application/json” localhost:8080/uaa/login is returning FAILURE response.
    but http://localhost:8080/api/ is returning the response properly: This is a test/demo service for the CloudFoundry UAA

    uaac target http://localhost:8080/uaa failed to access http://localhost:8080/uaa: invalid status response: 503

    any help is appreciated.

    — David

    • Not sure why you would be seeing this behavior David, the best bet may be to look at the logs – try searching for a file called uaa-server.log and that should record why the start-up may be failing for you.

  2. Biju,

    Finally got it working, some of the things which I did:

    1. At the location uaa\uaa\src\main\resources, there is a file required_configuration.yml.
    I added reqired_configuration.yml as param-value next to uaa.yml and login.yml in the web.xml (at uaa\uaa\src\main\webapp\WEB-INF)
    for param-name: environmentConfigDefaults

    environmentConfigDefaults
    uaa.yml,login.yml,required_configuration.yml

    2. For creating the client1 using uaac client add client1 command,
    the –autoapprove “.*” was not working. It was complaining about too many parameters
    so I need to do –autoapprove true instead of –autoapprove “.*”

    3. For the command to test the authorization_code flow: uaac token authcode get -c client1 -s client1 –no-cf
    It took me to the browser window, which asked me email and password…. but the email id: [email protected] and password user1
    didn’t work. But it worked for user1 instead of email id [email protected]. Thanks for mentioning it.

    4. To see the details of the logged in user, the command uaac context didn’t display the output as mentioned.
    But the command uaac token decode displayed the output as mentioned.

    Rest I was able to play around with other commands, currently going through the reference you provided (Intro to OAuth2) and your information was very useful.

    Looking forward for your next post on “securing a sample resource and demonstrate a flow using Spring Security and Spring Boot”

    Thanks
    — David

    • Awesome, good that it is working for you now David, the amount of changes in your first point feels too much though, it worked for me without any of these changes – wondering if it could be the different OS triggering this behavior – I am on Mac OSX.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Want to take your Java skills to the next level?

Grab our programming books for FREE!

Here are some of the eBooks you will get:

  • Spring Interview QnA
  • Multithreading & Concurrency QnA
  • JPA Minibook
  • JVM Troubleshooting Guide
  • Advanced Java
  • Java Interview QnA
  • Java Design Patterns