CustomPrincipal
Tweet
poniedziałek, 31 styczeń 2011
UPDATED: Zachęcam do zapoznania się z kontynuacją tego tematu - CustomPrincipal cd.
Obiekt użytkownika wykonującego żądanie (Context.User) jest powszechnie znany. Dzięki niemu w prosty i szybki sposób sprawdzimy, czy osobnik poruszający się po naszej aplikacji jest zalogowany oraz jaki jest jego login. Dodatkowo, jeśli zrzutujemy ten obiekt na klasę, np. RolePrincipal, to otrzymamy dodatkowe możliwości tego obiektu (wymagana deklaracja roleManagera w web.config). A co jeśli chcielibyśmy, aby ten obiekt zawierał nasze właściwości oraz metody? W tym artykule zaprezentuję co należy wykonać, aby obiekt User implementował naszą zawartość.
W pierwszej kolejności dodajemy nową klasę do projektu aplikacji. Ta musi dziedziczyć po GeneralPrincipal. Dodajemy dwie testowe właściwości: UserLogin oraz UserRoles. Definiujemy konstruktor, do którego przesyłać będziemy obiekt FormsIdentity i role użytkownika. Na koniec wywołujemy konstruktor z typu bazowego, po którym dziedziczymy oraz przypisujemy wartości zmiennych. Wszystko to może wyglądać w następujący sposób:
Efekt osiągnięty. W tym momencie możemy do woli rozwijać klasę CustomPrincipal. Przykładowo:
Obiekt użytkownika wykonującego żądanie (Context.User) jest powszechnie znany. Dzięki niemu w prosty i szybki sposób sprawdzimy, czy osobnik poruszający się po naszej aplikacji jest zalogowany oraz jaki jest jego login. Dodatkowo, jeśli zrzutujemy ten obiekt na klasę, np. RolePrincipal, to otrzymamy dodatkowe możliwości tego obiektu (wymagana deklaracja roleManagera w web.config). A co jeśli chcielibyśmy, aby ten obiekt zawierał nasze właściwości oraz metody? W tym artykule zaprezentuję co należy wykonać, aby obiekt User implementował naszą zawartość.
W pierwszej kolejności dodajemy nową klasę do projektu aplikacji. Ta musi dziedziczyć po GeneralPrincipal. Dodajemy dwie testowe właściwości: UserLogin oraz UserRoles. Definiujemy konstruktor, do którego przesyłać będziemy obiekt FormsIdentity i role użytkownika. Na koniec wywołujemy konstruktor z typu bazowego, po którym dziedziczymy oraz przypisujemy wartości zmiennych. Wszystko to może wyglądać w następujący sposób:
public class CustomPrincipal : System.Security.Principal.GenericPrincipal
{
#region properties
public string UserLogin { get; private set; }
public string[] UserRoles { get; private set; }
#endregion
#region ctors
public CustomPrincipal(System.Web.Security.FormsIdentity fiIdentity, string[] sUserRoles)
: base(fiIdentity, sUserRoles)
{
UserLogin = fiIdentity.Name;
UserRoles = sUserRoles;
//LoadDetails();
}
#endregion
}
Następnym krokiem jest deklaracja roleManagera w pliku web.config (można to uczynić tak, jak
w tym artykule).
Potem dodajemy do projektu
Global Application Class,
w której deklarujemy zdarzenie jak poniżej:
void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
if (Request.IsAuthenticated)
{
FormsAuthenticationTicket authTicket = FormsAuthentication
.Decrypt(Context.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
var user = Context.User as RolePrincipal;
CustomPrincipal customPrincipal = new CustomPrincipal(new FormsIdentity(authTicket), user.GetRoles());
Context.User = customPrincipal;
}
}
W powyższym kodzie w pierwszej kolejności pobieramy ciasteczka, stworzone po poprawnym zalogowaniu
użytkownika. Te są dekodowane, a z nich tworzony jest ticket autoryzacyjny wykorzystywany do stworzenia
obiektu FormsIdentity, który finalnie należy wykorzystać podczas tworzenia obiektu CustomPrincipal.
Na koniec należy jeszcze podmienić obiekt użytkownika.
Efekt osiągnięty. W tym momencie możemy do woli rozwijać klasę CustomPrincipal. Przykładowo:
public class CustomPrincipal : System.Security.Principal.GenericPrincipal
{
#region properties
// ...
public string FullName { get; private set; }
public DateTime BirthDate { get; private set; }
#endregion
// ...
#region public
public bool HasRight(SystemRight srRight)
{
// ...
}
#endregion
#region private
private void LoadDetails()
{
var user = DBHelper.GetModel().User
.FirstOrDefault(a => a.UserId ==
new Guid(System.Web.Security.Membership.GetUser().ProviderUserKey.ToString()));
FullName = "{FirstName} {LastName}".FormatWith(user);
BirthDate = user.BirthDate;
}
#endregion
}
oraz wykorzystanie:
protected void Page_Load(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
var user = User as CustomPrincipal;
lFullName.Text = user.FullName;
if (user.HasRight(SystemRight.VisitMoon))
{
// ...
}
}
}
Jak widać powyżej, jest to tylko mały przykład możliwości rozwoju klasy
CustomPrincipal. Myślę, że można ulepszać ją w każdym kierunku, a jej
granice wyznacza tylko wyobraźnia programisty.


Twitter