Modifying ASP.NET Membership Schema - c#

So I'm using Forms Authentication on my site, and I've set up all the tables and stored procedures in SQL Server. The only thing is, I really don't think I need all these tables, and I'm not a big fan of the table names either.
For instance, I'm using the authentication for employees, so it would be nice to change the table name from "aspnet_Users" to "Employees". And I don't really need the Personalization tables. But I don't know if that would break anything.
Is it possible to modify/delete tables and stored procedures without messing everything up?

Steven, I take it you ran the aspnet_regsql.exe command line tool to add these database objects? Alternatively, you can add just the necessary tables/views/stored procedures for different parts of Membership by running the applicable SQL scripts, which you'll find in the %WINDIR%\Microsoft.Net\Framework\version folder (where version is the .NET version you are using, like v4.0.30319).
There you'll find files named InstallCommon.sql, InstallMembership.sql, InstallRoles.sql, InstallProfile.sql, InstallSqlState.sql, and so on. You'll need to run InstallCommon.sql and then just those other files you need. So if you need just Membership and Roles, you'd run InstallCommon.sql, InstallMembership.sql, and InstallRoles.sql. In this way your database would not include the tables/views/sprocs for profile, SQL state, and so on.
All that being said, I'd just leave in all of the database objects that ASP.NET added. It's probably more work than it's worth to add just the subset of interest and, who knows, you may need to implement profile or Health Monitoring later so why not have these other database objects in place and
ready to go.
And to answer your first question - No, there is no way to change the table name from aspnet_Users to Employees. However, it's not uncommon to create your own table (perhaps called Employees) that stores information about an employee. This table, then, would have a foreign key back to aspnet_Users that links an employee to a particular login account. See Storing Additional User Information for a look at how this can be accomplished.
Happy Programming!

Why not write a simple SqlMembershipProvider?
Edit: No, the default providers expect that schema. I would not recommend modifying it.

Have you considered just leaving the authentication stuff in it's own database?

You can change all references to aspnet_Users to Employees in the .sql scripts mentioned by Scott Mitchell but it isn't recommended. The Membership / Roles API uses stored procs. So if you don't change storedProc names you will be fine.
The issues might be if any future changes to membership / Roles providers and/or API.
Also say in future you need to give access to some users who are not the Employees, the renaming will lose its meaning.

Related

How do I synchronise the usernames from the default Membership Provider in ASP.NET, to my other database?

I'm really unsure about how to handle this.
What I think I need is to have the usernames people register with ( through the default Provider ) to be copied to the UserName column of my other database, which has a junction table for a many:many relationship between User and Badge.
I've tried using SQL to copy the table over, but that's not really working out, as I don't know what table exactly I'm supposed to copy..
Any help would be dearly appreciated, and if more info is needed, please ask!
I'm not sure what your circumstances are, but as you're saying that the users are registered through the default Provider, I guess that the tables may have been generated by the aspnet_regiis tool?
If so, the users are stored in a table called aspnet_Users and the user names are in the column UserName.
I may have misinterpreted your question, but is this what you were asking for?
This really depends on your requirements which aren't really clear. If you always want your data to be up to date in your other database then syncing by copying the whole table isn't the way to go.
If you don't mind that you get the usernames on a later moment in time then syncing is the way to go. For example if you use the other database for BI purposes only, then a simple job for example in the night will do fine. Like Christoffer said you will need the UserName column from the aspnet_User table for this.
Now if you want it to be always up to date then you have two options:
Hacky and not advised by me. Extend the stored procs which are called by the default membership provider by also updating the other database. For example you could alter dbo.aspnet_Membership_CreateUser. Check your database for all aspnet membership stored procedures.
Implement your own membership provider which calls your own stored procedures or the default stored procedures + additional queries for updating the other database. This one is the most work and would be my choice. For examples of custom implementations see this one and this one.
Both options will need you to get familiar with the asp.net membership infrastructure.

