OT(?) Why separate IPrincipal and IIdentity objects

OT(?) Why separate IPrincipal and IIdentity objects

Old forum URL: forums.lhotka.net/forums/t/2594.aspx


SonOfPirate posted on Tuesday, March 27, 2007

I have been engaged in a debate regarding why there are separate IPrincipal and IIdentity objects in the .NET security model.  I've explained that the principal represents the security context and allows for role-checking while the identity is just that, the identity of the current user (name, etc.).  However, having been confronted with numerous questions and arguments, I am trying to understand the practical side of this as we follow this practice with Csla.

In all but one case that I've been able to find, there is a one-to-one relationship between the principal and identity classes (WindowsPrincipal/WindowsIdentity, PassportPrincipal/PassportIdentity, GenericPrincipal/GenericIdentity).  The only exception is the FormsIdentity object which will be contained by a GenericPrincipal object.

In researching the literature, Microsoft makes the statement that the only legitimate reasons why you would want to create your own custom principal is if you want to overload the IsInRole method (as is done with the WindowsPrincipal class) or add additional functionality (which is not demonstrated anywhere).

Given this, why then have a BusinessPrincipalBase class that does nothing different from GenericPrincipal?  Couldn't the custom identity be simply wrapped in a GenericPrincipal (as with FormsIdentity) using something similar to:

IPrincipal p = new GenericPrincipal(myIdentity);

That's the first question.  Second question is aside from the built-in forms authentication (using FormsIdentity), can anyone give me an example where it makes sense to have a separate identity class?

What I mean is, in the ProjectTracker sample application, there are custom PTPrincipal and PTIdentity classes.  Why not just have one class that implements both interfaces if there is a one-to-one relationship?

Many more thoughts have been thrown around here but I will leave it at that and open the floor for your comments and thoughts.

Thx

rrsstio replied on Saturday, January 05, 2008

IMHO sometimes an application might have not only one-to-one relationship between the principal and identity classes.
For example, a web-app can accept human "users" and other program "users" (which call services of the web-app). For these different types of users you might have different types of IIdentyfy objects.
Of course in this case you might have one base IIdentity class which will provide role-checking and two derived classes for human and program "users". But then you can't easy change role-checking system (by configuring in config file) or may be you want to support different role-checking systems in the same app.

Summary, it's just separation of responsibilities: IIdentity contains data of user, but IPrincipal executes some security functionality against an user and (it's important) IPrincipal doesn't represent an user (in spite of confusing System.Web.HttpContext.Current.User which is an IPrincipal object).

edited by: rrsstio at 7:25 PM (GMT -6) on Sat, Jan 05 2008
Found more clear explanation of responsibility separation of that interfaces at MSDN (http://msdn2.microsoft.com/en-us/library/ms172765(VS.80).aspx):

"Using two objects allows for a separation of authentication (in the identity object) and authorization (in the principal)."

goracio replied on Sunday, January 06, 2008

Think that BuisinessPrincipalBase is serializable class and GenericPrincipal is not.

And Separation of responsibilities may prove usefull in complex scenarios.

Max

goracio replied on Sunday, January 06, 2008

Figuruing it out a little i came to probable answer- Principal object can be used for caching some info in it that is not relevant to underlying identity. 

And a little off the question - dosnt  it seems to you that RolesForProperty is too granular for practical purposes, it adds heavyness to the business object?

It would be better to have RolesForObject instead, because object resposible for some functional resource that user in its entirety can read or write.

I think that such granularity is bad design of objects.

P.S.- Maybe its a question to Rocky:)

rasupit replied on Sunday, January 06, 2008

why there are separate IPrincipal and IIdentity objects in the .NET security model

The separation is just good OOP to follow SRP. IIdentity is for authentication and IPrincipal is for authorization

Given this, why then have a BusinessPrincipalBase class that does nothing different from GenericPrincipal?  Couldn't the custom identity be simply wrapped in a GenericPrincipal (as with FormsIdentity) using something similar to:

IPrincipal p = new GenericPrincipal(myIdentity);

Actually it should be new GenericPrincipal(myIdentity, myRoles);  This is a good question.  I could not find the reason in the book and I have never use it.  goracio, did you try that the GenericPrincipal could not be serialized?  I took a peek using reflector and found signature of this class is as follow:

[Serializable, ComVisible(true)] public class GenericPrincipal : IPrincipal

Second question is aside from the built-in forms authentication (using FormsIdentity), can anyone give me an example where it makes sense to have a separate identity class?

I usually built internal app and let windows in charge of the authentication through WindowsIdentity.  If the app want to manage the roles than I usually use have class to retrieve the roles for this user and use GenericPrincipal to store it, so I can use the IsInRole method.

Ricky

goracio replied on Sunday, January 06, 2008

Then I dont know why there BuisinessPrincipalBase istead of GenericPrincipal. There would be sufficient the second. But no harm is done.

Copyright (c) Marimer LLC