Custom fields in ASP.Net Login/Register? - asp.net

I have to edit the Login/Registration that ASP provides to include a custom dropdown ("BranchID") menu that saves to the database so each user has its own Branch. I am using ASP Membership system, and of course it saves to the ASPNETMDF database it creates. Googling has net me some results but I am quite confused. I know there are "User Profiles", and I I can save this Profile data, but what I am not quite sure is if its a temporary measure or if it does record to the database.
I could make my own custom membership system, use the built it and adapt it or use the user profiles. What is the best course of action? I'd vastly prefer to adapt/edit the built in Membership system and add the data I require to it but I still don't haven't a clear answer to what I should do or what's best.

You have two choices:
Create a CustomMembershipProvider , and if you need to a CustomRoleProvider, you can do this by implementing .NET's MembershipProvider. Sample: http://www.codeproject.com/Articles/165159/Custom-Membership-Providers
Create a separate table that stores additional user information, i.e., "BranchID", and add a one-to-one relationship between your table and .NET's Membership
It's really up to you which one you choose.

MembershipProvider is pretty easy to extend. Assuming the branch is something they have to select to authenticate? You should be able to extend authenticate to do something like:
public class MyCustomMembershipProvider : MembershipProvider
{
/*
....
*/
public bool ValidateUser(string username, string password, string branch)
{
return (::ValidateUser(username, password) && MyCustomRoutine(username, branch));
}
}

Related

ASP.NET Identity - Steps for custom authentication

