I wrote two services:
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..
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: