We are implementing two-factor authentication, and after much consideration we’ve gone with an approach that I would like to run by you. We’ve also run into an issue with Tyk that seems to prevent this approach from working.
Consider a client app hosted at app.example.com, and our login page hosted at login.example.com. The Tyk-managed API is public at api.example.com. It has an endpoint, at api.example.com/session that internally returns the meta-data from the Tyk key/session.
We’re using the OAuth 2 flow to sign people into app.example.com, basically:
- User tries to access restricted area on app.example.com
- User is redirected to api.example.com/oauth/authorize
- User is redirected to login.example.com
- User logs in using username and password
- Server at login.example.com verifies credentials and creates a Tyk key for user, handing them the code
- User is redirected back to app.example.com, carrying the code
- Code is exchanged for token by app.example.com
This is working great. Now we want to introduce two-factor authentication, but we don’t want to do it all the time. Only when the user is trying to access certain resources which are even more restricted. My initial idea was to do the same thing again but indicate in the scope
parameter that two-factor authentication is required. I quickly realized Tyk strips away the scope
parameter.
My next approach was to redirect the user to login.example.com, carrying along their access_token
, which login.example.com then uses to upgrade their key after successfully authenticating, i.e.:
- User tries to access even more restricted area on app.example.com
- User is redirected to login.example.com, carrying their app.example.com token
- User authenticates using SMS or whatever
- Server at login.example.com updates the Tyk key/session identified by the
access_token
to indicate in the meta-data that the user is now authenticated using two-factor authentication - User is redirected back to app.example.com, where the same token is now upgraded
First of all, what do you think of this approach?
Second, I’m having problems updating the the key. More precisely, I can upgrade it using PUT or POST to /tyk/keys/{access_token}, and it’s updated correctly. But when I redirect back to app.example.com, and it tries to access /session in my API which in turn GETs /tyk/keys/{access_token} (to return it’s meta-data) it hasn’t been updated.
If I sleep my code a few seconds after updating the key, before retrieving it again from app.example.com, it works.
Any idea why this would happen? Does it take time for it to propagate through my single-node Tyk system or something?