Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to create a Logon System with ASP.NET MVC but not use the MembershipProvider?

I have an existing database with a users table, and we are planning to take the database and use it for a new system built in ASP.NET MVC. However, what I am uncertain about is whether or not I am able to create a login system that doesn't use the built in account controller or a regular membership provider so that we can still use the existing table structure.

So my question is, would this be possible? Or even particularly difficult to do if it is?

What is the most widely accepted way of doing things and the simplest?

like image 755
LiamGu Avatar asked Sep 17 '09 11:09

LiamGu


People also ask

How does MVC handle authentication and authorization?

For form authentication the user needs to provide his credentials through a form. Windows Authentication is used in conjunction with IIS authentication. The Authentication is performed by IIS in one of three ways such as basic, digest, or Integrated Windows Authentication.

What is membership provider?

The ASP.NET membership provider is a feature that enables ASP.NET developers to create Web sites that allow users to create unique user name and password combinations. With this facility, any user can establish an account with the site, and sign in for exclusive access to the site and its services.

How can I use ASP Net Membership in C#?

To create a user in our application by using ASP.NET Membership we need the following steps to complete this process. Step 1: Firstly, open visual studio, then go to File Menu and click New -> Web Site. Step 2: After open the new empty website and add a new item Login. aspx in Registration inside Solution Explorer.


2 Answers

I had this exact same requirement. I had my own user and role schema and did not want to migrate to the asp.net membership schema but I did want to use the ASP.NET MVC action filters for checking authorization and roles. I had to do a fair amount of digging to find out exactly what needed to be done, but in the end it was relatively easy. I'll save you the trouble and tell you what I did.

1) I created a class that derived from System.Web.Security.MembershipProvider. MembershipProvider has a ton of abstract methods for all sorts of authentication-related functions like forgot password, change password, create new user, etc. All I wanted was the ability to authenticate against my own schema. So my class contained mainly empty overrides. I just overrode ValidateUser:

public override bool ValidateUser(string username, string password) {     if (string.IsNullOrWhiteSpace(username) ||         string.IsNullOrWhiteSpace(password))       return false;      string hash = EncryptPassword(password);     User user = _repository.GetByUserName(username);     if (user == null) return false;      return user.Password == hash; } 

2) I created a class that derived from System.Web.Security.RoleProvider. Again, I just had empty implementations for all the fluff I did not need like creating and changing roles. I just overrode two methods:

public override string[] GetRolesForUser(string username) {     User user = _repository.GetByUserName(username);     string[] roles = new string[user.Role.Rights.Count + 1];     roles[0] = user.Role.Description;     int idx = 0;     foreach (Right right in user.Role.Rights)         roles[++idx] = right.Description;     return roles; }  public override bool IsUserInRole(string username, string roleName) {     User user = _repository.GetByUserName(username);     if(user!=null)         return user.IsInRole(roleName);     else         return false; } 

3) Then I plugged these two classes into my web.config:

<membership defaultProvider="FirstlookMemberProvider" userIsOnlineTimeWindow="15">   <providers>     <clear/>     <add name="FirstlookMemberProvider" type="FirstlookAdmin.DomainEntities.FirstlookMemberProvider, FirstlookAdmin" />   </providers> </membership> <roleManager defaultProvider="FirstlookRoleProvider" enabled="true" cacheRolesInCookie="true">   <providers>     <clear/>     <add name="FirstlookRoleProvider" type="FirstlookAdmin.DomainEntities.FirstlookRoleProvider, FirstlookAdmin" />   </providers> </roleManager> 

That's it. The default authorization action filters will use these classes. You will still have to handle the login page sign in and sign off. Just use the standard forms authentication classes for this like you normally would.

like image 104
Matt Wrock Avatar answered Oct 09 '22 01:10

Matt Wrock


Whenever anyone tells you that something security-related is "easy," they are nearly always wrong. There are a lot of subtleties in security which non-experts tend to miss.

In particular, any form of authentication which does not explicitly deal with caching is inherently broken. When an action result is cached, this happens within ASP.NET, not necessarily within the ASP.NET MVC stack. If you examine the source code for AuthorizeAttribute, you will see that it contains some slightly tricky but effective code to ensure that it always runs, even when the action result is cached.

The best way, by far, to customize ASP.NET MVC authentication is to write a custom ASP.NET membership provider. I won't claim that this is foolproof, but there are fewer ways to get in trouble with a broken security implementation in this route then with other methods. A substantial advantage of this technique is that you can substitute a different authorization system at almost any time, with no code changes.

If you must implement a custom MVC attribute, then you should subtype AuthorizeAttribute and override AuthorizeCore, taking careful note of the comments in the source code regarding thread safety.

like image 42
Craig Stuntz Avatar answered Oct 09 '22 00:10

Craig Stuntz