views:

266

answers:

1

We have an email confirmation page for registration which can be hit with a use-once link to activate the account.

The nature of the site is such that we can allow this link to log the user in automatically. This requirement is under review (at my request!).

The following situation is proving a little confusing:

  1. The user follows the confirmation link in their email
  2. This lands on the Confirm controller.
  3. All things being good, the user is automatically logged in, using:

    FormsAuth.SignIn(user.UserName,false);
    
  4. The View is returned from the controller

The View uses a master page which contains a partial view that is the LogonUserControl.ascx component. Within the component, there is the following code (it comes straight out of the asp.net mvc project template):

if (Request.IsAuthenticated) { /*foo*/ }

When the page is rendered, Request.IsAuthenticated is returning false despite signing the user in at the controller.

I'm wondering why this might be. Has the master already been written out by the time the FormsAuth.SignIn method is called, or is using the Request object for this check wrong, because at the time the Request was received, it was indeed non-authenticated?

EDIT: It appears the default LogOn controller uses a redirect rather than returning a View. This would of course solve the problem, however I am interested in why the scenario above does not work.

+3  A: 

It doesn't work because the Request, which has already happened before your action runs, wasn't authenticated. A Request is either authenticated, or it isn't; it cannot start life as a non-authenticated and become authenticated in the middle of an action. An Authenticated request is one which was submitted with a valid authentication ticket. Since the login request did not include that, it isn't authenticated and cannot become authenticated.

However, when you redirect, the browser issues a new request, which does, of course, come with a valid authentication ticket, usually in the form of a cookie.

Incidentally, redirecting is the right thing to do in this case. Your login is a POST, and you should use the Post/Redirect/Get pattern. Imagine that the login page returns the user to the site home page. If you return the view instead of redirecting to the home page, then when the user pressed F5 to refresh the page, the browser would warn them that they were about to resubmit their login credentials, which isn't what you want. Doing a redirect makes the browser do a GET for the homepage, so the user will not be warned if they press F5.

Craig Stuntz
Great explanation, ran into this awhile ago, never understood why, now I do.
mxmissile