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:
- The frontend sends a request to a guarded backend route
- Because the user isn't authenticated, the server initiates a redirect to the SSO-Page provided by the identity provider.
- There the credentials are entered
- The user gets authenticated by the saml instance and it sends a request back to the server.
- 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
I've done something similar in a previous job with this logique:
- Implement a login page in Angular (Simple Form to get credentials),then call a login service in the backend.
- 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).
- 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.
- In the frontend, implement a guard which should handle token/ set user credentiels into local storage...
- 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.
- 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.