0

Trying to implement IPrincipal (ASP.NET MVC 3) and having problems: my custom IPrincipal:

  interface IDealsPrincipal: IPrincipal
    {
        int UserId { get; set; }
        string Firstname { get; set; }
        string Lastname { get; set; }
    }


public class DealsPrincipal : IDealsPrincipal
    {

        public IIdentity Identity { get; private set; }
        public bool IsInRole(string role) { return false; }

        public DealsPrincipal(string email)
        {
            this.Identity = new GenericIdentity(email);
        }

        public int UserId { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }

    }

To serialize/deserialize i use the following class:

public class DealsPrincipalSerializeModel
    {
        public int UserId { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }
    }

The Application authenticate event is as follows (works fine!)

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
        {
            HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
            if (authCookie != null)
            {
                //get the forms ticket
                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                //instantiate a new Deserializer
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                //deserialize the model
                DealsPrincipalSerializeModel serializeModel = serializer.Deserialize<DealsPrincipalSerializeModel>(authTicket.UserData);
                //put the values of the deserialized model into the HttpContext
                DealsPrincipal newUser = new DealsPrincipal(authTicket.Name); //this implements IPrincipal
                newUser.UserId = serializeModel.UserId;
                newUser.Firstname = serializeModel.Firstname;
                newUser.Lastname = serializeModel.Lastname;

                HttpContext.Current.User = newUser;                
            }
        }

As you can see in the last statement the HttpContext gets assigned this new DealsPrincipal (which works fine).

The problem is that if want to access this User in a Controller(Action) i always get a base class object. If i cast the User as follows:

User as DealsPrincipal 

to get for example the UserId (sample:

( User as DealsPrincipal).UserId 

this is always null!!! Why? What am i missing?

Savvas Sopiadis
  • 8,213
  • 10
  • 34
  • 53

1 Answers1

0

I would need to investigate more to give you correct answer but look this part of the code and it could help you (part of the source of WindowsAuthenticationModule.cs)

void OnAuthenticate(WindowsAuthenticationEventArgs e) {
        //////////////////////////////////////////////////////////// 
        // If there are event handlers, invoke the handlers 
        if (_eventHandler != null)
             _eventHandler(this, e); 

        if (e.Context.User == null)
        {
            if (e.User != null) 
                e.Context.User = e.User;
            else  if (e.Identity == _anonymousIdentity) 
                e.Context.SetPrincipalNoDemand(_anonymousPrincipal, false /*needToSetNativePrincipal*/); 
            else
                e.Context.SetPrincipalNoDemand(new WindowsPrincipal(e.Identity), false /*needToSetNativePrincipal*/); 
        }
    }

From this code I would suggest you to check if user is anonymous before assigning instance of your custom IPrincipal inmplementation. Also, not sure if this method is executed before or after "protected void Application_AuthenticateRequest". Will try to take more time to investigate this.

Also, please look at this article:

http://msdn.microsoft.com/en-us/library/ff649210.aspx

Andrej Kaurin
  • 11,592
  • 13
  • 46
  • 54