4

In my ASP.NET MVC app, I'm trying to create a custom HttpContent.User object. I've started by creating a Member class, which implements IPrincioal.

public class Member : IPrincipal { public string Id { get; set; } public IIdentity Identity { get; set; } public bool IsInRole(string role) { throw new NotImplementedException(); } ... } 

Then at authentication time I set HttpContext.User to an instance of a Member class:

FormsAuthentication.SetAuthCookie(email, false); HttpContext.User = member; 

Then later I want to check if the user is authenticated, like so:

if (User.Identity.IsAuthenticated) { ... } 

That's where I'm stuck. I'm not sure what I need to do for the public IIdentity Identity property on the instance of the Member. So that I can use the HttpContext.User object something like this:

IsAuthenticated = HttpContext.User.Identity.IsAuthenticated; ViewBag.IsAuthenticated = IsAuthenticated; if (IsAuthenticated) { CurrentMember = (Member)HttpContext.User; ViewBag.CurrentMember = CurrentMember; } 
3
  • 1
    Perhaps you will find this useful github.com/moov2/dotnet-mvc-boilerplate if you were to study the SessionAuthentication class, the LoginController and Global.asax.cs Commented Aug 11, 2012 at 5:34
  • Annd what is exactly your trouble with implementing simple IIdentity (or even using GenericIdentity)? Commented Aug 11, 2012 at 5:54
  • 1
    I've never done it before... searching Google for custom user.identity wasn't proving helpful. Do you know of some good examples I can look at? Commented Aug 11, 2012 at 5:56

1 Answer 1

6

A Principal is not something you can just set once when writing the auth cookie and forget later. During subsequent requests, the auth cookie is read and the IPrincipal / IIdentity is reconstructed before executing an action method. When that happens, trying to cast the HttpContext.User to your custom Member type will throw an exception.

One option would be to intercept in an ActionFilter, and just wrap the standard implementation.

public class UsesCustomPrincipalAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var systemPrincipal = filterContext.HttpContext.User; var customPrincipal = new Member(systemPrincipal) { Id = "not sure where this comes from", }; filterContext.HttpContext.User = customPrincipal; } } public class Member : IPrincipal { private readonly IPrincipal _systemPrincipal; public Member(IPrincipal principal) { if (principal == null) throw new ArgumentNullException("principal"); _systemPrincipal = principal; } public string Id { get; set; } public IIdentity Identity { get { return _systemPrincipal.Identity; } } public bool IsInRole(string role) { return _systemPrincipal.IsInRole(role); } } 

This way, you're not losing anything that comes out of the box with the default IPrincipal and IIdentity implementations. You can still invoke IsAuthenticated on the IIdentity, or even IsInRole(string) on the IPrincipal. The only thing you're gaining is the extra Id property on your custom IPrincipal implementation (though I'm not sure where this comes from or why you need it).

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, the Member class I posted was trimmed for brevity, there are many more properties. I'm not at my workstation right now, I'll look things over later. Thank you!
Hmm, well, it seems perhaps I shouldn't be doing this then. I was hoping that tying into FormsAuthentication, and HttpContext.User, that I could bypass doing it manually. I currently use a few Session variables, setting them on OnActionExecuting. Thanks for the info.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.