How to design a stateless REST Login with 2 Factor Authentication (2FA)?

感情迁移 提交于 2019-12-05 04:56:39

I'm adding the solution I came up with in case it is beneficial for someone else in the future. Please note that in this case, PVQ stands for "Personal Validation Question" (ie: Knowledge-Based-Authentication).

At the end, I designed my login endpoint to require:

  • Authorization header (which is a 2FA token) : Authorization: authType=”PVQ” token=”<tokenid>”
  • username
  • password

If the Authorization header is missing, the endpoint returns a 401 and sets a WWW-Authenticate header, indicating that a 2FA token (ie: Authorization header) is required to login. param could be PVQ, SMS, TOTP, etc (based on the user's configuration)

WWW-Authenticate : authType="PVQ"

If the client receives a 401/WWW-Authenticate response, it is its responsibility to call the 2FA endpoints:

  • challenge/get (receive a challenge token)

    • Client: sends username/password
    • Server: Responds with an ID, and either
      • a question (PVQ),
      • or just sends sends an SMS code via 3rd party SMS provider
  • challenge/verify (receive the 2FA Token needed for the Authorization header)

    • Client: sends
      • ID received in the challenge/get
      • username/password
      • response to the challenge (ie: text answer to a PVQ, or SMS code, or TOTP code)
    • Server: returns
      • 2FA token value

The client can now call the login endpoint with the required: username/password/Authentication token.

In the end, there is not "state" per say that the client returns to the server, but the tradeoff for this, is that the username/password combination must be sent to every request for the 2FA subsystem.

On the server side, there is some state information stored in the DB in the context of the SMS code or PVQ question that was sent to the user, as well as an ephemeral Authentication 2FA token (single use, and fixed TTL).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!