CustomPrincipal cd.
Tweet
niedziela, 15 styczeń 2012
Jakiś czas temu pokazałem w
tym artykule
sposób rozszerzenia możliwości obiektu zalogowanego użytkownika
(Context.User). Problemem tamtego rozwiązania jest to, iż na końcu każdego żądania tworzony jest na nowo
obiekt CustomPrincipal, co w finalnym efekcie znacząco wpływa na wydajność aplikacji. Oczywiście
jest to zależne od ilości rzeczy implementowanych przez nasz obiekt. W celu naprawy tego niedociągnięcia
należy nieznacznie zmodyfikować kod klasy z pliku Global.asax.cs - zapraszam do lektury.
Kluczową zmianą jest rezygnacja ze zdarzenia Application_PostAuthenticateRequest na rzecz zdarzenia Application_PreRequestHandlerExecute. Przewaga drugiego zdarzenia jest znacząca, ponieważ w kontekście naszej aplikacji mamy dostęp do sesji użytkownika, a ona jest sposobem rozwiązania problemu. Daje możliwość przechowania obiektu CastomPrincipal, a tym samym nie wymusza tworzenia go na nowo. Implementacja rozwiązania to indywidualna sprawa programisty, ja postąpiłem w sposób przedstawiony poniżej.
W pierwszej kolejności zaimplementowałem metodę odpowiedzialną za zwrócenie obiektu CustomPrincipal:
Kluczową zmianą jest rezygnacja ze zdarzenia Application_PostAuthenticateRequest na rzecz zdarzenia Application_PreRequestHandlerExecute. Przewaga drugiego zdarzenia jest znacząca, ponieważ w kontekście naszej aplikacji mamy dostęp do sesji użytkownika, a ona jest sposobem rozwiązania problemu. Daje możliwość przechowania obiektu CastomPrincipal, a tym samym nie wymusza tworzenia go na nowo. Implementacja rozwiązania to indywidualna sprawa programisty, ja postąpiłem w sposób przedstawiony poniżej.
W pierwszej kolejności zaimplementowałem metodę odpowiedzialną za zwrócenie obiektu CustomPrincipal:
private System.Security.Principal.IPrincipal GetPrincipal()
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch (Exception ex)
{
return Context.User;
}
if (null == authTicket)
{
FormsAuthentication.RedirectToLoginPage();
return null;
}
else
{
var roleUser = Context.User as RolePrincipal;
return new CustomPrincipal(
new FormsIdentity(authTicket),
roleUser.IsRoleListCached ? roleUser.GetRoles() : Roles.GetRolesForUser()
);
}
}
W kolejnym, ostatnim kroku wypełniłem metodę Application_PreRequestHandlerExecute:
const string CUSTOM_PRINCIPAL = "CustomPrincipal";
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
if (Context.Session != null)
{
if (Context.Session[CUSTOM_PRINCIPAL] == null)
{
Context.Session[CUSTOM_PRINCIPAL] = GetPrincipal();
}
Context.User = Context.Session[CUSTOM_PRINCIPAL] as CustomPrincipal;
}
else
{
//Context.User = GetPrincipal();
}
}
}
Tym oto sposobem, szybkim i łatwym w implementacji, można rozwiązać poważny wydajnościowy problem aplikacji.


Twitter