Geeks With Blogs

News profile for Aligned at Stack Overflow, Q&A for professional and enthusiast programmers

Donate Bitcoins

Check out Elapser from T3rse!
"free in Christ Jesus from the law of sin and death." Romans 8:2 (ESV) Check out the Falling Plates video on YouTube.
more about the Gospel
And then listen to Francis Chan speaking at LifeLight in SD.

Programming and Learning from SD

Edit on April 10, 2014: A lot has changed since I started this now out of date post and Microsoft has created and updated the authentication system to ASP.Net Identity. Please look at this first. Here's a video on the subject.


First: After searching for awhile to figure out what’s new/different with MVC 4 and forms authentication, this is the best article I've found on the subject:

http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4-5-web-forms-and-asp-net-mvc-4-templates.aspx

Some quotes from the article:

  • “The ASP.NET Web Pages team designed SimpleMembership to (wait for it) simplify the task of dealing with membership”
  • "WSAT is built to work with ASP.NET Membership, and is not compatible with Simple Membership.

    There are two main options there:

    • Use the WebSecurity and OAuthWebSecurity API to manage the users and roles
    • Create a web admin using the above APIs
    • Since SimpleMembership runs on top of your database, you can update your users as you would any other data - via EF or even in direct database edits (in development, of course)"
  • “If you want to use an existing ASP.NET Membership Provider in ASP.NET MVC 4, you can't use the new AccountController. You can do a few things:”
  • “Universal Providers do not work with Simple Membership.” ~ this post (look for Bob.at.SBS’s answer) says Universal Providers is not needed for MVC 4 to work in Azure)

 

I've been trying to figure out the Forms Authentication in MVC4. It's different than the past approach (aspnet_regsql). If you do file new project -> MVC 4 -> internet application, you get a really nice template with the controller and model setup for you. However, the tables are different than using aspnet_regsql and the ASP.Net Configuration tool (WSAT) wasn’t connecting to the data I had (it was creating an App_Data/aspnet.mdf file, which I didn’t see right away).

Points of Note

  • The database tables are created in the InitializeSimpleMembershipAttribute.SimpleMembershipInitializer class by the  WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true); method.
  • The tables created are webpages_Membership, webpages_OAuthMembership, webpages_Roles, webpages_UsersInRoles, UserProfile.
  • Web.config settings won’t work.
        - If you want to handle lockout based on the number of failures, you can call Websecurity.IsAccountLockedOut: see http://stackoverflow.com/questions/12206192/simplemembershipprovider-websecurity-configuration
        - http://stackoverflow.com/questions/12702649/simplemembershipprovider-minrequiredpasswordlength-always-returns-0-despite-it-b ~ the answer states you can’t use the web.config settings
  • When adding non-nullable values to the UserProfile, you also need to modify the AccountController.Register method, or you wont’ be able to create a new user / it will just have the defaults set. Here I’m using a ComplexType and setting them before creating the User (I’m moving this to a method in the UserProfile for a refactor):

    var values = new { ModInfo_CreatedDate = DateTime.UtcNow.ToString(), ModInfo_CreatedByUserId = 0 }; 
    WebSecurity.CreateUserAndAccount(model.UserName, model.Password, values);

  • Roles (10/31/12): I was trying to use User.IsInRole and it was always returning false. I found this post that helped me get past this on Stack Overflow: http://stackoverflow.com/questions/12257232/role-based-authentication-in-the-new-mvc-4-internet-template-using-simplemembers. 1) add the <roleManager to the web.config, which leads to the error “You must call the "WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" class. This call should be placed in an _AppStart.cshtml file in the root of your site.”. This is fixed by adding filters.Add(new InitializeSimpleMembershipAttribute()); to the Application_Start (FilterConfig.RegisterGlobalFilters for MVC 4).

  • PasswordSalt: I saw that the PasswordSalt column is empty. I then found this question that lead to this answer.
    “The good news is that appearances can be deceptive, and that the SimpleMembershipProvider does indeed salt hashes. In fact, the SimpleMembershipProvider makes use of the little known Crypto Helper whose HashPassword method is of most interest in relation to this article…”

  • Helpful Links

Scott Hanselman on Universal Providers was also useful if not somewhat out dated. Universal Providers and SimpleMembership are not compatible.

http://www.asp.net/web-pages/tutorials/security/16-adding-security-and-membership – walk-through

http://blog.osbornm.com/archive/2010/07/21/using-simplemembership-with-asp.net-webpages.aspx - use SimpleMembership with Asp.Net

https://nuget.org/packages/MvcMembership/3.7.0 ~ Nuget package that has the roles administration built in, not sure if it works with SimpleMembership

http://msdn.microsoft.com/en-us/library/webmatrix.webdata.simplemembershipprovider%28v=vs.111%29.aspx

http://odetocode.com/Blogs/scott/archive/2012/10/01/build-your-own-membership-system-for-asp-net-mvc-part.aspx ~ K. Scott Allen is building his own membership system. This seems worth keeping an eye on.

http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/ ~ EF5 CodeFirst with SimpleMembership tutorial

http://blog.spontaneouspublicity.com/including-asp-net-simple-membership-tables-as-part-of-your-entity-framework-model ~another introduction

