CustomPrincipal cd.

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:

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.

Promuj

What do you think?
Like Love Haha Wow Sad Angry

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *