creating a _simple_ fine grained user based security system

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • giddy

    #1

    creating a _simple_ fine grained user based security system

    hi,

    (I want someone to check if my idea is utterly stupid or ok??)

    I have a mid complex app for a hotel that needs a fine grained user
    security system. In other words an admin should be able to deny/grant
    specific access to users like Ability to make a Reservation or the
    ability to print reports.

    Now, I'm thinking the business objects could take something like:

    enum UserPrivileges { various privileges..... .. };

    IPrivilegedUser
    {
    public UserPrivileges Privileges
    {
    get;
    }
    }

    The user class inherits from this interface, the business objects
    could take this user in a function and return true/false as per the
    needed privileges, or maybe throw an exception:

    User user1 = new User(); //class User inherits from IPrivilegedUser
    and loads the right privileges from the DB
    Reservations.Lo adPrivileges(us er1);//check the returned value..??
    Reservations.Ed itReservation() // calling this should fail if the
    privileges are not enough!?

    Is this a good enough design, will it break apart somewhere or is
    there a better way to do this?

    Declarative security like CAS in .NET would be an overkill since its
    not a very large app, but I do need the design to be flexible enough
    so that if the app does grow big I'm not in a mess.

    Thanks

    Gideon
  • giddy

    #2
    Re: creating a _simple_ fine grained user based security system

    hi Peter,

    Thanks so much for your reply.
    IUserPermission Service
    {
        bool CanCreateReserv ations(User user);
        bool CanEditReservat ion(User user, Reservation reservation);
        etc
    >
    }
    This is nice, I've still got just few simple question, should I make
    the ServiceProvider singleton? So its available everywhere?

    Also, I will be testing for user rights in the UI's presentation
    classes so is there a nice way to Disable/Enable menus, buttons based
    on when a new User signs in?

    I was thinking the MainWorkspace(F orm) and the subview(usercon trols)
    and menus respond to a UserChanged event and then call the service to
    check for the right privileges. But where should the UserChanged event
    come from in the first place?

    Thanks so much

    Gideon

    Comment

    • Marc Gravell

      #3
      Re: creating a _simple_ fine grained user based security system

      To be honest, I'd still be tempted to use an IPrincipal. This does
      everything you want with existing APIs. You could always add a static
      class to provide simplified access, i.e.

      public static bool CanCreateReserv ation() {
      return HasAccess(some constant)
      }
      private static bool HasAccess(strin g role) {
      // get principal and call IsInRole...
      }

      If you don't want to create your own principal, you can use
      GenericPrincipa l / GenericUser very simply.

      Marc

      Comment

      • Peter Morris

        #4
        Re: creating a _simple_ fine grained user based security system

        >>
        This is nice, I've still got just few simple question, should I make
        the ServiceProvider singleton? So its available everywhere?
        <<

        You could do, yes, as long as you ensure thread safety in your services.
        >>
        Also, I will be testing for user rights in the UI's presentation
        classes so is there a nice way to Disable/Enable menus, buttons based
        on when a new User signs in?
        <<

        You'd have to execute some code after login to enable or disable them based
        on results from the security service.

        >>
        I was thinking the MainWorkspace(F orm) and the subview(usercon trols)
        and menus respond to a UserChanged event and then call the service to
        check for the right privileges. But where should the UserChanged event
        come from in the first place?
        <<

        You expect the user to change whilst your app is running? Can you explain?



        Pete

        Comment

        • Marc Gravell

          #5
          Re: creating a _simple_ fine grained user based security system

          Also, I will be testing for user rights in the UI's presentation
          classes so is there a nice way to Disable/Enable menus, buttons based
          on when a new User signs in?
          I didn't add anything to support hot-swapping of the user (since that
          isn't usually expected), but for a lazy way to enable/disable buttons,
          etc - how about a custom UI component that lets you specify roles on
          controls in the IDE?



          Note that UI enabling/disabling should really be just a convenience -
          your "real" code should enforce the access - hence why declarative
          security ([PrincipalPermis sion] etc) can be useful for simple code.

          Marc

          Comment

          • giddy

            #6
            Re: creating a _simple_ fine grained user based security system

            hi thanks for your replies,
            >You expect the user to change whilst your app is running? Can you explain?
            oh, seem like an odd thing for you guys? Different users with
            different privileges work in different shifts on the same machine
            which runs the app, so after a certain time the app on Machine1 will
            have another user with different privileges logging in. It would be a
            little odd for me to tell them to shut the app down just for the next
            person. Also, its only a matter of calling UIEnable routines through
            an event.

            I didn't add anything to support hot-swapping of the user (since that
            isn't usually expected), but for a lazy way to enable/disable buttons,
            etc - how about a custom UI component that lets you specify roles on
            controls in the IDE?
            >
            http://groups.google.com/group/micro...languages.csha...
            I like your component Marc although I was thinking more along the
            lines of a service.

            Note that UI enabling/disabling should really be just a convenience -
            your "real" code should enforce the access - hence why declarative
            security ([PrincipalPermis sion] etc) can be useful for simple code.
            Yes, i understand what you're saying, i did think about this, was kind
            of hard to explain. (I'm not formally computer literate)

            If Base Code enforces security I would still be doing the same thing
            in the UI code.

            if(userPermServ ice.CanEditRese rvations(user1) )
            {
            Reservations.Ed it(res1);//now whether my code enforces permissions or
            not would make a difference here right?
            }
            Unless of course if i tried to directly call Reservations.Ed it(res1);
            without checking for permissions the code would throw an exception if
            he didn't.

            So does that make it a better design? Enforcing rules so that I
            *might* not end up making a mistake?

            Thanks so much
            Gideon

            Comment

            • Peter Morris

              #7
              Re: creating a _simple_ fine grained user based security system

              oh, seem like an odd thing for you guys? Different users with
              different privileges work in different shifts on the same machine
              which runs the app, so after a certain time the app on Machine1 will
              have another user with different privileges logging in. It would be a
              little odd for me to tell them to shut the app down just for the next
              person. Also, its only a matter of calling UIEnable routines through
              an event.
              But it wouldn't be odd to ask them to sign out of the app when they leave,
              returning the user to the sign in form. So you wont be "hot" swapping the
              user then (changing the user in the middle of something).
              So does that make it a better design? Enforcing rules so that I
              *might* not end up making a mistake?
              I always do that. For example; my business objects are able to produce a
              list of validation errors. I use those in the GUI to prevent the user from
              saving. However, it is possible that something might eventually call
              UpdateDatabase on my persistence service without first checking these
              constraints, so my persistence service will check the validity of each
              object before attempting to save and throw an exception if there is
              something wrong.



              Pete

              Comment

              • Marc Gravell

                #8
                Re: creating a _simple_ fine grained user based security system

                Just to second what Pete said:

                * returning to a login form makes for a clean place to swap users
                without existing forms needing to worry
                * your business logic should definitely enforce any rules

                The biggest point about the second bullet is that it allows you to
                cleanly separate the UI from the business rules; for example, you
                might have an alternative UI for some users (perhaps a web/winform/wpf/
                silverlight/CF version etc), but it would be nice if the same rules
                were applied in case you forget things. Declarative security just
                happens to be a simple way of handling the "check access and throw an
                exception" in a single statement, without cluttering the code:

                [PrincipalPermis sion(SecurityAc tion.Demand, Role =
                MyRoles.Reserva tionEdit)]
                public void EditReservation (...)
                {
                //...
                }

                (obviously you can do more sophisticated things if you want to check
                different roles in different scenarios, etc)

                For re-use (and to avoid duplication / typos) you can keep the roles
                together like:

                static class MyRoles
                {
                public const string ReservationEdit = "RES EDIT";
                // ...
                }

                If you wanted to get fancy you could probably also hook it into that
                IDE component without too much pain...

                The point of the IPrincipal usage is partly that it allows use of
                declarative security - but more importantly this is how all the core
                framework identity code operates: if you login to ASP.NET, you get an
                IPrincipal. If you login via WCF you get a IPrincipal; etc. You can,
                of course, invent your own API - but using the core API allows you to
                exploit all the framework code. For example, you could use "client
                application services" in VS2008 to use the same identity/roles model
                for aspx and winform/wpf.

                Marc

                Comment

                • giddy

                  #9
                  Re: creating a _simple_ fine grained user based security system

                  hi,

                  thanks for your help. I get what you saying.

                  I'm just a little afraid of over complicating this app, its in its
                  second version now. I ruined the first by created a mess of code that
                  was too complicated with all sorts of "features"

                  I want make it simple but sturdy so It can change later, and this
                  seems like the way to go.

                  I know .NET very well actually, but i'm just not old/experienced
                  enough to design an app all on my own.

                  Thanks so much

                  Gideon

                  Comment

                  • Marc Gravell

                    #10
                    Re: creating a _simple_ fine grained user based security system

                    I'm just a little afraid of over complicating this app

                    IMO - creating your own identity/roles model adds complexity. Using
                    IPrincipal, especially if you just start at the simplest level using
                    GenericPrincipa l etc keeps the complexity low while allowing you to
                    switch to more sophisticated models later.

                    Here's some code that tells the system that the current user is Fred,
                    and the roles he has:

                    Thread.CurrentP rincipal = new GenericPrincipa l(
                    new GenericIdentity ("Fred"),
                    new string[] { "GUEST", "USER", "CUST EDIT", "CUST
                    ADMIN" }
                    );

                    Obviously in most cases you'd build the list of roles separately
                    (perhaps in a List<string>).

                    Marc

                    Comment

                    • giddy

                      #11
                      Re: creating a _simple_ fine grained user based security system

                      thanks so much Marc,

                      I've already planned a User class so I think it would be better for me
                      to derive from IPrinciple .

                      Gideon

                      Comment

                      • Peter Morris

                        #12
                        Re: creating a _simple_ fine grained user based security system

                        Following on from my previous post about using(Tricks) here is an example which makes writing test cases easier rather than just for making ...

                        Comment

                        Working...