6

I am rearchitecturing and rewriting my monolithic BaaS solution into microservices regarding to scalability and single responsibility rules. Due to the internal dependencies, services are placed on different logical tiers. See figure below;

enter image description here

Instead of directly accessing to database or key-value storage, each service in Tier 2 must use Tier 1 Data Storage Service. Target of the internal service calls are located via Configuration Service hosted independently from API Gateway. API Gateway is deployed and configured per product. Product has an apikey and apisecret.

Scenario 1:

  • End users can login to the hosted product. (http*://host/authentication/login)

Scenario 2:

  • Business Service serves a custom logic: MyClass.MyOperation() (http*://host/business/myclass/myoperation)
  • End users of Business Service must be authenticated via Authentication Service to use the business logic (token based authentication)

On monolithic architecture, I was able to intercept dispathced business invocations via configured interceptors inside current executing http task. Therefore I was able to receive AuthenticationToken from business service request and decide whether the end user has authenticated via authentication service by directly querying the key-value storage.

Following the micoservice architecture, before executing business logic Business Service should make a request with transferring all original request headers to the Authentication Service, awaits its response, then parse the authentication result, and executes desired business logic then pipes to the response task. Single responsibility, fair enough.

Question:

  • Considering each Tier 2 services can be distributed anywhere inside the network, what options do I have in order to safely distinguish the internal and external requests between gateway and microservices?
  • Would this approach could be used to prevent internal service loop?
  • Can't you just make sure that the Gateway only sends messages to the Tier 2 services and precludes access to the Tier 1 services? – Erik Eidt Mar 30 '16 at 15:57
  • @ErikEidt tier 1 services are not exposed directly to the orchestrator; however gateway must be aware of the instance endpoints of tier 1 services for the sake of scalability. therefore the only option to internal service communication would be through the gateway. i could also consider suggestions for this structure too. – denolk Mar 30 '16 at 16:52
  • Perhaps you should (logically) add an internal gateway, so external one stays separate (e.g. an external Tier 2 load balancing gateway, and an internal Tier 1 load balancer). – Erik Eidt Mar 30 '16 at 16:57
3

The best thing to do is to ensure that all requests are from an authenticated source. This could mean a user request, but also a 'service' user that corresponds to each microservice. If a hacker gains access to your tier2, and you have an un-authenticated API, they can wreak havoc.

Each microservice should have its own distinct user for use for unsolicited requests, but generally every API call should be passing along the user token you received from the original request.

  • wouldn't this imply a lot of communication between each microservice and auth microservice? If I get it correctly, a request that would trigger the following interaction: User -> Business -> NoSql -> CDN actually triggers this interaction: User -> Business -> auth -> NoSql -> auth -> CDN -> auth am I correct? I also have this problem and I am considering using JWT to carry signed authentication material for each call so that any call to the auth microservice subsequent to the first one can be replaced with a local signature verification (e.g. this) – Davide Vernizzi Jul 11 '16 at 9:04
  • @DavideVernizzi no more than any other system has - currently the user has to supply logged-on token of some sort to access services, this just re-uses the same auth mechanism to apply to each microservice. Think of each one running as a different user. – gbjbaanb Jul 11 '16 at 9:18
  • agree, but in a monolithic architecture there is only one DB lookup to check if the call is authenticated/authorized, while in microservice architecture, this becomes many network calls. I am concerned with the overhead of these many network calls. – Davide Vernizzi Jul 11 '16 at 9:23
  • @DavideVernizzi that's still many DB calls. Why would there be many network calls if you use the token-based auth system we use on, say, the web already. Each service was run as a user that has auth permissions to the DB so it could only access its schema. Nobody would argue against that, so why would you argue against treating other services like the DB? Auth doesn't have to be DB lookups, you can do it once and pass a token around, then the called service decides if your token is good or not - some will ignore it, some will look up against an external system, some will look up internally. – gbjbaanb Jul 11 '16 at 9:28
  • 1
    Agree, but this doesn't work if each microservice has its DB separated from the others. In this case only auth microservice would have the possibility to check the validity of the token and, therefore, all the others would need to make a network call to the auth service to verify it. That's why I was thinking passing around a Token which is some data signed by the auth service so that the others do not have to actually call the auth service to check for correctness, but can locally verify. – Davide Vernizzi Jul 11 '16 at 9:35
2

Make sure you have some sort of context (for want of a better word) on all internal calls. This should contain an authentication token from the originator of any given request and can simply be passed on whenever you do internal requests.

You then need to perform authorization, based on the authentication token (ideally by verifying the token EVERY time), as appropriate within each micro-service.

For calls that are not due to an external user, make sure each one of your services acquires an appropriate authentication token, identifying it as the request originator.

Depending exactly on how your internal architecture looks, it may then be appropriate for a micro-service receiving a request identifying itself as the originator to result in an error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.