I've a password protected web application (ASP.NET 4.5), and a requirement that when a registered user accesses the site from a device for the first time, I should authorize that access by sending an authorization code to user's email, and validating that s/he can provide the correct code back.
It's not mandatory, but considered nice if user does not have to authorize the device when s/he accesses the site using two different browsers on the same machine.
Once device is authorized, system must not prompt user for an authorization until some period is expired, say a month.
Solution must also be tolerant towards for dynamic IP community, and should not keep prompting for authorization, just because the IP visible to outside world changed.
Here is how my current solution works, but apparently it has some weaknesses.
I primarily depend on the user's IP address to detect if this is a new device (Did not use User Agent string, as they seem to change when browsers update).
- When a request comes in, I check if there is a cookie indicating that device is authorized by this user already, if so request may proceed.
- If a cookie is not present, I check in local db to see if there is an authorization obtained for this IP by the user, by correctly entering an emailed code.
- If authorization record is found, in order to remember authorization for this device (and not to prompt again if IP changes), I create a cookie in client's browser, set to expire in a month, or whatever time left on that obtained authorization.
- If neither a cookie, nor a authorization in database is not found, user will be redirected to a page, where he can request a new code to be sent to his email Once code is requested, user is sent to a second page, where he can enter the code emailed to him.
- If the correct code is entered on the second page, corresponding record is updated to reflect the authorization, and user is redirected back to the original page he tried to access.
- Now we will hit the first step again, find the authorized record in local db, and will create the cookie.
- Other requests should proceed normally as now there is a cookie in the request.
My questions are:
- Any obvious issues in this solution, to which I've been blind?
- Are there any tools/frameworks which could be useful in implementing this kind of requirement?
- Any best practices/patterns/anti-patterns that I'm not aware of applicable to this kind of scenarios?