Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

OAuth 2.0 Resource Server Sample

This sample demonstrates integrating Resource Server with the Spring Authorization Server, though it can be modified to integrate with a mock server or your favorite Authorization Server.

With it, you can run the integration tests or run the application as a stand-alone service to explore how you can secure your own service with OAuth 2.0 Bearer Tokens using Spring Security.

1. Running the tests

To run the tests, do:

./gradlew integrationTest

Or import the project into your IDE and run OAuth2ResourceServerApplicationTests from there.

What is it doing?

By default, the tests are pointing at a mock Authorization Server instance via the test profile.

The tests are configured with a set of hard-coded tokens originally obtained from the mock Authorization Server, and each makes a query to the Resource Server with their corresponding token.

The Resource Server subsquently verifies with the Authorization Server and authorizes the request, returning the phrase

Hello, subject!

where "subject" is the value of the sub field in the JWT returned by the Authorization Server.

2. Running the app with Spring Authorization Server

Before running this application with the default configuration, you will need to start up an Authorization Server, such as the authorization-server sample in this project which is pre-configured to work with this Resource Server sample out of the box.

To run the Authorization Server as a stand-alone application, navigate to the servlet/spring-boot/java/oauth2/authorization-server and do:

./gradlew bootRun

Or import the project into your IDE and run OAuth2AuthorizationServerApplication from there. Next, you can run this Resource Server.

To run as a stand-alone application, do:

./gradlew bootRun

Or import the project into your IDE and run OAuth2ResourceServerApplication from there.

Once it is up and running, you can issue the following request:

curl -X POST messaging-client:secret@localhost:9000/oauth2/token -d "grant_type=client_credentials" -d "scope=message:read"

This returns something like the following:

{
    "access_token": "eyJraWQiOiI4YWY4Zjc2Zi0zMTdkLTQxZmYtYWY5Yi1hZjg5NDg4ODM5YzciLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJtZXNzYWdpbmctY2xpZW50IiwiYXVkIjoibWVzc2FnaW5nLWNsaWVudCIsIm5iZiI6MTYyNzMzNDQ1MCwic2NvcGUiOlsibWVzc2FnZTpyZWFkIl0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo5MDAwIiwiZXhwIjoxNjI3MzM0NzUwLCJpYXQiOjE2MjczMzQ0NTAsImp0aSI6IjBiYjYwZjhkLWIzNjItNDk0MC05MGRmLWZhZDg4N2Q1Yzg1ZSJ9.O8dI67B_feRjOn6pJi5ctPJmUJCNpV77SC4OiWqmpa5UHvf4Ud6L6EFe9LKuPIRrEWi8rMdCdMBOPKQMXvxLoI3LMUPf7Yj973uvZN0E988MsKwhGwxyaa_Wam8wFlk8aQlN8SbW3cKdeH-nKloNMdwjfspovefX521mxouaMjmyXdIFrM5WZ15GZK69NIniACSatE-pc9TAjKYBDbC65jVt_zHEvDQbEkZulF2bjrGOZC8C3IbJWnlKgkcshrY44TtrGPyCp2gIS0TSUUsG00iSBBC8E8zPU-YdfaP8gB9_FwUwK9zfy_hU2Ykf2aU3eulpGDVLn2rCwFeK86Rw1w",
    "expires_in": 299,
    "scope": "message:read",
    "token_type": "Bearer"
}

Then, export the access token from the response:

export TOKEN=...

Then issue the following request:

curl -H "Authorization: Bearer $TOKEN" localhost:8080

Which will respond with the phrase:

Hello, messaging-client!

where messaging-client is the value of the sub field in the JWT returned by the Authorization Server.

Or this to make a GET request to /message:

curl -H "Authorization: Bearer $TOKEN" localhost:8080/message

Will respond with:

secret message

In order to make a POST request to /message, you can use the following request:

curl -X POST messaging-client:secret@localhost:9000/oauth2/token -d "grant_type=client_credentials" -d "scope=message:write"

Then, export the access token from the response:

export TOKEN=...

Then issue the following request:

curl -H "Authorization: Bearer $TOKEN" -d "my message" localhost:8080/message

Which will respond with:

Message was created. Content: my message

3. Running the app with a mock Authorization Server

To run as a stand-alone application with an embedded mock Authorization Server, do:

./gradlew bootRun --args='--spring.profiles.active=test'

Or import the project into your IDE and run OAuth2ResourceServerApplication from there with the test profile active.

Once it is up, you can use the following token:

