I am starting a new ASP.Net MVC 3 app and I'm hoping to be able to use the built in Membership provider.
The issue I have is that my application can be used by various organizations and it is important that the information shown is only applicable to the organization the user is working for.
The no brainer approach would be to insist all users use their email addresses as their username so everyone is unique and can be associated with their respective organizations. The problem is, some users don't have email addresses so there is no reliable way of ensuring unique names and I don't want people to know the Usernames already in use by different organizations. (USernames should only be unique to the Organization, not the entire app)
Ideally, I would want the User to enter their organization name in one field, then their username in another (and then the password!)
So we could have Jane login from one organization.....
Organization Company1
Username Jane
Password ********
and then someone else also called Jane could login from a different organization..
Organization Company2
Username Jane
Password ********
So my question is, what is the best way of modifying the Membership system to allow for this extra field?
I'd go about writing a custom MembershipProvider to suite the requirement.
http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx
The provider pattern used by membership is designed so that you can extend it. You can inherit from the default provider and from the default membership use class to add the fields you need. This saves you from having to write a provider from scratch. As #mare pointed out, there are potential pitfalls though.
I would overcome these by perhaps having a login form that prompts for organisation, username & password, but behind the scenes combine the org & username & use that as the internal username.
The built-in (default ASP.NET) membership provider does not provide a concept of an Organization/Company/Firm or Department. You will have create your own tables in the database for those with a foreign key to the aspnet_users table to be able to store that additional information (I wouldn't go changing the default aspnet_users table because it might make it incompatible with the current default provider or future ones). You will then need to use the default provider for the default functionality and create a Service class to support the extended functionality. I know, I have done it. It gets complicated and dirty, takes time but it's completely doable.
Most likely you will end up creating your own provider and that starts with the requirement to support Users in Companies. In case you thought that changing the default provider to support that wouldn't be necessary. The requirement about uniqueness within the company is another one you will have to implement.
I think there is a built in option in the membership. look into the APPLICATION field in table my_aspnet_users.
reference here:
http://msdn.microsoft.com/en-us/library/system.web.security.membership.applicationname.aspx
Related
The customers (clients) of an ASP.NET webapplication are companies and each company may have many users that have access to the site.
So, for instance CompanyA subscribes to the site to consume the site's services. Immediately a superuser of that company is created. Then, this supersuser has the permission to create more users of CompanyA that have access to the site.
So, in general, each user is identified by a CompanyName and a UserName.
Typical ASP.NET forms authentication provides automatic login and register functionality but only with Username and Password fields.
Does the .NET framework provides a way to include a CompanyName and CompanyPassword fields in the Login and Register controls?
A company and the initial superuser may also be registered in the system by the Site's administrator.
Actually what I would like is to include a CompanyName field in the provided .NET Login control, and not only Username and Password.
Is there a .NET framework way to do this, or do I have to custom-code it? In the latter case, which is the best practice?
Your scenario should NOT require a company name at all. So long as the username is a unique column, you should be able to lookup to which company does the user belong to. All you need is a user_company table which will link usernames to company ids. Once the super user is created, you know the company he belongs to and when he creates a user, you also know which company that user will belong to. On the login page you still only need to ask for username and password only; that's of course, if you don't want to allow users from different companies with the same username, which I think is reasonable and a good trade off for simplicity.
You can use any pre-existing or planned authentication scheme you want with ASP.Net Forms authentication.
See this (overly simplified) example from MSDN where you can even hard code the auth scheme if you so choose - not that you should, but it gives you the overall idea.
ASP.net Membership is provided to you by Microsoft if you want to use it (you don't have to). It has all the scaffolding you need if you use it (including the database you mention) and is used by Forms Authentication by default (not exclusively).
I have these roles:Admin, Doctor and Patient. But login information is stored in different table. Admin's username and password are stored in User_TABle(They are two items). Patient's Login information is stored in Patient_TABLE: PatientID, Year and DocumentID(They are three items). I want to use SQLRoleProvider and SQLProfileProvider. How can I design different login page with loginView?
Sincerely yours
I think a better setup would be this:
Use the standard MembershipProvider shipped with ASP.NET to use in conjunction with RoleProvider. Once this is setup and you have the roles you can store personal information for each either by:
Using ProfileProvider (not a bad method but requires a bit of work as you have polymorphic data (you would store it using XML in text field of the provider or write your own custom profile provider)
OR
Add a table similar to your schema but with a foreign key to the aspnet_Users PK. In code then you could do Roles.IsUserInRole("Whatever") and change the loginView appropriately. It would also mean you could just drag and drop the remaining LoginControl etc and have it just work with the standard membership provider
SqlRoleProvider, SqlProfileProvider and SqlMembershipProvider come with default Aspnetdb.
To create the database used by these providers, run the aspnet_regsql.exe executable found in the C:\WINDOWS\Microsoft.NET\Framework\ versionNumber folder. Otherwise, you have to create CustomRoleProvider, CustomProfileProvider and CustomMembershipProvider.
http://msdn.microsoft.com/en-us/library/system.web.security.sqlroleprovider.aspx
I'm looking to implement a membership system where there a several different levels of membership.
Something along the lines of:
Administrators
Bob
Organisations
Organisation members
Fred
Owners
Supporting users
Wilma
I'd like the Administrator to be able to add an organisation and from then on the person assigned to as the admin/owner of the organisation will be delegated the task of setting up membership/roles etc only within that sub-group (of course administrator would be able to override/change this as well)
So in this example Bob could add an organisation with fred as its administrator and fred could assign a new user say 'Thelma' as a member of his organisation.
From what I've seen this doesnt really seem to fit into the model of membership/roles that asp.net uses unless I'm thinking about it in the wrong way.
Is there a way to make this work with the inbuilt providers or would the best approach to be to ditch them and implement something custom?
You can keep the inbuilt providers and solve it with a relation between the organization and the membershipUser so you can say that a membershipUser "owns" an organization.
After that, you have a membershipUser Foreign Key on your organization that you can use to query the organizations that a user owns.
Shure you can implement a custom provider but it could take time to code and debug. I used the aproach I mention years ago and saved me from implementing the custom provider.
In a website, I need to integrate membership and authentication. So I want to use the functionality of ASP.NET Membership, but I have other custom stuff, that a "user" has to do.
So I am sitting here with my pencil and paper, drawing lines for my domain model... And how can I best utilize the ASP.Net membership, but extend it to fill my needs?
Should I create a class that inherits from a MembershipUser and extend it with my own properties and methods (and save this in a seperate table). Or should I let the MembershipUser be a property on my custom User/Client object?
What would be a good solid way to do this?
I've thought about it and there are 2 ways that seem appropriate (of course there are more ways to make it work).
Custom Membership Provider
You change the membership provider to use your own and use your User object to store all the information.
The problem with this one is that it involves a lot of re-implementation of things that are already well handled by Asp.Net. The good thing is that you have a single User object with all the details.
Link from a Membership User to your User
With this method, you would use the original Membership provider to handle the user name and password, but you link your own User object with this one with something like the user name by using a service for example.
It's really easy to set up, you just need to create a service that would be used like this:
string userName = "Jon Skeet";
User user = new UserManagementServices().GetUserByUserName(userName);
I ended up writing my own membership-provider, and have implemented that in 3 separate solutions now. It is extremely simple and much, much more elegant than linking a user to a membershipUser (which I have also tried).
Read this...:
Create Custom Membership Provider for ASP.NET Website Security
And if you want to learn more, watch this video (with sourcecode).
I've extended MembershipUser and created my own version of the SqlMembershipProvider to map to my existing domain, and its working well, in production now.
MembershipUser is essentially a view over my User table. My extended MembershipUser class includes profile/account-style properties instead of using the default SqlProfileProvider system, which is a bit fragile.
I wasn't able to use the existing membership tables or sprocs, but wrote my own. For example, the SqlMembershipProvider uses a GUID as an opaque key, but the production system uses a plain old int. All of the dates are UTC, etc. too.
All of the extra User functionality is accessed via the User domain not via Membership methods.
HTH.
I'm currently working through the Microsoft ASP.NET 2.0 Membership API Extended article from CoDe Magazine which explains how to extend the membership API by writing a wrapper around the existing classes. Main benefit is that you can keep all the out of the box functionality and not have to rewrite your own as you would when implementing a custom provider. Source code is provided.
Encouraged by SO, I'm trying to write an ASP.NET site that uses OpenID for user authentication. It's a regular WinForms site (not MVC.NET), using the DotNetOpenId library for authentication.
Is it safe for me to permit/deny administrative functions on the site by simply comparing the current session's "ClaimedID" (as returned in the OpenIdLogin_LoggedIn event, as member DotNetOpenId.RelyingParty,OpenIdEventArgs.Response.ClaimedIdentifier) to a known administrator's OpenID (i.e. mine)?
If so, is it safe for this ID to be visible (e.g. in open source code), or should it be "hidden" in a configuration file or a database row? (I know it's better design to make it configurable, my question is just about safety.)
My solution is to follow the same idea of the Roles table. After you've authenticated the user, look up that user's roles. If the user has role "Administrator" in the UserRoles table, then they can do whatever the Administrator can do.
I don't broadcast open ID's in my app. They're stored in the table. On every action result, I'm hitting the Users table, since I have also modified mine to store various user state information. With the exception of the home page, there is going to be some user information that I need from that table. I'm using LINQ, so I include the .LoadWith() to load the User with his list of roles when it serializes.
Jarrett makes some good comments about using database tables.
Just to answer another one of your questions, no, it's not a confidentiality thing to put your OpenID in your code generally. If setting up roles seems overkill for your site, a simple equality check against your ClaimedIdentifier is just perfect.