175

I'm having a hard time choosing a decent/secure authentication strategy for a microservice architecture. The only SO post I found on the topic is this one: Single Sign-On in Microservice Architecture

My idea here is to have in each service (eg. authentication, messaging, notification, profile etc.) a unique reference to each user (quite logically then his user_id) and the possibility to get the current user's id if logged in.

From my researches, I see there are two possible strategies:

1. Shared architecture

Shared architecture

In this strategy, the authentication app is one service among other. But each service must be able to make the conversion session_id => user_id so it must be dead simple. That's why I thought of Redis, that would store the key:value session_id:user_id.

2. Firewall architecture

Firewall architecture

In this strategy, session storage doesn't really matter, as it is only handled by the authenticating app. Then the user_id can be forwarded to other services. I thought of Rails + Devise (+ Redis or mem-cached, or cookie storage, etc.) but there are tons of possibilities. The only thing that matter is that Service X will never need to authenticate the user.


How do those two solutions compare in terms of:

  • security
  • robustness
  • scalability
  • ease of use

Or maybe you would suggest another solution I haven't mentioned in here?

I like the solution #1 better but haven't found much default implementation that would secure me in the fact that I'm going in the right direction.

kaya3
  • 47,440
  • 4
  • 68
  • 97
Augustin Riedinger
  • 20,909
  • 29
  • 133
  • 206
  • 1
    Would you please priovide more details on what you are trying to achieve? In the first case does authentication happen against Redis, or in the services themselves? Redis is missing in the second diagram, is this intentional? – Plamen G Apr 15 '15 at 10:53
  • I have added some information. Please let me know it is still unclear. Thanks! – Augustin Riedinger Apr 15 '15 at 12:30
  • Have you thinking about the idea to create a microservice which use the OAuth Protocol and your other's service use Token created? – Tiarê Balbi Apr 16 '15 at 00:50
  • I'm curious about this solution, but I still don't understand how it will work in practice. Do you know where I could find some standard implementations of it? – Augustin Riedinger Apr 16 '15 at 07:34
  • @AugustinRiedinger, thanks for putting this up. I am also breaking my monolithic web application into micro services by taking baby steps. In your case, are the Services 1-n stateless or state-full. In case they are state-full, have you thought about managing sessions in each of these services. Thanks – Manchanda. P Oct 07 '15 at 09:11
  • Well if you use a different session storage for each service, either the user has to login in every services, or you need to setup a process that for 1 signup, signs the user up on every other service, which in its most basic form, is to share the session ID, which corresponds to strategy #1. Or did I miss something? – Augustin Riedinger Oct 07 '15 at 15:02

5 Answers5

75

Based on what I understand, a good way to resolve it is by using the OAuth 2 protocol (you can find a little more information about it on http://oauth.net/2/)

When your user logs into your application they will get a token and with this token they will be able to send to other services to identify them in the request.

OAuth 2 Model

Example of Chained Microservice Design Architecture Model

Resources:

Matthew Murdoch
  • 30,874
  • 30
  • 96
  • 127
Tiarê Balbi
  • 1,480
  • 1
  • 23
  • 32
  • 1
    Thanks it is pretty clear. I found this very good article decomposing pretty much the same solution: http://dejanglozic.com/2014/10/07/sharing-micro-service-authentication-using-nginx-passport-and-redis/ – Augustin Riedinger Apr 21 '15 at 09:48
  • 19
    Your answer is great, but how does the token generated from the API Gateway (from inside of it, or in a AuthMicroService) can be handle by a random microservice, whose the aim is not to authenticate, and dont probably have oauth management inside of his business code ? – mfrachet Jun 23 '15 at 07:53
  • For example you can use Netflix Zuul to send the token received in the gateway to all services and they will know the user information. http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-security-oauth2 – Tiarê Balbi Feb 22 '16 at 15:20
  • Another nice thing about using OAuth2 between services is you can have endpoints which distinguish between service authenticated and user authenticated actions. – cmp Mar 21 '16 at 20:47
  • Check out this article for using microservices with oauth.http://nordicapis.com/how-to-control-user-identity-within-microservices/ – Declan Whelan May 03 '16 at 01:52
  • 2
    OAuth is more about granting a system access to a user's data held in another system. This to me looks like a good case for SAML. – Rob Grant Nov 27 '16 at 00:26
  • Better than SAML: Use OpenID Connect. – user2679859 Mar 02 '17 at 15:00
12

Short answer : Use Oauth2.0 kind token based authentication, which can be used in any type of applications like a webapp or mobile app. The sequence of steps involved for a web application would be then to

  1. authenticate against ID provider
  2. keep the access token in cookie
  3. access the pages in webapp
  4. call the services

Diagram below depicts the components which would be needed. Such an architecture separating the web and data apis will give a good scalability, resilience and stability

enter image description here

Sandeep Nair
  • 357
  • 3
  • 8
  • Doesn't AWS Lambda become "cold" and takes time to start up? That would make the login slow, wouldn't it? – Taku Sep 03 '19 at 17:07
  • @tsuz, AWS has now introduced concurrency feature in lambda where you can reserve the concurrency. With this you could fix the cold start problem. https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html – Sandeep Nair Jan 29 '20 at 19:31
  • I would have loved to have seen this answer years before, it makes incredibly simply to understand how microservices architecture with authentication and authorization independent microservices can be orchestated to give access to other services – brayancastrop May 01 '20 at 06:45
  • @Sandeep, I think you're referring to Provisioned concurrency and not reserved. – Anil Kumar May 12 '20 at 18:37
8

You can avoid storing session info in the backend by using JWT tokens.

Here's how it could look like using OAuth 2.0 & OpenID Connect. I'm also adding username & password login to the answer as I assume most people add it as a login option too.

enter image description here Here are the suggested components of the solution:

  1. Account-service: a microservice responsible for user creation & authentication. can have endpoints for Google, Facebook and/or regular username & password authentication endpoints - login, register. On register - meaning via register endpoint or first google/fb login, we can store info about the user in the DB. After the user successfully logs in using either of the options, on the server side we create a JWT token with relevant user data, like userID. To avoid tampering, we sign it using a token secret we define(that's a string). This token should be returned as httpOnly cookie alongside the login response. It is recommended that it's https only too for security. This token would be the ID token, with regards to the OpenID connect specification.

  2. Client side web application: receives the signed JWT as httpOnly cookie, which means this data is not accessible to javascript code, and is recommended from a security standpoint. When sending subsequent requests to the server or to other microservices, we attach the cookie to the request(in axios it would mean to use withCredentials: true).

  3. Microservices that need to authenticate the user by the token: These services verify the signature of the JWT token, and read it using the same secret provided to sign the token. then they can access the data stored on the token, like the userID, and fetch the DB for additional info about the user, or do whichever other logic. Note - this is not intended for use as authorization, but for authentication. for that, we have refresh token & access token, which are out of scope of the question.

I have recently created a detailed guide specifically about this subject, in case it helps someone: https://www.aspecto.io/blog/microservices-authentication-strategies-theory-to-practice/

Tom Weiss
  • 116
  • 1
  • 4
2

One more architecture perspective is to use nuget-package (library) which actually do authentication/token validaton. Nuget-package will be consumed by each microservice.

One more benefit is that there is no code duplication.

-5

you can use idenitty server 4 for authentication and authorisation purpose

you must use Firewall Architecture hence you have more control over secutiry , robustness ,scalability and ease of use

Vijay Parmar
  • 795
  • 4
  • 13