Security Architecture

The Big Picture

When ShopEase is split into services (see the Microservices with Spring Cloud material), each service must still know who is calling. The common, safe design:

Browser (React)                 API Gateway                       Services (resource servers)
  ---------------                 -----------                       ---------------------------
  HttpOnly session  ---------->  OAuth2 client (oauth2Login)
  cookie only                    holds tokens in its session
                                 TokenRelay: adds                 -> product-service  (public GETs)
                                 Authorization: Bearer <user JWT> -> order-service    validates JWT
                                                                  -> user-service     validates JWT
                                                                           |
                                                       client_credentials  |  Bearer <service JWT>
                                                                           v
                                                                     payment-service  validates JWT,
                                                                                      needs payments.write
                        Authorization server (Keycloak / Spring Authorization Server) issues all tokens

Principles

  • Zero trust inside the network: every service validates the JWT itself. A request is not trusted just because it came from inside the cluster.
  • The gateway does coarse checks (is the user logged in?). Services do fine-grained checks (does this order belong to this user?).
  • Use the user's token when acting for a user; use a service token (client credentials) for background work.
  • Never accept identity from plain headers like X-User-Id unless they are set by the gateway and the service is unreachable from outside (network policy / mTLS).