Search code examples
node.jsangularpassport.jssamlsaml-2.0

SAML-Authentication using angular, node.js and an identity provider


I want to to implement SSO using SAML2. But I don't know how to get it work with a distributed system where each instance is running independently on its own server. The environment consists out of three instances:

  • Instance #1: an angular frontend
  • Instance #2: a node.js backend (using express.js + passport)
  • Instance #3: a SAML instance (identity provider)

The question is what would be the best approach if the frontend calls a guarded backend route? Which sequence of actions can be seen as good practice?

At the moment I have this behaviour in my mind:

  1. The frontend sends a request to a guarded backend route
  2. Because the user isn't authenticated, the server initiates a redirect to the SSO-Page provided by the identity provider.
  3. There the credentials are entered
  4. The user gets authenticated by the saml instance and it sends a request back to the server.
  5. Now the user is authenticated, the server sends back the response with the requested resource to the client.

But as long as I think about this sequence I realize this couldn't work. Its because the frontend is its own instance and it is independent from the backend. The redirect to the SSO-Page initiated by passport don't work if you have a separated frontend instance. It works if you call the guarded route directly with the browser, because then you have only two communication partners (service provider & identity provider) instead of three. But this is not the case here.

Thanks and regards

Philipp


Solution

  • I've done something similar in a previous job with this logique:

    1. Implement a login page in Angular (Simple Form to get credentials),then call a login service in the backend.
    2. That backend login service should verify the credentials provided by the frontend against the identity provider (I'm sure they would provide you an url where you can inject these params).
    3. Once the identity is verified, call an athentication service in the backend to generate a token for this user (Passport JS should do the job) then send back this token to the frontend.
    4. In the frontend, implement a guard which should handle token/ set user credentiels into local storage...
    5. In the frontend, implement also an interceptor which injects this token in every XHR header or redirect the user to the login form in case token is absent or expired.
    6. In the backend, the logique will be classical (verify token validity from XHR header before sending back data / tell the frontend to login if the verification fails).

    With this logique you'll keep the frontend away from the identity provider and in coherence with the backend.