Search code examples
javaspringoauth-2.0keycloakspring-cloud

Spring Cloud Gateway -> Keycloak -> Microservice


I wrote two services:

  1. api gateway (spring cloud gateway)
  2. catalog service

Next, I used keycloak. As far as I understand, according to OAuth2, the gateway is a resource, not a client. I did so. Everything works fine.

My problem: I can access catalog-service through the gateway, which will access keycloak, and in case of successful authentication will go to catalog-service, BUT I can still access catalog-service directly, without authentication.

This is logical, because I haven't changed anything in catalog-service for security, but I don't understand how to do it correctly. Declare a catalog service as a resource server too and use Token Relay in Spring Gateway? Will it work and is it a good practice? Or use Spring Security somehow? I'm confused..

And should I make the gateway a client after all? Because I see many more examples on the Internet of exactly this use of the gateway..


Solution

  • Both configurations (client and resource server) are possible for the gateway.

    If you want direct calls to APIs to be secured, then each of this APIs should be configured as resource server.

    If downstream APIs are configured as resource servers and front-ends (whatever is sending requests to the gateway) are configured as OAuth2 clients, then no security at all is necessary on the gateway (it's job is just routing).

    TokenRelay= filter is to be used on gateway configured as client with downstream API configured as resource servers and front-ends secured with sessions. This filter replaces on the fly session cookie with access token before forwarding requests to downstream resource servers. This is called the backend for frontend pattern (aka BFF), and is now recommanded: yes, using session cookies (flagged with same-site and http-only) with CSRF protection is safer than exposing OAuth2 tokens to Javascript.

    I suggest you have a look at my tutorials for more OAuth2 background and many configuration samples (including a BFF one)

    The reason why I did not write much about gateway configured as resource server is because, in my opinion, it is a bad practice:

    • downstream services are not secured or security is duplicated, which is worth
    • gateway is tightly coupled to downstream services, which breaks the value of micro-services (maintaining small pieces of loosely coupled software). For instance, gateway has to know what a catalog is, how it is structured and probably how it relates to users to implement security rules like "can edit this product if manager or member of the team responsible for this product"
    • you can hardly unit test security rules on the gateway (difficulties to unit-test usually are a good indicator for bad design)