4 ms·
It's an interesting idea, but that would mean every internal microservice request (they don't just service users) would have to go through an API gateway, and e
by lobster_johnson 10y ago
It's an interesting idea, but that would mean every internal microservice request (they don't just service users) would have to go through an API gateway, and every call would have to be checked against a session store.
It also means (if I understand the design correctly) that the API gateway has to munge every request envelope to add the actual user ID as an HTTP header (or something similar with gRPC), so that the internal microservices can see it, otherwise they'd have to ask the session store, which would defeat the purpose.
This in turn would mean that every microservice has to trust the upstream, which would require some infrastructure to manage (i.e., microservices would no longer be simply exposed to the world; the API gateway would be a special trusted actor). You also now have a dependency on the API gateway, because the microservice wouldn't know how to deal with a session without it.
- DenisM 10y agoThe services are behind the firewall, unreachable from the internet, and only accept requests from the gateway, and from each other. The gateway strips your SSL (which I'm sure you are using :)), authenticates the request against its local security token store, then adds a bunch of headers: request id for tracing purposes, user IP for logging purposes, user id for authorizing access to various resources, etc. The service only accepts the request, it doesn't care where the request came from because it implicitly trust the environment to be protected from direct, unauthenticated calls. Request has the user id in it, so the service knows which data is being accessed. This way we have separated concerns of security from that of state management. This is what I'm arguing for - security without unnecessary public-facing crypto, and separation of authentication from authorization. The problem public-facing crypto is that there are tons of obscure of attacks on it - manipulating individual bits and sending it to the victim often yields information. New exploits come to light every now and again. I was caught with my pants around my ankles when padding oracle attack against signed cookies came out of the clear blue sky: http://robertheaton.com/2013/07/29/padding-oracle-attack/ http://robertheaton.com/2013/07/29/padding-oracle-attack/ Now, to keep the session state you have three options: - Do the same thing you do with JWT: send the data to the user and accept it back. You know the user has been authenticated already, he can only harm his own resources. When services call each other they pass the session state along with the call, same as JWT again. - Keep the session data in the centralized session store. Which kid of defeats the purpose of eliminating the centralized session store. :) There are many ways to make that scale well for throughput, e.g. once you know the user id you can trivially shard the session store, but I'm not sure about the latency from accessing yet another machine. This needs to be tested though, perhaps it's negligible. But let's keep that out for now, given the scope of the article. - Keep the session store at the gateway. When the service replies to the request, part of the payload is the new (additional) session data. The gateway strips that part and keeps it to itself. The next time gateway calls a service for the same user it passes the session data along. The service does not need to know anything about the gateway - it receives a request with user id and session state, then returns the result with new/updated session state. The nice thing is that the users never see the session state (shorter url, less data on the wire, lower chance of malformed data), and yet microservices never have to know where it came from. When services call each other they can attach the state along with it. It may get tricky having to pass the sate back and forth along the call chain of various services, but it's the same problem you would have with JWT anyways. The complexity is why I would circle back to sharded session state storage. Hopefully this answers all of your questions, let me know if it doesn't? It's an interesting conversation, thanks for that.
- lobster_johnson 10y agoYou're right about the API gateway being a good pattern for sending external traffic to internal microservices, and it is something you'd want regardless of what session system you used. I'd let microservices talk directly to each other, however, rather than going through the API gateway. This means you reserve the API gateway for external traffic, and trust the internal traffic. You still need to standardize on/configure a set of "context headers" to pass from one services to another so that the identity of the original caller is preserved; but since this won't rely on a session, it can be trusted and treated opaquely by each application. My earlier point stands, though: Once you deploy something like this, you now have an explicit dependency on the API gateway, because services can never be directly exposed to the world. It impacts local development, too, because now you either talk using session via the API gateway (which you have to run locally) or directly to the service (using whatever identifying information it trusts), and the fact that they are different is a potential point of confusion, especially for someone not familiar with the architecture. ("It isn't working" — "Oh, you need to go through the API gateway.") Interesting conversation indeed. I wish there were a better forum for such discussions. There's a lot about microservices where I'd love to exchange ideas and good patterns.