diff --git a/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc b/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc index 4aa67cc3d8072..9388e24a7d120 100644 --- a/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc +++ b/docs/src/main/asciidoc/security-oidc-auth0-tutorial.adoc @@ -84,7 +84,7 @@ public class GreetingResource { } } ---- -<1> The injected `JsonWebToken` (JWT) bean has an `@IdToken` qualifier, which means it represents not an access token but OIDC `IdToken`. +<1> The injected `JsonWebToken` (JWT) bean has an `@IdToken` qualifier, which means it represents not an access token but OIDC `ID token`. `IdToken` provides information in the form of claims about the current user authenticated during the OIDC authorization code flow and you can use `JsonWebToken` API to access these claims. <2> The `io.quarkus.security.Authenticated` annotation is added to the `hello()` method, which means that only authenticated users can access it. @@ -105,7 +105,7 @@ quarkus.oidc.client-id=sKQu1dXjHB6r0sra0Y1YCqBZKWXqCkly quarkus.oidc.credentials.secret=${client-secret} ---- -In completing this step, you have just configured Quarkus to use the domain, client ID, and secret of yourAuth0 application. +In completing this step, you have just configured Quarkus to use the domain, client ID, and secret of your Auth0 application. Setting the property `quarkus.oidc.application-type=web-app` instructs Quarkus to use the OIDC authorization code flow, but there are also other methods, which are discussed later on in the tutorial. The endpoint address will be \http://localhost:8080/hello, which must also be registered as an allowed callback URL in your Auth0 application. @@ -145,8 +145,8 @@ This is the only time during this tutorial when you are expected to manually sta The configuration and code update steps in the remaining sections of this tutorial are automatically observed and processed by Quarkus without you needing to restart the application manually. ==== -Open the browser and access the following URL: -`http://localhost:8080/hello` +Open the browser and access \http://localhost:8080/hello. + You will be redirected to Auth0 and prompted to log in: image::auth0-login.png[Auth0 Login] @@ -296,7 +296,7 @@ quarkus.http.auth.permission.authenticated.paths=/logout quarkus.http.auth.permission.authenticated.policy=authenticated <6> ---- <1> Auth0 does not include the end sessiion URL in its metadata, so complement it with manually configuring the Auth0 end session endpoint URL. -<2> Auth0 will not recognize a standard `post_logout_redirect_uri` query parameter and expects a parameter `returnTo' instead. +<2> Auth0 will not recognize a standard `post_logout_redirect_uri` query parameter and expects a parameter `returnTo` instead. <3> Auth0 expects `client-id` in the logout request. <4> Authenticated requests to `/logout` path will be treated as RP-inititated logout requests. <5> This is a public resource to where the logged out user should be returned to. @@ -304,7 +304,7 @@ quarkus.http.auth.permission.authenticated.policy=authenticated <6> Here we have customized the Auth0 end session endpoint URL and indicated to Quarkus that an `http://localhost:8080/logout` request must trigger a logout of the currently authenticated user. An interesting thing about the `/logout` path is that it is `virtual`, it is not supported by any method in the JAX-RS endpoint, so for Quarkus OIDC to be able to react to `/logout` requests we attach an `authenticated` https://quarkus.io/guides/security-authorize-web-endpoints-reference#authorization-using-configuration[HTTP security policy] to this path directly in the configuration. -We also have configured Quarkus to return the logged out user to the public `/hello/post-logout` resource, with this path included in the logout request as the Auth0 specific `returnTo` query parameter. Finally, the Quarkus application's `client-id` is included in the logout URL as well. +We also have configured Quarkus to return the logged out user to the public `/hello/post-logout` resource, and this path is included in the logout request as the Auth0 specific `returnTo` query parameter. Finally, the Quarkus application's `client-id` is included in the logout URL as well. Update the endpoint to accept the post logout redirects: @@ -357,7 +357,7 @@ Next, go to the Dev UI, `http://localhost:8080/q/dev/`, login to Auth0 from the image::auth0-devui-dashboard-with-name.png[Auth0 Dashboard with name and Logout] -For the logout to work from OIDC DevUI, the Auth0 application's list of allowed logout callbacks have to be updated to include the OIDC DevUI endpoint: +For the logout to work from OIDC DevUI, the Auth0 application's list of allowed logout callbacks has to be updated to include the OIDC DevUI endpoint: image::auth0-allowed-logouts.png[Auth0 Allowed Logouts] @@ -592,7 +592,7 @@ Please see the following <> and <> section [NOTE] ==== -Typically one uses access tokens to access remote services but OIDC DevUI SPA dashboard also offers an option to test with the ID token. This option is only available to emulate the cases where SPA delegates to the endpoint to verify and retrieve some information from the ID token for SPA to use - but ID token will still be sent to the endppont as Bearer token by OIDC DevUI. Prefer testing with the access token in most cases. +Typically one uses access tokens to access remote services but OIDC DevUI SPA dashboard also offers an option to test with the ID token. This option is only available to emulate the cases where SPA delegates to the endpoint to verify and retrieve some information from the ID token for SPA to use - but ID token will still be sent to the endpoint as Bearer token by OIDC DevUI. Prefer testing with the access token in most cases. ==== [NOTE] @@ -624,7 +624,7 @@ In fact, the last code example, showing the injected `UserInfo`, is a concrete e But what about propagating access tokens to some custom services ? It is very easy to achieve in Quarkus, both for the authorization code and bearer token flows. All you need to do is to create a Reactive REST Client interface for calling the service requiring a Bearer token access and annotate it with `@AccessToken` and the access token arriving to the frontend endpoint as the Auth0 Bearer access token or acquired by Quarkus after completing the Auth0 authorization code flow, will be propagated to the target microservice. This is as easy as it can get. -Please see xref:security-openid-connect-client-reference.adoc#reactive-token-propagation[OIDC token propagation] for more information about the token propagation and the following sections in this tutoal for a concrete example. +Please see xref:security-openid-connect-client-reference.adoc#reactive-token-propagation[OIDC token propagation] for more information about the token propagation and the following sections in this tutorial for a concrete example. [[jwt-access-tokens]] === Access tokens in JWT format @@ -710,7 +710,7 @@ import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import io.quarkus.oidc.token.propagation.AccessToken; @RegisterRestClient -@AccessToken +@AccessToken <1> @Path("/echo") public interface ApiEchoServiceClient { @@ -719,6 +719,7 @@ public interface ApiEchoServiceClient { String echoUserName(String username); } ---- +<1> Propagate access token as an HTTP `Authorization: Bearer accesstoken` header And update the configuration for the Quarkus frontend application, `GreetingResource`, which has been created earlier, to request that an authorization code flow access token (as opposed to ID token) includes an `aud` (audience) claim targeting `ApiEchoService`, as well as configure the base URL for the `ApiEchoService` REST client: @@ -948,7 +949,7 @@ image::auth0-password-grant.png[Auth0 password grant] It is important to clarify that we do not recommend using the deprecated OAuth2 `password` token grant in production. However using it can help testing the endpoint with tokens acquired from the live dev Auth0 tenant. ==== -`OidcTestClient` should be used to test applications accepting bearer tokens which will work for the endpoint developed in this tutorial as it supports both authorization code flow and bearer token authentication. You would need to use OIDC WireMock or `HtmlUnit` directly against the Auth0 dev tenant if only authorization code flow was supported - in the latter case `HtmlUnit` test code would have to be aligned with how Auth0 challenges users to enter their credentials - please copy and paste an xref:security-oidc-code-flow-authentication#integration-testing-wiremock[HtmlUnit test fragment] from the documentation and experiment if you would like. +`OidcTestClient` should be used to test applications accepting bearer tokens which will work for the endpoint developed in this tutorial as it supports both authorization code flow and bearer token authentication. You would need to use OIDC WireMock or `HtmlUnit` directly against the Auth0 dev tenant if only the authorization code flow was supported - in the latter case `HtmlUnit` test code would have to be aligned with how Auth0 challenges users to enter their credentials - please copy and paste an xref:security-oidc-code-flow-authentication#integration-testing-wiremock[HtmlUnit test fragment] from the documentation and experiment if you would like. In meantime we will now proceed with fixing the currently failing test using `OidcTestClient`. @@ -1077,12 +1078,13 @@ The steps described in this tutorial should work exactly as the tutorial describ == Summary -This tutorial demonstrated how Quarkus endpoints can be secured with the `quarkus-oidc` extension and Auth0 using authorization code and bearer token authentication flows, whereby both flows are supported by the same endpoint code. +This tutorial demonstrated how Quarkus endpoints can be secured with the `quarkus-oidc` extension and Auth0 using Authorization code and Bearer token authentication flows, with both flows being supported by the same endpoint code. Without writing a single line of code, you have added support for the custom Auth0 logout flow and enabled role-based access control with a custom Auth0 namespace qualified claim. Token propagation from the frontend endpoint to the microservice endpoint has been achieved by adding the `@AccessToken` annotation to the microservice REST client. -Microservice endpoint activated the ermission-based access control with the `@PermissionsAllowed` annotation. +Microservice endpoint activated the permission-based access control with the `@PermissionsAllowed` annotation. You used Quarkus dev mode to update the code and configuration without restarting the endpoint, and you also used the OIDC Dev UI to visualize and test Auth0 tokens. You used the continuous testing feature of Quarkus to complement OIDC Dev UI tests with integration tests against the live Auth0 development tenant. +Finally, you have run the application in JVM and native modes. Enjoy!