Multi User App with MVC3, ASP.NET Membership - User Authentication/ Data Separation -


i'm building simple multi-user (multi-tenant?) app asp.net mvc3 , ef4, 1 database, 1 code base, users access app using same url. once user logged in should have access data, i'm using default asp.net membership provider , have added ‘userid’ guid field on each of data tables. don't want user have access user b’s data have been adding following every action on controllers.

public actionresult editstatus(int id)     {         if (!request.isauthenticated)             return redirecttoaction("index", "home");          var status = sservice.getstatusbyid(id);          // check if logged in user has access status         if (status.userid != getuserid())             return redirecttoaction("index", "home");     .     .     .     }      private guid getuserid()     {         if (membership.getuser() != null)         {             membershipuser member = membership.getuser();             guid id = new guid(member.provideruserkey.tostring());             return id;         }         return guid.empty;     } 

this repetition feeling wrong , there must more elegant way of ensuring users can't access each other's data – missing?

what missing?

a custom model binder:

public class statusmodelbinder : defaultmodelbinder {     public override object bindmodel(controllercontext controllercontext, modelbindingcontext bindingcontext)     {         // fetch id routedata         var id = controllercontext.routedata.values["id"] string;          // todo: use constructor injection pass service here         var status = sservice.getstatusbyid(id);          // compare whether id passed in request belongs          // logged in user         if (status.userid != getuserid())         {             throw new httpexception(403, "forbidden");         }         return status;     }      private guid getuserid()     {         if (membership.getuser() != null)         {             membershipuser member = membership.getuser();             guid id = new guid(member.provideruserkey.tostring());             return id;         }         return guid.empty;     } } 

and register model binder in application_start:

// use constructor injection pass repository model binder modelbinders.binders.add(typeof(status), new statusmodelbinder()); 

and finally

// authorize attribute ensures user authenticated.  // if want redirect /home/index in original // example if user not authenticated write custom // authorize attribute , job there [authorize] public actionresult editstatus(status status) {     // if got far means user has access resource     // todo: status , return view     ... } 

conclusion: we've put controller on diet way controllers should :-)


Comments

Popular posts from this blog

c# - How to set Z index when using WPF DrawingContext? -

razor - Is this a bug in WebMatrix PageData? -

visual c++ - Using relative values in array sorting ( asm ) -