changing ASP.NET core table names

Is there a good way to change the aspnet_Users, aspnet_Membership, aspnet_Applications and other table names which are generated by the ASPNET SQL Server registration tool -
http://msdn.microsoft.com/en-us/library/ms229862%28VS.80%29.aspx#3
and change the reference to them in web.config or machine.config without breaking the default login, profiles and roles functionality that is provided by those tables?
If you really want that much control (btw, the OOB stuff works great), you might want to consider implementing your own Membership Provider
If you look in C:\windows\Microsoft.NET\Framework\v2.0.50727\
You can see the installation scripts used to create these tables/procs etc...
They are InstallMembership.sql etc..
You could back these up, change them then run aspnet_regsql.exe
I may be wrong but IIRC the standard implementation does not reference the tables directly. All DB calls go though stored procedures created by the same script that creates the tables. Just change the code inside the procedures. Should be easier (but not that elegant) than implementing a membership provider from scratch

Using the ASP.NET membership provider database with your own database?

We are developing an ASP.NET MVC Application that currently uses it's own database ApplicationData for the domain models and another one Membership for the user management / membership provider.
We do access restrictions using data-annotations in our controllers.
[Authorize(Roles = "administrators, managers")]
This worked great for simple use cases.
As we are scaling our application our customer wants to restrict specific users to access specific areas of our ApplicationData database.
Each of our products contains a foreign key referring to the region the product was assembled in.
A user story would be:
Users in the role NewYorkManagers should only be able to edit / see products that are assembled in New York.
We created a placeholder table UserRightsRegions that contains the UserId and the RegionId.
How can I link both the ApplicationData and the Membership databases in order to work properly / having cross-database-key-references? (Is something like this even possible?)
All help is more than appreciated!
In my opinion, you should be able to integrate your database with the standard aspnet_db reliably, but I would advise against duplicating or replacing the aspnet_users table.
That is the focal point of all the providers that use the aspnet_db schema, including custom providers that may augment but do not implement custom replacement.
To maximize reuse of strong tested infrastructure code in the provider stack/API it is best to go with that flow.
You will want to be very attentive to any modified membership core functions and ensure that the way your new constraints behave in an expected fashion in each case.
The facet of the membership story that I have found needs the most attention is deleting a user, and a simple modification/addition to the delete user sproc can manage this capably.
It sounds like you might need to create your own customized Membership Provider. You can probably (not positive here) extend the existing one so you don't have to completely reinvent it. Here is a video from ASP.net that describes how to do that. Google "asp.net membership provider" for tons more.
You can try rolling your own membership or just extend is like Dave suggests.
Create your own [Users] Table which can be populated based off the aspnet_Membership table. So therefore you could have more control over it.
You could also just implement a more involved Profiles system. The .NET team has improved the way profiles are stored now, so instead of "blobicizing" them, you can set them up to be stored in an actual table now [thank god].
Table Profile Provider
If you find the right articles, it's really easy to extend the membership provider to allow for extra functionality. I've moved my users table to my main SQL server table and have written my own role manager that gets values from a separate table. What it sounds like you need to do is to set up a table in your users DB with the location of each user, then create a method on the user object something like "GetLocation()" that returns the user's location from the DB, you could then user that to filter your data from your main DB. Here's a few articles I had kicking aroundin my bookmarks, see if they help, if you have a look on the main ASP.NET site or google for membership provider extending articles, there are plenty around.
http://msdn.microsoft.com/en-us/library/ms998347.aspx
https://web.archive.org/web/20211020202857/http://www.4guysfromrolla.com/articles/120705-1.aspx
http://msdn.microsoft.com/en-us/library/aa479048.aspx
As the others have pointed out there are many good resources available that can help you with creating your custom provider using the existing database.
It looks like you are headed in the right direction with mapping tables. I think the one piece you are missing is Distributed Queries. This link is specific to Sql Server 2008. There is a link there to the documentation for Sql Server 2005 if that is what you are using.

