161 lines
4.7 KiB
Plaintext
161 lines
4.7 KiB
Plaintext
|
= OAuth 2.0 Authorization Server Sample
|
||
|
|
||
|
This sample demonstrates Authorization Server with the `client_credentials` grant type. This authorization server is configured to generate JWT tokens signed with the `RS256` algorithm.
|
||
|
|
||
|
* <<running-the-tests, Running the tests>>
|
||
|
* <<running-the-app, Running the app>>
|
||
|
* <<testing-with-a-resource-server, Testing with a resource server>>
|
||
|
|
||
|
[[running-the-tests]]
|
||
|
== Running the tests
|
||
|
|
||
|
To run the tests, do:
|
||
|
|
||
|
```bash
|
||
|
./gradlew integrationTest
|
||
|
```
|
||
|
|
||
|
Or import the project into your IDE and run `OAuth2AuthorizationServerApplicationTests` from there.
|
||
|
|
||
|
=== What is it doing?
|
||
|
|
||
|
The tests are making requests to the token endpoint with the `client_credentials` grant type using the `client_secret_basic` authentication method, and subsequently verifying them using the token introspection endpoint.
|
||
|
|
||
|
The introspection endpoint response is used to verify the token (decode the JWT in this case), returning the payload including the requested scope:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"active": true,
|
||
|
"aud": [
|
||
|
"messaging-client"
|
||
|
],
|
||
|
"client_id": "messaging-client",
|
||
|
"exp": 1627070941,
|
||
|
"iat": 1627070641,
|
||
|
"iss": "http://localhost:9000",
|
||
|
"jti": "987599e3-1048-4fe8-89df-ad113aef2d6c",
|
||
|
"nbf": 1627070641,
|
||
|
"scope": "message:read",
|
||
|
"sub": "messaging-client",
|
||
|
"token_type": "Bearer"
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Note that Spring Security does not require the token introspection endpoint when configured to use the Bearer scheme with JWTs, this is simply used for demonstration purposes.
|
||
|
|
||
|
[[running-the-app]]
|
||
|
== Running the app
|
||
|
|
||
|
To run as a stand-alone application, do:
|
||
|
|
||
|
```bash
|
||
|
./gradlew bootRun
|
||
|
```
|
||
|
|
||
|
Or import the project into your IDE and run `OAuth2AuthorizationServerApplication` from there.
|
||
|
|
||
|
Once it is up and running, you can issue the following request:
|
||
|
|
||
|
```bash
|
||
|
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:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"access_token": "eyJraWQiOiI4YWY4Zjc2Zi0zMTdkLTQxZmYtYWY5Yi1hZjg5NDg4ODM5YzciLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJtZXNzYWdpbmctY2xpZW50IiwiYXVkIjoibWVzc2FnaW5nLWNsaWVudCIsIm5iZiI6MTYyNzMzNDQ1MCwic2NvcGUiOlsibWVzc2FnZTpyZWFkIl0sImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdDo5MDAwIiwiZXhwIjoxNjI3MzM0NzUwLCJpYXQiOjE2MjczMzQ0NTAsImp0aSI6IjBiYjYwZjhkLWIzNjItNDk0MC05MGRmLWZhZDg4N2Q1Yzg1ZSJ9.O8dI67B_feRjOn6pJi5ctPJmUJCNpV77SC4OiWqmpa5UHvf4Ud6L6EFe9LKuPIRrEWi8rMdCdMBOPKQMXvxLoI3LMUPf7Yj973uvZN0E988MsKwhGwxyaa_Wam8wFlk8aQlN8SbW3cKdeH-nKloNMdwjfspovefX521mxouaMjmyXdIFrM5WZ15GZK69NIniACSatE-pc9TAjKYBDbC65jVt_zHEvDQbEkZulF2bjrGOZC8C3IbJWnlKgkcshrY44TtrGPyCp2gIS0TSUUsG00iSBBC8E8zPU-YdfaP8gB9_FwUwK9zfy_hU2Ykf2aU3eulpGDVLn2rCwFeK86Rw1w",
|
||
|
"expires_in": 299,
|
||
|
"scope": "message:read",
|
||
|
"token_type": "Bearer"
|
||
|
}
|
||
|
```
|
||
|
|
||
|
In order to make the same token introspection request as the tests, export the access token from the response:
|
||
|
|
||
|
```bash
|
||
|
export TOKEN=...
|
||
|
```
|
||
|
|
||
|
Then issue the following request:
|
||
|
|
||
|
```bash
|
||
|
curl -X POST messaging-client:secret@localhost:9000/oauth2/introspect -d "token=$TOKEN"
|
||
|
```
|
||
|
|
||
|
Which will return something like the following:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"active": true,
|
||
|
"aud": [
|
||
|
"messaging-client"
|
||
|
],
|
||
|
"client_id": "messaging-client",
|
||
|
"exp": 1627334750,
|
||
|
"iat": 1627334450,
|
||
|
"iss": "http://localhost:9000",
|
||
|
"jti": "0bb60f8d-b362-4940-90df-fad887d5c85e",
|
||
|
"nbf": 1627334450,
|
||
|
"scope": "message:read",
|
||
|
"sub": "messaging-client",
|
||
|
"token_type": "Bearer"
|
||
|
}
|
||
|
```
|
||
|
|
||
|
[[testing-with-a-resource-server]]
|
||
|
== Testing with a resource server
|
||
|
|
||
|
This sample can be used in conjunction with a resource server, such as the https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/java/oauth2/resource-server/hello-security[resource-server sample] in this project.
|
||
|
|
||
|
To change the sample to point to this authorization server, simply find this property in that project's `application.yml`:
|
||
|
|
||
|
```yaml
|
||
|
spring:
|
||
|
security:
|
||
|
oauth2:
|
||
|
resourceserver:
|
||
|
jwt:
|
||
|
jwk-set-uri: ${mockwebserver.url}/.well-known/jwks.json
|
||
|
```
|
||
|
|
||
|
And change the property to:
|
||
|
|
||
|
```yaml
|
||
|
spring:
|
||
|
security:
|
||
|
oauth2:
|
||
|
resourceserver:
|
||
|
jwt:
|
||
|
jwk-set-uri: http://localhost:9000/oauth2/jwks
|
||
|
```
|
||
|
|
||
|
And then you can run that app similarly to the authorization server:
|
||
|
|
||
|
```bash
|
||
|
./gradlew bootRun
|
||
|
```
|
||
|
|
||
|
Once it is up and running, you can issue the following request:
|
||
|
|
||
|
```bash
|
||
|
curl -X POST messaging-client:secret@localhost:9000/oauth2/token -d "grant_type=client_credentials" -d "scope=message:read"
|
||
|
```
|
||
|
|
||
|
Then, export the access token from the response:
|
||
|
|
||
|
```bash
|
||
|
export TOKEN=...
|
||
|
```
|
||
|
|
||
|
Then issue the following request:
|
||
|
|
||
|
```bash
|
||
|
curl -H "Authorization: Bearer $TOKEN" localhost:8080
|
||
|
```
|
||
|
|
||
|
Which will respond with the phrase:
|
||
|
|
||
|
```
|
||
|
Hello, messaging-client!
|
||
|
```
|