.NET MVC4 SimpleMembership Error - "No user found was found that has the name xxx"
Asked Answered
S

6

6

I am using SimpleMembership in my .NET MVC4 project. During development, while manually manipulating/rebuilding the database, I've come across an error that would be unlikely in production, but I want to solve this and I cannot find a graceful way to handle it.

If, after logging in to the application, your username gets changed in the database, or your user record deleted entirely, the user will no longer be able to access any page of the application... including public pages that allow anonymous views, and the login screen. Instead, an exception is thrown - "No user found was found that has the name 'username'".

All pages in my application display a partial view which renders a login/logoff control. Request.IsAuthenticated is returning true regardless of what's in the database. It seems the app thinks the user is still logged in based on information in the cookie, but no corresponding record can be found in the database. Clearing the auth cookie solves this, but that's not an instruction I would want to provide to a user that may be experiencing this.

My current solution is to catch that exception in the Global.asax, clear cookies, and redirect to the login page. This just seems entirely hacky to me.

Has anyone got a better solution to this scenario? I've never encountered issues like this using the old .NET Membership provider... my expectation is that this situation should be covered right out of the box and I shouldn't have to account for it... if a record is altered/deleted in the DB, the user should just fail authorization and be redirected to the login page automagically.

Spreadeagle answered 30/11, 2012 at 23:51 Comment(0)
M
2

Not sure where you have your authentication logic first, but here is what I do:

In Global.asax.cs:

    protected void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError();

        if (ex.Message.Contains("No user found was found that has the name"))
        {
            FormsAuthentication.SignOut();
            Response.Redirect(Request.RawUrl);
        }
    }

Since the thrown exception is just a System.InvalidOperationException, there is not much you can do with it. Not very smart, but does what needs to be done. Also, make sure that on the page you're redirecting to there is no authentication logic like IsUserInRole(...), if yes then you might wanna wrap it in try{} catch(){}

Mallet answered 4/11, 2013 at 5:29 Comment(0)
S
1

Can you please check the db cache or somewhere the page, after logging in, dependency of the user record, where it is dependant, chain delete or it may be occuring due to the dependency injection.

Please check for it or please share the code..

Sibyl answered 13/12, 2012 at 8:1 Comment(0)
B
1

I was having the same kind of problem, IsAuthenticated returning true while I was not logged in the MVC 4 site, resulting in the same error message. In our solution I had two MVC 4 sites with SimpleMembership and it turned out that I was logged in to the first site while debugging the second site. I think it will have to do with the cookie that gets set as both sites run under adifferent port on localhost en so both will set the same authentication cookie. I will probably need to change how the authentication cookie will be set.

I think you might have a different problem, but maybe my "solution" can help someone having this issue.

Blaspheme answered 13/1, 2014 at 10:30 Comment(1)
This solution worked for me, I was logged in from another site and when i switched sites it was giving me this error. Just clear your cache / cookies, it will work fine.Energize
W
0

Override AuthorizeAttribute:

public sealed class AuthorizeAttribute : System.Web.Http.AuthorizeAttribute
{
  protected override bool IsAuthorized(HttpActionContext actionContext)
  {
    try
    {
      return base.IsAuthorized(actionContext);
    }
    catch
    {
      return false; // user name from cookie is no longer in db
    }
  }

  protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
  {
    // handle this exception by global exception filter for redirection to login
    throw new CustomAuthException(); 
  }
}
Wakerly answered 12/2, 2015 at 9:30 Comment(0)
C
0

I have added to Arman Bimatov response so that it log's you out before redirecting you to the current page. And by redirecting you to the current page then returnURL will be correctly placed into the query string.

In Global.asax.cs:

protected void Application_Error(object sender, EventArgs e)
    {
      Exception ex = Server.GetLastError();

      if (ex.Message.Contains("No user found was found that has the name"))
      {
        FormsAuthentication.SignOut();
        Response.Redirect(Request.RawUrl);
      }
    }

However, this will not work unless you have a CustomerErrors section in your web.config as per this question: global.asax Application_Error not firing

Chiliad answered 25/7, 2016 at 14:16 Comment(1)
#3714439Chiliad
M
-1

This seems to be caused when switching from you dev environment to another host. The localhost is remembering the login cookie and trying to use it against the new simple membership database.

As you said it doesn't happen in production. Sorry I don't know a better way short of using the same login on both databases local and production.

Miltiades answered 3/2, 2013 at 14:17 Comment(1)
Well I imagine it still would happen in production, all I meant was that it likely wouldn't happen because in a production situation I wouldn't be manually deleting records in the database. It's not a matter of switching hosts. I've not spent much more time trying to figure out how to overcome this, but it basically has to do with an authentication cookie in my browser that references a user which no longer exists in the database... I just wish this was handled more gracefully out of the box.Spreadeagle

© 2022 - 2024 — McMap. All rights reserved.