Membership Provider users in different tables

I have an existing database with users and administrators in different tables.
I am rewriting an existing website in ASP.net and need to decide - should I merge the two tables into one users table and just have one provider, OR leave the tables separated and have two different providers.
Administrators, they need the ability to create, edit and delete users. I am thinking that the membership/profile provider way of editing users (i.e.
System.Web.Profile.ProfileBase pro = System.Web.Profile.ProfileBase.Create("User1");
pro.Initialize("User1", true);
txtEmail.Text = pro["SecondaryEmail"].ToString();
is the best way to edit users because the provider handles it? You cannot use this if you have two separate providers? (because they are both looking at different tables).
Or should I make a whole lot of methods to edit the users for the administrators?
UPDATE:
Making a custom membership provider look at both tables is fine, but then what about the profile provider? The profile provider GetPropertyValues and SetPropertyValues would be going on the same set of properties for users and admins.
Probably you should merge the two tables into one and use a RoleProvider to make the distinction between administrators and "normal" users.
Alternatively, you could implement your own, custom membership provider, which would use both tables.
Mike,
My advice is to go ahead and merge your two 'membership' tables and segregate admins from non with roles.
(This is, I know a duplicate of the previous answer but I feel the need to explain..)
In this way, unless you have some compelling reason to implement custom providers, you will be able to leverage the stock providers and database structure to provide a robust user management story for your website without writing any code (that you have to test and maintain).
.2 pesos....

Why is the asp.NET profile designed in such a horrible way?

In the current project I'm working on, we are using the asp.NET profile to store information about users, such as their involvment in a mailing list.
Now, in order to get a list of all the users in the mailing list, I cannot simply do a database query, as the asp.NET profile table is, simply put, awful.
For those who do not know, the profile table has two main columns, the 'keys' column, and 'values' column, and they are organised as so:
Keys:
Key1:dataType:startIndex:endIndex:key2:dataType . . etc.
Values:
value1value2value3...
This is pretty much impossible to query using SQL, so the only option to find users that have a specific property is to load up a list of ALL the users and loop through it.
In a site with over 150k members, this is understandably very slow!
Are there specific reasons why the Profile was designed like this, or is it just a terrible way of doing dynamically-generated data?
I agree that it's a pretty bad way to store profile data, but I suspect the use case was just to get the profile data for a user with a single query but in such a way that it can be extended to handle any number of different profile properties. If you don't like it, you can always write your own, custom profile provider that separates each value out into its own column. Having implemented various membership and role providers, I don't think that this would be too complicated a task. The number of methods doesn't look too large.
The whole point of the Provider model is that it abstracts away the data source. The idea is that, as a developer, you don't need to know how the data is stored or in what format - you just have a common set of methods for accessing it. This means you can swap providers without changing a single line of code. It also means that you specifically do not try and access data direct from the data source (eg. going straight to the database) by bypassing the provider methods - that defeats the whole point.
The default ASP.NET profile provider is actually very powerful, as it can not only store simple value types (strings, ints etc.) but it can also store complex objects and entire collections in a single field. Try doing that in a relational database! However, the downside of this generic-ism is that it comes at a cost of efficiency. Which is why, if you have a specific need, then you are supposed to implement your own provider. For example, see SearchableSqlProfileProvider - The Searchable SQL Profile Provider.
Of course, your third option is to simple not use the profile provider - nobody is forcing you to! You could implement your own classes/database entirely, as you would have had to do in other frameworks.
I have implemented various custom providers (membership/Sitemap/Roles etc) and havent really looked at the ASP.NET Profile Provider after seeing that kind of thing (Name/Value pairs or XML data). I am not sure, but I think the Profile is primary created for User Preferences/Settings where the settings are only required for a specific user, I dont think the Profile is meant for User "Data" that can be queried?
Note: This is an assumtion based on what I think I know, please comment on this otherwise.

Categories

Resources