ch4mpy / spring-addons

Ease spring OAuth2 resource-servers configuration and testing
Apache License 2.0
521 stars 84 forks source link

Expand servlet-client tutorial to show calling servlet-resource-server with user that has NICE privileges. #207

Closed tvogel8570 closed 1 month ago

tvogel8570 commented 4 months ago

I'm unable to close the gap between the client and resource server. My specific scenario is following your recommendation of using an Oauth2 client (a Spring Boot Thymeleaf client application) to access an OAuth2 Resource Server (separate Spring Boot application ). Both Spring Boot applications are configured to use the same Keycloak instance and client.

Since my Oauth2 client is a Thymeleaf client, it is a "secure client" and I don't need to use the BFF pattern.

Pseudo code for what I think needs to happen

1) User accesses the Thymeleaf application from a browser 2) User requests page that shows information from a protected API on the Resource Server 3) User is prompted to login (authorization code flow) by the client application (Spring Boot Oauth2 Client) 4) Controller in the Spring Boot Oauth2 Client gets a token that is valid for the user currently logged in that the Resource Server will accept 1) Requests a token from Keycloak based on the currently logged in principal 2) Uses a property / attribute of the principal 3) Something else ???? 5) Controller builds request to Resource Server using the new RestClient.exchange() 6) Resource Server validates token for specific NICE role 7) Results are returned to user's browser

I'm stuck on how to accomplish #4.

ch4mpy commented 4 months ago

Since my Oauth2 client is a Thymeleaf client, it is a "secure client" and I don't need to use the BFF pattern

True!

Both Spring Boot applications are configured to use the same Keycloak instance and client

A REST API configured as a resource server (so called oauth2ResourceServer() in Spring Security configuration) does not need client configuration or dependencies at all (unless it needs to call another resource server with client-credentials flow, but that's most probably not your case).

  1. User is prompted to login

That happens natively on a Spring client with oauth2Login() when a user tries to access a resource (path) if this resource isn't permitAll(). So if the model for a Thymeleaf template needs to retrieve a secured resource from your resource server, I strongly suggest that the MVC controller endpoint returning a reference to this template is not permitAll() (isAuthenticated() would be enough).

  1. Controller in the Spring Boot Oauth2 Client gets a token

A Spring OAuth2 client gets tokens from an AuthorizedClient. It gets this "authorized client" from the OAuth2AuthorizedClientManager. As soon as a user is authenticated with oauth2Login, the authorized client repo is populated (there are other ways to "authorize" clients, but in your case, what you need is an authorization-code flow to complete and authorization-code flows are initiated with oauth2Login).

All Spring REST clients have their own way to integrate with AuthorizedClientRepository. So, once you ensured that oauth2Login is triggered (that will happen as soon as you require access to the MVC endpoint to be isAuthenticated()), refer to your chosen REST client (RestClient? WebClient? RestTemplate? @FeignClient?) documentation to authorize its requests with an access token from the authorized clients repo.

The resource-server_with_ui tutorial uses a RestClient implementation magically generated from an @HttpExchange by Spring's HttpServiceProxyFactory (thanks to spring-addons magic).

tvogel8570 commented 4 months ago

Perhaps not as fully implemented as I hoped, WRT RestClient and Oauth2..., a SO answer, Spring enhancement request and POC github.

Working through your linked github and poc from above.

ch4mpy commented 1 month ago

@tvogel8570 please have another look at the resource-server_with_ui tutorial. It contains a REST call to an external API (a Keycloak admin endpoint) using a RestClient and authorized with a token obtained using client-credentials.

spring-addons-starter-rest README might help you define the configuration for your REST clients and @HttpExchange implementations generation.