5

I have developed a simple IIdentity and IPrincipal for my MVC project and I would like to override the User and User.Identity to return the value with the right type

Here is my custom Identity:

public class MyIdentity : IIdentity
{
    public MyIdentity(string name, string authenticationType, bool isAuthenticated, Guid userId)
    {
        Name = name;
        AuthenticationType = authenticationType;
        IsAuthenticated = isAuthenticated;
        UserId = userId;
    }

    #region IIdentity
    public string Name { get; private set; }
    public string AuthenticationType { get; private set; }
    public bool IsAuthenticated { get; private set; }
    #endregion

    public Guid UserId { get; private set; }
}

Here is my custom Principal:

public class MyPrincipal : IPrincipal
{
    public MyPrincipal(IIdentity identity)
    {
        Identity = identity;
    }


    #region IPrincipal
    public bool IsInRole(string role)
    {
        throw new NotImplementedException();
    }

    public IIdentity Identity { get; private set; }
    #endregion
}

Here is my custom controller, I successfully updated the User property to return my custom principal type:

public abstract class BaseController : Controller
{
    protected new virtual MyPrincipal User
    {
        get { return HttpContext == null ? null : HttpContext.User as MyPrincipal; }
    }
}

How can I do it the same way for User.Identity to return my custom identity type?

Nipuna
  • 6,846
  • 9
  • 64
  • 87
JuChom
  • 5,717
  • 5
  • 45
  • 78

2 Answers2

3

You can explicitly implement IPrincipal in your MyPrincipalclass, and add your own Identity property of type MyIdentity.

public class MyPrincipal : IPrincipal 
{
    public MyPrincipal(MyIdentity identity)
    {
        Identity = identity;

    }

    public MyIdentity Identity {get; private set; }

    IIdentity IPrincipal.Identity { get { return this.Identity; } }

    public bool IsInRole(string role)
    {
        throw new NotImplementedException();
    }
}
Joe
  • 122,218
  • 32
  • 205
  • 338
  • 1
    Could you please double check your code, I don't see how to fix it. Thanks – JuChom Nov 20 '12 at 15:38
  • 1
    I think i understand this line: "IIdentity IPrincipal.Identity { get { return this.Identity; } }", but this is the first time I see something like that. Can you explain how to interpret it? TIA – JuChom Nov 21 '12 at 11:21
  • 1
    Swell `IPrincipal.Identity` is an explicit implementation of the interface member (google for "explicit interface implementation" for more info). The interface member needs to be implemented explicitly to avoid it conflicting with your custom member Identity which has a different type (MyIdentity vs IIdentity). The implementation simply returns the MyIdentity instance (which is automatically cast to IIdentity). – Joe Nov 21 '12 at 11:26
1

You're asking something that cannot be done without an explicit cast

public class MyClass
{
    private SomeThing x;
    public ISomeThing X { get { return x; } }
}

When you call MyClass.X, you're going to get an ISomeThing, not a SomeThing. You can do an explicit cast, but that's a bit clumsy.

MyClass myClass = new MyClass();
SomeThing someThing = (SomeThing)(myClass.X);

Ideally, the value you store for IPrincipal.Name will be unique. If "jdoe" is not unique in your application, then your IPrincipal.Name property would be better if it stored the user ID. In your case, that appears to be a GUID.

Jarrett Meyer
  • 19,333
  • 6
  • 58
  • 52
  • I want to do an explicit cast like for MyPrincipal User. I want to cast the return type of User.Identity to MyIdentity – JuChom Nov 20 '12 at 15:23