export TOKEN=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzdWJqZWN0IiwiZXhwIjoyMTY0MjQ1ODgwLCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiMDFkOThlZWEtNjc0MC00OGRlLTk4ODAtYzM5ZjgyMGZiNzVlIiwiY2xpZW50X2lkIjoibm9zY29wZXMiLCJzY29wZSI6WyJub25lIl19.VOzgGLOUuQ_R2Ur1Ke41VaobddhKgUZgto7Y3AGxst7SuxLQ4LgWwdSSDRx-jRvypjsCgYPbjAYLhn9nCbfwtCitkymUKUNKdebvVAI0y8YvliWTL5S-GiJD9dN8SSsXUla9A4xB_9Mt5JAlRpQotQSCLojVSKQmjhMpQWmYAlKVjnlImoRwQFPI4w3Ijn4G4EMTKWUYRfrD0-WNT9ZYWBeza6QgV6sraP7ToRB3eQLy2p04cU40X-RHLeYCsMBfxsMMh89CJff-9tn7VDKi1hAGc_Lp9yS9ZaItJuFJTjf8S_vsjVB1nBhvdS_6IED_m_fOU52KiGSO2qL6shxHvg

And then make this request:

curl -H "Authorization: Bearer $TOKEN" localhost:8080

Which will respond with the phrase:

Hello, subject!

where subject is the value of the sub field in the JWT returned by the Authorization Server.

Or this to make a GET request to /message:

export TOKEN=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzdWJqZWN0IiwiZXhwIjoyMTY0MjQ1NjQ4LCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiY2I1ZGMwNDYtMDkyMi00ZGJmLWE5MzAtOGI2M2FhZTYzZjk2IiwiY2xpZW50X2lkIjoicmVhZGVyIiwic2NvcGUiOlsibWVzc2FnZTpyZWFkIl19.Pre2ksnMiOGYWQtuIgHB0i3uTnNzD0SMFM34iyQJHK5RLlSjge08s9qHdx6uv5cZ4gZm_cB1D6f4-fLx76bCblK6mVcabbR74w_eCdSBXNXuqG-HNrOYYmmx5iJtdwx5fXPmF8TyVzsq_LvRm_LN4lWNYquT4y36Tox6ZD3feYxXvHQ3XyZn9mVKnlzv-GCwkBohCR3yPow5uVmr04qh_al52VIwKMrvJBr44igr4fTZmzwRAZmQw5rZeyep0b4nsCjadNcndHtMtYKNVuG5zbDLsB7GGvilcI9TDDnUXtwthB_3iq32DAd9x8wJmJ5K8gmX6GjZFtYzKk_zEboXoQ

curl -H "Authorization: Bearer $TOKEN" localhost:8080/message

Will respond with:

secret message

In order to make a POST request to /message, you can use the following request:

export TOKEN=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzdWJqZWN0IiwiZXhwIjoyMTY0MjQzOTA0LCJhdXRob3JpdGllcyI6WyJST0xFX1VTRVIiXSwianRpIjoiZGI4ZjgwMzQtM2VlNy00NjBjLTk3NTEtMDJiMDA1OWI5NzA4IiwiY2xpZW50X2lkIjoid3JpdGVyIiwic2NvcGUiOlsibWVzc2FnZTp3cml0ZSJdfQ.USvpx_ntKXtchLmc93auJq0qSav6vLm4B7ItPzhrDH2xmogBP35eKeklwXK5GCb7ck1aKJV5SpguBlTCz0bZC1zAWKB6gyFIqedALPAran5QR-8WpGfl0wFqds7d8Jw3xmpUUBduRLab9hkeAhgoVgxevc8d6ITM7kRnHo5wT3VzvBU8DquedVXm5fbBnRPgG4_jOWJKbqYpqaR2z2TnZRWh3CqL82Orh1Ww1dJYF_fae1dTVV4tvN5iSndYcGxMoBaiw3kRRi6EyNxnXnt1pFtZqc1f6D9x4AHiri8_vpBp2vwG5OfQD5-rrleP_XlIB3rNQT7tu3fiqu4vUzQaEg

curl -H "Authorization: Bearer $TOKEN" -d "my message" localhost:8080/message

Will respond this:

Message was created. Content: my message

4. Testing against other Authorization Servers

In order to use this sample, your Authorization Server must support JWTs that either use the "scope" or "scp" attribute.

To change the sample to point at your Authorization Server, simply find this property in the application.yml:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: http:https://localhost:9000/oauth2/jwks

And change the property to your Authorization Server’s JWK set endpoint:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: https://dev-123456.oktapreview.com/oauth2/default/v1/keys

And then you can run the app the same as before:

./gradlew bootRun

Make sure to obtain valid tokens from your Authorization Server in order to play with the sample Resource Server. To use the / endpoint, any valid token from your Authorization Server will do. To use the /message endpoint, the token should have the message:read scope.