I have an application where our domain users can register their domain account via an Active Directory interface. They can then unlock their account or reset their password via this application. These two "functionalities", the registration/administration & the unlock/reset, take place on different servers. The whole process of unlocking or resetting uses two-factor authentication via a token app on the mobile phone. The only way to link the token to the app is by scanning a QR code (or typewriting the code) which is shown in the registration process. So far so good.
Now it can happen that we have to reset the mobile phone of a user completely, for example for sending it to repair. Even with a backup, the data in the token app cannot be restored. So far, the only possibility to get the QR code back, is to completely delete the registration in our service and re-register again, thereby generating a new QR code. The process of registration takes a while, as you have to think of several security questions (and answers). This is not very user-friendly.
My task now is to implement a function that allows you to show the QR code. This page can be accessed from the "administration" page each user has for their account. The whole site uses single sign on, which of course makes sense, as you don't want to enter the password every time you want to edit a security question for example.
With single sign on, every person can walk up to another user's computer and if it isn't locked, show and scan their QR code, change the security questions so they know the answers, reset the victim's password and log into their account. This has to be prevented of course, as it poses a huge security risk.
To check if it's the same user that logged in, I use a cookie with the username from SSO. Then, in the controller, I check if it's equal to
User.Identity.Name. If not, I set the cookie with the username from SSO and the rest of the response:
// do some irrelevant stuff
Request.Cookies["cookieName"] = User.Identity.Name;
Response.StatusCode = 401;
Response.StatusDescription = "Unauthorized";
This works just fine. There is one problem though: If you click on cancel in the Windows Security window, you'll be redirected to a "unauthorized access" page. You can then, however, refresh the page and TADA! Single Sign On logged you in automatically and you or the attacker can therefor see the QR code.
How can I go around SSO in this specific scenario? So far I have only found solutions saying that I should turn off SSO which would affect the whole application.
I know this is a long question, my English might not be clear in some cases and I possibly left out some information unintentionally. Feel free to ask for more information.