Envrionment: Visual Studio 2013, ASP.NET MVC 5
On the new MVC5-based project I will be working on, I need to use a custom database that stores usernames, passwords, and roles in its own way. I am searching the Internet to look for an example for custom authentication. Looks like the old-style "membership provider" classes have been replaced by the new "Identity" mechanism.
However, finding a good step-by-step example has proven to be futile. There are a few links (published this year) that talk about implementing custom IPrincipal and DbContext classes. Some other links talk about implementing IUserLoginStore and IUserPasswordStore. A few others hinted on implementing IUser, IUserStore interfaces.
Maybe the last option is what is needed. Can someone please guide me with the steps or point me to any link that has a simple example? Something like:
Implement MyUser based on IUser
Implement MyUserStore based on IUserStore
Modify web.config to use MyUserStore
Remove DefaultConnection from web.config as it is not required
Regards.
First, stop. Stop thinking about "custom authentication". You don't need custom authentication, you just need custom storage of authentication data.
ASP.NET Identity has abstracted out the storage mechanism of authentication from the process of authentication. There are several interfaces that follow the pattern IxxxStore.. Such as IUserStore, IRoleStore, etc...
You can find more information about this here, along with custom implementations for various databases which you can probably convert to your own needs.
http://odetocode.com/blogs/scott/archive/2014/01/20/implementing-asp-net-identity.aspx
As an example, here is a RavenDB implementation that uses all the various interfaces in a single class.
https://github.com/tugberkugurlu/AspNet.Identity.RavenDB/blob/master/src/AspNet.Identity.RavenDB/Stores/RavenUserStore.cs
However, all this assumes you really truly a need to store data totally differently. If you just need to store the data in different columns, then it may simply be as easy as overriding OnModelCreating in your IdentityContext and changing the names of the columns in use.
ad.1.
public class ApplicationUser :IUser
{
public string Id
{
get;
set;
}
public string UserName
{
get;
set;
}
}
ad.2.
public class MyStore : IUserStore<ApplicationUser>, IUserPasswordStore<ApplicationUser>, IUserSecurityStampStore<ApplicationUser>, IUserEmailStore<ApplicationUser>
{
... //implement all interfaces here
}
ad. 3.
Now you can create your applicationUserManagerService (you will need IdentityMessageService, and IDataProtectionProvider):
var applicationUserManagerService = new ApplicationUserManagerService(new MyStore(), emailService, dataProtectionProvider);
Try to use IoC and register your IUserStore (I did it this way - link below):
unityContainer.RegisterType<IUserStore<ApplicationUser>, MyStore>();
check also my answer here (i'm using int as UserId there):
AspIdentiy ApplicationUserManager is Static, how to extend so it participates in my IoC framework?

Which is the best? Roles based App or Table per Type?

I'm recently working on an application that requires 2 user types. Physicians and General Users. They share some attributes (for example Username, Password, FirstName, LastName, Gender, etc).
But Physicians also need some other attributes that General Users does not have it. Fore example Physicians may have Speciality and WorkingPlace. I found that I should use Table Per Type Inheritance (TPT) in Entity Framework. I created a abstract base class named People, also I created two subclass named (RegisteredUser and Phisycian) inherit from People abstract class.
I Also found that the default Membership Provider in ASP.NET is not suitable for my needs. So I developed a CustomMembershipProvider class that can now work with Table per Type inheritance in Entity Framework.
But I think that it can be very better that I use Roles instead of Table Per Type inheritance. So I want to change my application for using Roles. But the problem is that how can I handle different attributes for Phisycians and General Users? I need a solution that can handle multiple profile fields for multiple User roles. For example if a User is in Physician role, he should have Speciality and WorkingPlace attributes.
Can anyone help me?
How about using Simple Membership with Roles?
You can use Custom Attributes for the specific User Types (Physicians, GeneralUsers ) like so.
public class PhysicianProfile : ProfileBase
{
public string WorkingPlace {
get { return this["WorkingPlace"]; }
set { this["WorkingPlace"] = value; }
}
}

Switch to SQL membership provider from AD membership provider runtime

In my asp.net application admin functionality, I am trying to combine AD authentication and form authorization for creating the users, roles and Assign users to roles etc. I have configured MembershipADProvider and AspNetSqlMembershipProvider in my web.config with MembershipADProvider as the default one. After user logs in using AD authentication, I need to switch/assign my membership object to use AspNetSqlMembershipProvider in order to get all the users from membership object (from dbo.aspnet_Users table). How do I switch the provider during run time? I have tried different approaches after searching for this issue and none of that seem to work for me so far.
Here are couple of approaches I tried:
1. foreach (MembershipProvider mp in Membership.Providers)
{
if (mp.Name == "MembershipADProvider")
{
Membership.Providers.Remove(MembershipADProvider");
MembershipUserCollection users = Membership.GetAllUsers();
ddlUsers.DataSource = users;
ddlUsers.DataBind();
break;
}
}
Membership.Providers.Remove(MembershipADProvider"); - doesn't work as it's not supported..
Also, tried to clear the Membership.Providers and then add only the type of AspNetSqlMembershipProvider which are also not supported.
I can't set Membership.Provider with value from
Membership.Providers["AspNetSqlMembershipProvider"] as Membership.Provider is a read only property.
I tried to swtich the connection string between 2 providers, which didn't swtich the provider, as both are different types of providers..if both were sqlserver providers this would have worked I believe.
Please let me know if anybody has successfully implemented or if at all this is a plausible approach. Thank You!
You would pass an explicit provider to your code, rather than taking a dependency on Memebership directly (which just wraps the one flagged as default in the config). There is no need to swap them in and out at runtime, think how this would affect thread safety.
So rather than saying Membership.GetAllUsers(); you would do something like (I don't have a compiler to hand):
public UserSerivce : IUserService
{
private MembershipProvider provider;
public UserService(MembershipProvider provider)
{
this.provider = provider;
}
public IEnumerable<MembershipUser> GetUsers()
{
return provider.GetAllUsers();
}
public void DoSomethingElseUseful()
{
...
}
}
And then to use it for a particular provider:
var service = new UserService(Membership.Providers["mySqlMembershipProvider"]);
var users = service.GetUsers();
Or if using AD specific code:
var service = new UserService(Membership.Providers["myADMembershipProvider"]);
var users = service.GetUsers();
Using DI in this way also helps keep code testable.
If all you need a list of users in the aspnet_Users table, just connect to your database with System.Data.SqlClient objects and query the table. There is no reason (that you mentioned) you need to use a membership provider to get that data.
Having said that, your membership/authentication scheme sounds like it may have some design issues, perhaps best tackled in a different question, but I think it might be useful to you if you sought comment on what you are trying to accomplish overall with the multiple membership providers.
Edit: I found some potentially useful posts on using multiple membership providers. It looks like the general idea is to implement custom code handling the Login.Authenticate event on your Login control, and use Membership.Providers["ProviderName"].ValidateUser to attempt authentication with each provider.
http://www.stevideter.com/2008/03/20/using-two-membership-providers-for-aspnet-logins/
http://forums.asp.net/p/1112089/1714276.aspx

ASP.NET MVC, Account Model : How to make relations to it?

I've created a new MVC 3 Internet Application, and it comes with the Account model/controller, etc.
Those are stored in a MDF database.
I'd like to create new models for my application, and make relations from these to my account model.
I did not find anything about it, maybe I looked for the wrong thing... So I was wondering, is there anybody who could point me in the right direction about how to do so?
Thanks!
Ah there in lies a problem with using the built in providers and aspnet default db.. In that database there is a unique id for each row - you in theory CAN use that to link to your databasse - but realize this is completely separate. One alternative many people do is to use a Custom Membership Provider (for example custom sql membership provider)
There are tons of articles/blogs out there on that - for starters see:
http://blogs.syrinx.com/blogs/dotnet/archive/2007/12/14/a-simple-custom-sql-membership-provider-part-1.aspx
This enables you to keep everything in your own database and its fairly easy to implement.
I found this as well:
https://github.com/anderly/SimpleMembership.Mvc3
I guess it's another alternative.
The answer I was looking for is exactly this:
In your model, link to the Membership User like this:
public virtual Guid UserGuid { get; set; }
public virtual MembershipUser User
{
get
{
return Membership.GetUser(UserGuid);
}
}

Implementing Custom Membership Provider Membership User Issues

I am trying to implement a custom membership provider and want to change the GetUser method. The problem is that GetUser returns MembershipUser and I want to return MyMembershipUser which has two additional properties FirstName and LastName. I can create a new method in my membership provider which returns MyMembershipUser but then I think it won't make any sense.
How would I go about doing this?
That would defeat the purpose of the Membership classes. Do something like this if you need to access other properties:
var user = Membership.GetUser(userName, true) as MyMembershipUser;
Really you should have a separate Profile class that handles things that MembershipUser does not provide.
var profile = Profile.GetProfile(Membership.GetUser(userName, true));
You should go for Profile Provider.
check this link, you have either SqlStoredProcedureProfileProvider and SqlTableProfileProvider, this way you have ability to store Profile data “in the clear” in the database, letting you query the db whenever u want.
"you can implement whatever business logic you need in the stored procedures to map the Profile data to your own database schema and database logic."
If MembershipUser is the base class of MyMembershipUser then you can return instances of MyMembershipUser even though the return type of GetUser() is MembershipUser and then, if necessary, cast them back to MyMembershipUser (but do you really need to do that?)
BTW, this is an example of polymorphism.

Resources