@@ -39,7 +39,7 @@ Whatever you choose, do not write the oauth endpoints yourself!
3939- Java 21
4040 - required by the SpringBoot plugin at build time
4141 - Gradle tool chain is used to compile and run tests
42- - Docker (only required for running tests)
42+ - Docker (required for running tests and for ` ./gradlew bootTestRun ` )
4343- jq (used for some demos, not a hard dependency)
4444
4545## Technologies Used
@@ -56,6 +56,52 @@ Whatever you choose, do not write the oauth endpoints yourself!
5656
5757## Running
5858
59+ ### Running Locally
60+
61+ One command starts the app together with a real Ory Hydra container and a pre-registered demo
62+ client (Docker must be running):
63+
64+ ```
65+ ./gradlew bootTestRun
66+ ```
67+
68+ Then open http://localhost:8080 and click "Start the OAuth flow". The credentials are
69+ ` foo@bar.com ` / ` password ` ; the flow ends on a page that exchanges the authorization code for
70+ real tokens. Hydra runs on its default ports (public 4444, admin 4445), the same
71+ single-container setup the functional tests use via
72+ [ testcontainers-ory-hydra] ( https://github.com/ardetrick/testcontainers-ory-hydra ) — see
73+ ` TestOryHydraReferenceApplication ` for how the container is configured and the demo client is
74+ seeded. Ports 4444, 4445, and 8080 must be free.
75+
76+ ### Running With Your Own Ory Hydra
77+
78+ To run the app against a Hydra you manage yourself, configure your Hydra with the app's
79+ endpoints as the login, consent, and logout URLs (` URLS_LOGIN=http://localhost:8080/login ` ,
80+ and likewise ` /consent ` and ` /logout ` ), then start the app with ` ./gradlew bootRun ` . If your
81+ Hydra's admin API is not at the default ` http://localhost:4445 ` , point the app at it with the
82+ ` reference-app.hydra.base-path ` property. This path starts with whatever OAuth2 clients your
83+ Hydra already has — the landing page at http://localhost:8080 lists them and includes
84+ instructions for creating one. To see each step of the flow and token exchange as raw terminal
85+ commands, see
86+ [ walking the authorization code flow by hand] ( docs/manual-token-exchange.md ) .
87+
88+ <details >
89+ <summary >Example: a minimal disposable Hydra via docker run</summary >
90+
91+ ```
92+ docker run --rm --name hydra \
93+ -p 4444:4444 -p 4445:4445 \
94+ -e DSN="sqlite:///tmp/db.sqlite?_fk=true" \
95+ -e SECRETS_SYSTEM=local-dev-secret \
96+ -e URLS_LOGIN=http://localhost:8080/login \
97+ -e URLS_CONSENT=http://localhost:8080/consent \
98+ -e URLS_LOGOUT=http://localhost:8080/logout \
99+ --entrypoint sh oryd/hydra:v25.4.0 \
100+ -c "hydra migrate sql -e --yes && hydra serve all --dev"
101+ ```
102+
103+ </details >
104+
59105### Running Functional Tests
60106
61107The functional tests for this project run along all other tests with the standard gradle command.
@@ -68,6 +114,9 @@ The functional tests are unique because there is practically no mocking. This ma
68114setup, but it allows us to reproduce scenarios in a context very similar to what would be seen in production, all the
69115way from interacting with the UI back to Ory Hydra.
70116
117+ <details >
118+ <summary >How the test rig works</summary >
119+
711201 . Using ` @SpringBootTest ` , the application is started on a random port. Note that the application also configures two
72121 extra controllers to help facilitate testing.
731222 . A Playwright browser instance is created (shared by all tests).
@@ -92,99 +141,7 @@ Since the token flow of OAuth is inherently UI driven, it is imperative that the
92141with this the ` Playwright ` framework is used. It allows us to use a headless driver to load the UI and use HTML
93142selectors to interact with the loaded page just like a human would.
94143
95- ### Running With Local Ory Hydra
96-
97- Running the application and Ory Hydra locally is a useful way to manually interact with the application. Use the
98- following commands to start Hydra, start the reference application, create a client, exchange a token.
99-
100- Note: All steps require Docker and some require ` jq ` . All commands should run relative to the root of this repo.
101-
102- #### Start Hydra And The Reference App
103-
104- ```
105- # Start Hydra with an in-container SQLite database, running the migrations first —
106- # the same single-container setup the functional tests get from testcontainers-ory-hydra.
107- docker run --rm --name hydra \
108- -p 4444:4444 -p 4445:4445 \
109- -e DSN="sqlite:///tmp/db.sqlite?_fk=true" \
110- -e SECRETS_SYSTEM=local-dev-secret \
111- -e URLS_LOGIN=http://localhost:8080/login \
112- -e URLS_CONSENT=http://localhost:8080/consent \
113- --entrypoint sh oryd/hydra:v25.4.0 \
114- -c "hydra migrate sql -e --yes && hydra serve all --dev"
115-
116- # At this point Hydra urls such as http://localhost:4445/admin/clients should be up and running.
117-
118- # Open a new terminal...
119-
120- # Start the Spring app.
121- ./gradlew bootRun
122-
123- # At this point the reference app pages such as localhost:8080/index.html should load.
124- ```
125-
126- #### Demo App
127-
128- Once both the app and Hydra are started, visit http://localhost:8080/demo for instructions on how interactively demo
129- the application. This is a more user-friendly approach than the subsequent testing instructions.
130-
131- #### Create A New Client And Test Via Terminal
132-
133- There may be existing clients you can use, visit to see http://localhost:4445/admin/clients .
134- Otherwise, follow these instructions to create a client and test it by going through the oauth flow.
135-
136- ```
137- # Create a client. Uses the Hydra container to access the Hydra CLI.
138- hydra_client=$(docker exec hydra \
139- hydra create client \
140- --endpoint http://127.0.0.1:4445 \
141- --grant-type authorization_code,refresh_token \
142- --response-type code,id_token \
143- --format json \
144- --secret omit-for-random-secret-1 \
145- --scope openid --scope offline \
146- --redirect-uri http://127.0.0.1:5555/callback
147- )
148-
149- # Put the client ID and client secret values into env variables for later use.
150- hydra_client_id=$(echo $hydra_client | jq -r '.client_id')
151- hydra_client_secret=$(echo $hydra_client | jq -r '.client_secret')
152- hydra_client_redirect_uri_0=$(echo $hydra_client | jq -r '.redirect_uris[0]')
153-
154- # Update the client to avoid some issues with the Java SDK.
155- curl -X PATCH \
156- http://localhost:4445/admin/clients/$hydra_client_id \
157- --data-binary @patch_client_body.json
158-
159- # Open a new terminal.
160-
161- # Build the endpoint to initiate the OAuth flow
162- oauth_endpoint="http://localhost:4444/oauth2/auth?\
163- client_id=${hydra_client_id}&\
164- response_type=code&\
165- redirect_uri=${hydra_client_redirect_uri_0}&\
166- scope=openid+offline&\
167- state=123456789"
168-
169- # Print the endpoint.
170- echo $oauth_endpoint
171-
172- # Click on the printed endpoint (or paste it into a browser).
173- # Complete the OAuth flow (by default the hard coded credentials are username: foo@bar.com password: password).
174-
175- # replace '...' with the `code` query param in the call back.
176- code=...
177-
178- # Exchange the authorization code for an access token
179- curl -X POST \
180- -H "Content-Type: application/x-www-form-urlencoded" \
181- -H "authorization: basic $(echo -n "${hydra_client_id}:${hydra_client_secret}" | base64)" \
182- -d "grant_type=authorization_code" \
183- -d "code=${code}" \
184- -d "redirect_uri=http%3A%2F%2F127.0.0.1%3A5555%2Fcallback" \
185- -d "client_id=${hydra_client_id}" \
186- http://127.0.0.1:4444/oauth2/token
187- ```
144+ </details >
188145
189146## OAuth 2.0 Authorization Code Grant Flow
190147
0 commit comments