How does the default template for asp.net mvc store accounts (the AccountController)? Can I add unique numbered ids, since so far I have found out, that it uses unique login as primarz key? Is there a table containing these accounts? And which classes should I look for to work with them?
Thanks in advance.
It doesn't use the unique login as the primary key, not really. Under the hood there's a provider specific membership identifier, which in the case of the SQL membership provider is a GUID.
MembershipUser membershipUser = Membership.GetUser();
object userKey = membershipUser.ProviderUserKey;
In fact it's even more complicated than that, as you can have multiple applications sharing a membership database, either sharing the users, or using an application name to distinguish their users from each other, but calling ProviderUserKey will get the right result every time.
The default MVC app will generate an ASPNETDB.MDF file in the App_Data directory when the first person registers. This contains the "standard" ASP.NET SQL membership schema, which ties in with the various MembershipProvider classes.
I've not really worked with the SQL membership stuff, but I imagine you could extend the schema and the classes to suit yourself.
Why do you need a unique id rather than using the default?
Related
In asp.net i am using Membership where i have used
Membership.CreateUser(login, password, email, null, null, true, out status);
But I've the requirement where i want some more info from
user such as Contact no and Short name
System has created tables for membership using aspnet_regsql.exe
But i've above requirement with more custom column
How i can store them
Do i modify those table but at a same time Membership.CreateUser has only limited entities
Please help
you could use the asp.net Memberhip Profiles. but I find it to be very limiting. For my last project, I created a separate table with specific columns to hold the extra data. the PK was the username. then I would simply query for the custom properties.
var profile = context.Set<Profile>().Find(User.Identity.Name);
You may also want to take a look at the Universal Membership Provider. It's much more flexible than the asp.net membership provider.
In my application I need to register users. The users can be any of three: admin, client and general. They have different attributes (Admin may have only name, client may have company address and so on). The default MVC membership scheme is okay but how can it be extended to register more information during registration time? Or should I use custom membership?
I need to have a record of clients and general users with clientID or generalID.
The default MVC membership scheme is okay but how can it be extended
to register more information during registration time? Or should I use
custom membership?
I think too many people, yourself included, are expecting to get too much from the default ASP.NET Membership Provider. It was never designed to handle application-specific things, like what company your customer works for, your admin's name, and so on. It's main purpose is storing passwords for authentication.
Sure, the password needs to be linked to a username, so that there can be a 2-key authentication pair. Sometimes you also need the user's email address, when it is different from their username, in order to contact the user regarding their password. But don't store anything else about your users in the membership store. Store it in your application database.
In order to join data between your application and the membership provider, use the membership provider's UserName or ProviderKey as a column in one of your database tables. You end up with 2 entities which are not explicitly related. You can even have your SqlMembershipProvider implemented in a separate database from your application database. Even if they are in the same database, avoid having a foreign key between any of the provider tables and your application tables. This muddies the waters between what you own, and what you "outsource" to the membership provider.
You end up with 2 physically isolated representations of your user. One is the MembershipProvider, which contains a password for your user. The other is your application, which contains other business-specific details. The two are only logically associated within your application. After you authenticate a user with the membership API, their UserName and/pr ProviderKey become available to your application. You can then use that piece of data to query your app database and get the additional details. This is where you might put something like the clientID or generalID you mentioned.
If you look at the System.Web.Security.Member* API, this should make things clearer. It does one thing really well -- associating your users with passwords and other information related to password resetting (like the email address, question and answer, etc). So outsource just the password provider, and rely on your application to do the important stuff.
You could customise the default profile provider or create your own... Follow this reference
http://msdn.microsoft.com/en-us/library/8zs47k7y
You can add new properties to the profile for anything in the web.config too
I highly suggest creating your own membership roles. It's dead simple and nothing can beat the flexibility of having your own implementation.
Here's a video I made a while back showing you step by step how to achieve this:
http://www.youtube.com/watch?v=BsxUsyMSGeA
The gist of it is, you create your own AuthorizeAttribute and create your own roles; protecting each controller or even individual Action methods along the way.
The one drawback of this approach is that you can determine what Role a user has in your system, but not what a Role can do in your system. Does that make sense?
There are other choices if you need to edit what a role can do at runtime.
I am building a multi-tenant site with MVC3. Prior to this project I had never touched either the .NET stack or web development in general, so as you can imagine my domain knowledge is somewhat lacking.
I'm still using the default AccountController architecture, but I pretty quickly determined that I didn't want to use aspnetdb.mdf for authentication, as its design is pretty different from my requirements. I do want role-based authentication, so I ultimately wrote custom User and Role classes as code-first Entity classes and used this tutorial to set up a custom MembershipProvider and RoleProvider.
Everything works fine at the moment, but as I'm building the multi-tenancy functionality it's getting messier. Based on this example, I am using a custom extension of Controller which keeps track of which tenant is using this session, and all my controllers extend this class instead of the base Controller class.
All tenants are using the same database. Each entity has a Tenant property that identifies who it belongs to.
So, here's the problem:
Usernames do not need to be globally unique. Only the combination of username and tenant must be unique. Thus, ValidateUser needs to know the username, password, and tenant. Since my custom MembershipProvider is not a Controller, it doesn't know which tenant is using the session, and the ValidateUser method only accepts username and password so I can't pass it that information.
Furthermore, pretty much everything MembershipProvider does besides ValidateUser is already implemented in a UserRepository class, which that tutorial told me to make. I'm rather fond of the Repository pattern, and it's way more convenient than adhering to MembershipProvider's interface, but now there's a massive conflict of interest between UserRepository and MembershipProvider.
So, my question:
Do I need to use MembershipProvider, or even Membership, at all?
It seems like everything MembershipProvider does would be performed more conveniently by my repository class. At this point all I'd have to do is write a new Authorize attribute that doesn't rely on Membership, and everything should work without any MembershipProvider at all, right? If I don't drop Membership I'm forced to completely mutilate my MembershipProvider implementation to the point that it barely resembles the original interface anyway.
...Either that or Membership does a ton of things I'm unaware of and removing it is blatant stupidity. That is also a distinct possibility.
No, you don't need to use Membership, but consider for a moment exactly what Membership is. Membership does not involve your users names, or addresses, or other information. Membership is strictly related to the login account of the system. It only handles details with creating, validating, updating, or deleting the information needed to login. That's it.
Likewise, the Role system is only assigning a role name to the user.
Ultimately, Membership and Roles are just implementations of the IPrincipal interface. While FormsAuthentication is an implementation of the IIdentity interface. These work together so that you can utlize the built-in ASP.NET Authorization and Authentication system.
Membership actually does have the concept of multiple tennants. This functionality is accomplished via the "ApplicationNane" field of the aspnet_users table (also settable in the Membership class itself)
From the documentation on the Membership class:
The ApplicationName is used to identify users specific to an application. That is, the same user name can exist in the database for multiple ASP.NET applications that specify a different ApplicationName. This enables multiple applications to use the same database to store user information without running into duplicate user name conflicts. Alternatively, multiple ASP.NET applications can use the same user database by specifying the same ApplicationName. The ApplicationName can be set programmatically or declaratively in the configuration for the Web application.
Now, this is designed to typically be set in the Web.Config and stay the same for the life of the app, but I see no reason why you can't use it to specify which tennant you want.
The only issue here is that Membership.ApplicationName is static, which means it's shared by all threads running in the App Pool. However, if you use some kind of lock around accessing it, then this shouldn't be a huge issue (though it could affect scalability at some level).
This would basically allow you to use the standard, out of the box membership provider without any changes. You just have ot make sure to guard the access calls.
You don't have to use the membership provider at all. Its simply provided as a quick and consistent way to get up and running. Some choose it because it supports multiple databases (universal membership providers include azure as well as sql ce, express, and full) but for others trying to map it to your applications rules can be more difficult than the <5 lines of code it takes to authenticate and issue your own forms auth ticket.
With that said I'm assuming you are using forms authentication. You can simply issue the ticket yourself. I would still program against an interface for this which the default MVC template should have, so simply add in a new tenant id.
With that said, I'd consider having unique names. It ensures you don't 'forget' to do an additional tenant check somewhere else in the app and tenant1\userBip and tenant2\userBip surprisingly end up stomping on each others record at some point.
True, testing should uncover this - if testing is complete : )
I am looking to see what is the best way to implement asp.net membership in an MVC 3 project. One thing to note is that I have a separate users table and would like to still use this. So can I link my users table to the asp.net memberships table?
Cheers,
Noel.
You can create an additional field (unique identified type) on your custom table and link it to the membership users table.
create new user, if succeed then get id for the newly created user and insert it to your custom table.
MembershipUser mUser= Membership.GetUser(username);
Guid myId = (Guid)mUser.ProviderUserKey;
...Insert my/id to your custom table.
Description
You can implement your own MembershipProvider. Then you have full control about
how authentification works and wich database / tables are relevant.
I think you dont need the default asp.net membership database.
More Information
Create a Custom Membership Provider?
I have an existing project that i'm working on that uses .net membership. We want to expand the project to allow anonymous users but we seem to have hit a snag as we use the UserId of the aspnet_Users table as a foreign key in many of our database tables.
The following call returns null as there is no record in the aspnet_Membership table for anonymous users
Membership.Provider.GetUser(Request.AnonymousID, false);
Is there any way to get the UserId of an anonymous user through the standard API's? or will I have to write an extension that can do it?
As far as I know it is about access. If your web site has modules or pages that do not need access. You need to create a user first in the aspnet users table. It could be that this anonymous user is not created correctly leading to the null value.
Additionally if you want to track these anonymous users, you have to set allowanonymous to true in your profile provider configuration.
See this article for more help
http://www.odetocode.com/Articles/440.aspx