http://blog.spontaneouspublicity.com/including-asp-net-simple-membership-tables-as-part-of-your-entity-framework-model ~shows how to abstract out the WebSecurity calls for unit testing

http://weblogs.asp.net/thangchung/archive/2012/11/15/customize-the-simplemembership-in-asp-net-mvc-4-0.aspx ~ Article about customizing simple membership.

You must call the "WebSecurity. InitializeDatabaseConnection” error

 

We kept getting the ”You must call the "WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" class. This call should be placed in an _AppStart.cshtml file in the root of your site.” exception during development. We’d modify a page, then refresh and sometimes get an exception. It fixed it by going to the main index page and then back. The was happening because Simple Membership needs to be initialized in code before it can make any queries into the the membership. Here is what I did:

This probably won't make any sense, unless you've seen the code already and have the same setup as I do, but hopefully it will help out or you can let me know if I did it incorrectly.

I added a method on the Web.Filters.InitializeSimpleMembershipAttribute class that is setup in the FilterConfig file. I think this came with the new MVC 4.5 template??

so in FilterConfig public static void RegisterGlobalFilters(GlobalFilterCollection filters): I have a line:

// setup the Membership provider
filters.Add(new InitializeSimpleMembershipAttribute());

And in InitializeSimpleMembershipAttribute I added a static method:

 public static void Initialize()
 {
    if (!WebSecurity.Initialized)
    {
        WebSecurity.InitializeDatabaseConnection(
           "DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: false);
     }
 }

 

Then I call that in my base controller before I try to work with the membership system through the WebMatrix.WebData.WebSecurity object.

// don't do it if mocked with FakeItEasy
if (this.WebSecurity.GetType().FullName != "Castle.Proxies.ObjectProxy")
{
  InitializeSimpleMembershipAttribute.SimpleMembershipInitializer.Initialize();
}
 

Remember Me

I was expecting that checking the remember me checkbox from the new MVC template would fill in the username the next time I came to the site (similar to mint.com or other sites). My assumption was incorrect and it is setting a “persistent cookie” that “true to specify that the authentication token in the cookie should be persisted beyond the current session; otherwise false. The default is false.” ~ http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity.login(v=vs.111).aspx. The source code comments say “(Optional) true to specify that the authentication token in the cookie should   be persisted beyond the current session; otherwise false. The default is false.”

I’ve been searching for a better explanation of this, but haven’t found it. I’m ‘persisting’ my logins using the web.config and the forms authentication, so it doesn’t seem like this does anything for me.

<authentication mode="Forms">
      <!-- 12 hours = 720 minutes without sliding for my example -->
      <forms loginUrl="/" timeout="720" slidingExpiration="false" />
</authentication>

To add my expected behavior, I’m manually adding a cookie and reading it and it’s simple to implement.
In my Login action I added:

if (model.RememberMe)
{
    // Bug 619, add the username cookie to fill it in next time, keep increasing the timeout.
    var cookie = new HttpCookie("USERNAME") { Value = model.UserName, Expires = DateTime.Now.AddDays(14) };
    this.Response.Cookies.Add(cookie);
}
else
{
    // delete the cookie
    if (this.Request.Cookies["USERNAME"] != null)
    {
        var cookie = new HttpCookie("USERNAME") { Expires = DateTime.Now.AddDays(-1D) };
        this.Response.Cookies.Add(cookie);
    }
}

in the login load view action

var loginModel = new LoginModel();
if (this.Request.Cookies["USERNAME"] != null)
{
    loginModel.UserName = this.Request.Cookies["USERNAME"].Value;
    loginModel.RememberMe = true;
}

return this.View("Login", loginModel);

Posted on Thursday, August 30, 2012 1:20 PM MVC 4 | Back to top


Comments on this post: MVC 4 Authentication

# re: MVC 4 Authentication
Requesting Gravatar...
Thanks for this summary. I really like the look of the SimpleMembership providers but it doesn't seem easy to migrate your existing data to the new SimpleMembership provider. See http://stackoverflow.com/questions/12236533/migrating-from-asp-net-membership-to-simplemembership-in-mvc4-rtm
Left by Jim on Sep 03, 2012 4:18 PM

# re: MVC 4 Authentication
Requesting Gravatar...
I've been searching for the same topic and puzzled how there can be such a small number of published posts about it - and for that matter, so few questions about it at StackOverflow.

You'd think this is kind of a significant new feature and would generate quite a bit more traffic.

thx
Left by Steve on Sep 07, 2012 1:06 PM

# re: MVC 4 Authentication
Requesting Gravatar...
This article covers full integration with SimpleMembershipProvider and SimpleRoleProvider.

http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/
Left by Long Le on Sep 24, 2012 9:39 PM

# re: MVC 4 Authentication
Requesting Gravatar...
I think this blog will help you with migrating from existing databases
Left by Derese Getachew on Jan 21, 2013 7:31 PM

# re: MVC 4 Authentication
Requesting Gravatar...
can anyone help me with mvc4 authentication using my own database tables
Left by noha on May 19, 2013 5:04 PM

Your comment:
 (will show your gravatar)
 


Copyright © Aligned | Powered by: GeeksWithBlogs.net | Join free