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
Related
I am building an app with Role based Security. I have built my Record Types (Projects, Accounts, HistoryLog, Financial, Customer, etc) in Cloudkit Dashboard, and I have created Security Roles as well. I have roles named: Executive and DeptManager. I have assigned to the Record Types the appropriate access by Role. I have also assigned to the user in the special Record Type "Users" the role of either Executive or DeptManager.
I have successfully accessed and manipulated data in the Record Types. Now I am implementing Role based viewing in the App. So on the first view there is a log in "like" feature, so after i discover the user, I want to display the Roles of that user in a PickerView for them to select. Once they select a role I will them take them to the appropriate view. For example I may have the role of both DeptManager and Executive. If today I select DeptManager, I will be taken to a view that allows me to enters Production Metrics. If another day I select Executive, I will see performance metrics for all the departments that report to me.
Here is an image from CloudKit Dashboard showing the info I'm trying to retrieve. Thanks in advance for any advice.
Currently it is not possible to get the roles a user is in. At the moment the information that is returned from the discoverUserInfoWithUserRecordID is very limited. I also hope it will be extended soon. Currently you only get a userRecordID, first name and last name. If you do want such functionality, then the only solution is creating a shadow registration which you could query. You then would have a challenge keeping these 2 in sync. That has to be done manually.
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 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 just started an MVC 3 project using Forms Authentication. I have a web project (mvc project), and a data project. The data project handles all database interactions.
I need to store the current user id in my database on every insert and update.
Here's what I am doing right now. I feel like this has to be a common scenario. Can anyone shed some light on a better way to do this?
On LogIn or Register, I grab my current user record (by username) from the database and store the user id in session.
When saving a record within my data project, I refer to the httpcontext (if it exists) and use the user id that is stored in session.
This works for all but one scenario. It fails when a user has a valid cookie saved, and so they are allowed to bypass the login/register action. When this happens, obviuosly, my session variable for userId is null. My next step would be to create a base controller and imlement OnAuthorizeStarting to check if my Session variable is null or not. This feels kludgy, and I'm hoping there is a better way.
I do not want to have to pass the user Id to the data project as a parameter on every Save call.
Anyone have some brilliance? thanks.
The UserID is available via membership. So, something like this:
Membership.GetUser(HttpContext.User.Current.UserName).ProviderUserKey
The IPrincipal (HttpContext.user.Current) is created when the user is authenticated against the forms authentication cookie. You just pull up the user id from the Membership whenever you need it.
If you don't like accessing Membership every time then you can always create a static helper class that wraps your UserID session call. If it's null, it goes out to the membership provider, gets it, then stores it in the session.. on later accesses it just retrieves the session variable.
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?