Search code examples
asp.net-mvcasp.net-identity

What's the purpose of this SignInManager call when the controller has the [Authorize] attribute?


Having set up a default ASP.Net MVC 5 application, I fail to understand why the below snippet has a call to SignInManager.

This is in the ManageController, which has the [Authorize] attribute.

    //
    // POST: /Manage/RemoveLogin
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> RemoveLogin(string loginProvider, string providerKey)
    {
        ManageMessageId? message;
        var result = await UserManager.Get().RemoveLoginAsync(User.Identity.GetUserId<int>(), new UserLoginInfo(loginProvider, providerKey));
        if (result.Succeeded)
        {
            var user = await UserManager.Get().FindByIdAsync(User.Identity.GetUserId<int>());
            if (user != null)
            {
                await SignInManager.Get().SignInAsync(user, isPersistent: false, rememberBrowser: false);
            }
            message = ManageMessageId.RemoveLoginSuccess;
        }
        else
        {
            message = ManageMessageId.Error;
        }
        return RedirectToAction("ManageLogins", new { Message = message });
    }

I am wondering if, whenver I retrieve the authenticated user, I should repeat this step, i.e. check if the user is null and if not, await SignInAsync. Edit: check if the user is null and if it is, await SignInAsync

Now, I've created a new controller, that I've given the [Authorize] attribute, and in the Index() function of the controller, I do:

        var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<int>());

If I load that page in two tabs, sign out in one of them and then refresh the page, I'm redirected to the login screen. I've attached a debugger and have been unable to cause a case where the SignInManager is hit.

In what scenario would the user be not-null?


Solution

  • They do entirely different things. The Authorize attribute checks that the user is authenticated and authorized to access the action (based on role permissions and such). It doesn't authenticate the user. That's what the call to SignInManager is for. It actually authenticates the user, so that the user can then pass checks made by the Authorize attribute.

    As for when the user might be null, effectively, if the action is protected by Authorize it probably never will be. It would have to take some strange confluence of events where the user was found in the database in order to sign them in, but then somehow was removed by the time you tried to retrieve it. In other words: not bloody likely. Still, it's good practice to always perform a null-check like this when a value could potentially be null, which user could.