0

I've been learning MVC and am looking at sessionless authentication (for reduced server strain/scaleability and also because AppFabric Cache is expensive on Azure Websites for hosting Session).

My user information is stored in SQL and each user has a Department, Rank, Roles and Permissions (and roles/Depts also have permissions). I was thinking that all I really need to store is their userId in a secure cookie and if it's not expired fetch the rest of their info with each request in the global.asax. I would secure it with a method such as http://eversystems.eu/Document/15/Sessionless_Authentication_with_Encrypted_Tokens

What I would like to end up with is the ability in my ViewModels to annotate them with custom fields

[Authorize(Roles="Admin")] [Authorize(Dept="IT")] [Authorize(Rank="Manager")]

or in the Html say

@if(User.IsInDept("IT")

or

@if(User.HasRank("Manager"))

I looked at extending the FormsAthenticationTicket and Membership Provider / Roles etc and IPricipal and IIdentity etc but it's difficult to understand exactly how i'd modify them all to achieve what i'm after. The examples i've seen have a lot of extra bloat that I don't want but the best example i've found is by @Ahmad Abu Raddad here ASP.NET MVC - Set custom IIdentity or IPrincipal

If someone could point out if i'm heading in the right direction or possibly suggest alternatives I would appreciate it.

Community
  • 1
  • 1
Peter Lea
  • 1,731
  • 2
  • 15
  • 24
  • 1
    The best post on this Ive found is Brady Gasters here http://www.bradygaster.com/custom-authentication-with-mvc-3.0 should point you in the right direction. – Luke Baughan Apr 10 '13 at 12:00
  • Thanks, looks good, will look more in depth tonight. – Peter Lea Apr 10 '13 at 12:24
  • Its worth reading the comments at the bottom of that blog post - Ive dropped a few on there myself for hooking up the auth ticket etc ;o) – Luke Baughan Apr 10 '13 at 13:14

1 Answers1

0

Just wanted to share how I ended up solving this problem. I ended up simply creating a custom IPrincipal and exposed my internal database class.

 interface ICustomPrincipal : IPrincipal
{
    //I pass the whole model across so if we update/modify in the future it will automatically populate the new items for the cookie
    user d { get; set; }
   //some other variables
}

I set up a ton of methods in the user class like IsInRole(), isInDept(), HasRank(), HasPermission etc which returned a bool after querying database which gave me the logic in the view/controller that I needed.

I created a BaseController that could retrieve this new CustomPrincipal

public class BaseController : Controller
{
    protected virtual new CustomPrincipal User
    {
        get { return HttpContext.User as CustomPrincipal; }
    }
}

I also needed to update my WebViewPage so I could retrieve my new CustomPrincipal in the views.

public abstract class BaseViewPage : WebViewPage
{
    public virtual new CustomPrincipal User
    {
        get { return base.User as CustomPrincipal; }
    }

}

and modify my views web.config

<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="MyNameSpace.BaseViewPage">
  <namespaces>
    <add namespace="System.Web.Mvc" /> .....

If anyone finds this useful but needs more info just pm me

Peter Lea
  • 1,731
  • 2
  • 15
  • 24
  • It would be helpful for others to include when you are creating this custom principal and setting it as the User object on the HttpContext. (`HttpContext.User as CustomPrincipal` would fail if you hadn't yet done this) – JoeBrockhaus Mar 17 '14 at 20:43