Avatar billede jmarkling Nybegynder
18. december 2004 - 18:42 Der er 15 kommentarer og
1 løsning

Undgå TypeCast (boxing) af Session objekt

Jeg har en login system med GenericPrincipal and FormsIdentity som virker fint.
Men udover det har jeg et session objekt der peger på et user objekt jeg har oprettet ved login.
På de sider hvor der kan flere roller logget ind, vil jeg helst undgå at typecaste(boxing) det. Eksempelvis i en pageload, hvor jeg loader en menu.

Roles.RoleDecorator user = (Roles.Admin) Session["user"];
Label1.Text = user.LoadMenu();

Her kan jeg jo ikke vide om det er en admin, der er logget ind eller om det er ordinary user.

Så koden skulle se sådanne ud.

Roles.RoleDecorator user = (Roles.NormalUser) Session["user"];
Label1.Text = user.LoadMenu();

Jeg har kigget lidt på denne løsning, men syntes ikke rigtigt om den:

http://www.codeproject.com/aspnet/typedsessionstate.asp#xx625463xx
Avatar billede burningice Nybegynder
18. december 2004 - 20:46 #1
?? hvorfor har du dobbelt loginsystem?
Avatar billede jmarkling Nybegynder
19. december 2004 - 11:18 #2
Der er mange grunde, men det er sku' da cool at jeg eksempelvis, kan gøre som ovenstående, og loade en menu special-tilpasset den bruger der logget ind.
Avatar billede burningice Nybegynder
19. december 2004 - 11:29 #3
jo.. men det er jo ikke svært at lave sit eget user-object der kan populeres igennem FormAuthentication.
Avatar billede jmarkling Nybegynder
19. december 2004 - 11:55 #4
ok... det lyder som noget jeg kan bruge...
Avatar billede burningice Nybegynder
19. december 2004 - 12:04 #5
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT06.asp

kig under "Create a Class that Implements and Extends IPrincipal"
Avatar billede jmarkling Nybegynder
19. december 2004 - 13:21 #6
Nu har jeg lavet min custom class:

using System;
using System.Security.Principal;
using Roles;


namespace CalendarMan
{
    /// <summary>
    /// CustomPrincipal.
    /// This class i devloped because of ASP.NET's
    /// Session object is loosely typed, and it's annoying to
    /// typecast(boxing) it every time we need a user object
    /// </summary>
    /// <see>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/SecNetHT06.asp</see>
    public class CustomPrincipal : IPrincipal
    {
        private IIdentity _identity;
        private string [] _roles;
        //This is the custom user object according to the User classes
        private Roles.RoleDecorator user;

        /// <summary>
        /// Constructor
        /// </summary>
        public CustomPrincipal(IIdentity identity, string [] roles, Roles.RoleDecorator us)
        {
            _identity = identity;
            _roles = new string[roles.Length];
            roles.CopyTo(_roles, 0);
            Array.Sort(_roles);
            user = us;
        }

        // IPrincipal Implementation


        /// <summary>
        /// IsInRole, function to see if a user has a surden role
        /// </summary>
        /// <param name="role">the role to check</param>
        /// <returns>bool</returns>
        public bool IsInRole(string role)
        {
            return Array.BinarySearch( _roles, role ) >=0 ? true : false;
        }
       
        /// <summary>
        /// Proberty Identity
        /// </summary>
        /// <returns>Identity</returns>
        public IIdentity Identity
        {
            get
            {
                return _identity;
            }
        }
       
       
        /// <summary>
        /// Checks whether a principal is in all of the specified set of
        /// </summary>
        /// <param name="roles">the roles to check</param>
        /// <returns>bool</returns>
        public bool IsInAllRoles( params string [] roles )
        {
            foreach (string searchrole in roles )
            {
                if (Array.BinarySearch(_roles, searchrole) < 0 )
                    return false;
            }
            return true;
        }
       
        /// <summary>
        /// Checks whether a principal is in any of the specified set of
        /// </summary>
        /// <param name="roles">the roles to check</param>
        /// <returns>bool</returns>
        public bool IsInAnyRoles( params string [] roles )
        {
            foreach (string searchrole in roles )
            {
                if (Array.BinarySearch(_roles, searchrole ) > 0 )
                {
                    return true;
                }
            }
            return false;
        }


    }
}
Avatar billede jmarkling Nybegynder
19. december 2004 - 13:22 #7
Og jeg har ændret en linje i Global.asax filen... til:
CustomPrincipal principal = new CustomPrincipal(id, roles, user);
Avatar billede jmarkling Nybegynder
19. december 2004 - 13:27 #8
Nu, skal jeg bare finde frem til hvordan jeg for smidt min user ind i constructoren... og hvordan jeg får fat i ham igen...
Avatar billede burningice Nybegynder
19. december 2004 - 13:36 #9
din user?? altså, du kan smide alle de metoder du har lyst til ind i din CustomPrincipal, f.eks. en LoadMenu(). det er meningen at al User-relateret snask skal foregå gennem denne klasse
Avatar billede jmarkling Nybegynder
19. december 2004 - 13:39 #10
Jeg har alle mine user types i en seperat dll, og der skal de blive...
Avatar billede burningice Nybegynder
19. december 2004 - 13:47 #11
:) så er det jo ikke nemt..  der vist ingen grund til at rodere videre med .nets indbyggede usermodel så.

så bruger du nødt til at lave en form for RequestHelper der kender typerne og navnene på dine ting i session'en
Avatar billede jmarkling Nybegynder
19. december 2004 - 13:50 #12
Har lige et spørgsmål til, bliver Application_AuthenticateRequest, kaldt hver gang en bruger ønsker en resource på serveren?
Avatar billede jmarkling Nybegynder
19. december 2004 - 15:24 #13
Nå,jeg har valgt at holde det i sessions, men jeg har stadig samme problem... jeg har lavet en snyde klasse til at afhjælpe problemet... men syntes ikke løsningen er særlig elegant.
Avatar billede burningice Nybegynder
19. december 2004 - 15:43 #14
Application_AuthenticateRequest bliver kaldet hver gang, ja... dog vil man som oftest kun loade de nødvendige ting fra sin datastore første gang og derefter gemme det f.eks. i cachen eller i session.

det er den eneste løsning da session returnerer typen object, og c# er meget striks med typerne. Måske du kunne skifte til VB.Net og udnytte dens lidt slatne holdning til typerne ;)
Avatar billede jmarkling Nybegynder
19. december 2004 - 15:49 #15
Smid et svar din ide' til en custom Principal var cool nok...
Men din ide' med at skifte til VB lugter... :D
Avatar billede burningice Nybegynder
19. december 2004 - 15:57 #16
jeg benytter selv metoden at udnytte IPrincipal-interfacet til at gøre brug af FormsAuthentication, så den er skam god nok. Men jeg kan da godt se, at hvis man har et stort stystem allerede, så vil det være træls at kode om.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester