RE: Security with CFCs [LONG]
On Jul 17, 2004, at 1:05 AM, Jim Davis wrote: >A rather brute-force way of handling permission changes is to force >that (or all) user to re-login after a permission change, A bit >inconvenient, but probably acceptable because you likely wouldn't do >it often That does work... but we can do better! ;^) Also, at least in the other canned system's I've seen out there this is really (surprisingly) difficult. In these systems the security information is copied to the session (and there is normally no way for an application to access all of its attendant sessions). All the security system checks is the roles/groups information stored in the session against the allowable roles/groups stored in the template (or, even worse, just checks a simple "logged in" Boolean in the session scope itself). So without restarting the application there's no way to force new logins because after authenticating these systems NEVER check with the security system again. That's a bad thing, I think. >So, conceptually, you are securing the server, thru that the >application, and thru that the user, and thru that each user request. > >And, you can have as much (or as little) security at each level as you >want, Sorta, kinda? In the simplest case the application.cfm (or some other single point of entry) would just check to see if the user was authenticated (not caring about the roles) like this: The session is logged in The session is not logged in The actually entitlement system is pretty simplistic right now: you define a group (say "administrator") and add UserKeys to it (using an admin system that hasn't been defined yet). After authentication the check entitlement code would be (something like): DP_Security.isEntitled(SessionKey, "Adminstrator"). However you could get very fine grained if you like. You could define Groups that cover functionality just as easily as location. For example you might define a group called "Admin_DeleteUser". Then, in your admin system you could do something like this: Present the control to delete a user. This is what I meant by "the security system doesn't protect itself" - instead you protect the security by defining (in as detailed a fashion as you like) entitlement groups and building your admin UI around them. I've enough on my plate now, but in the future I'd like to expand this to include more advanced entitlements: nested groups of entitlements (allowing you to say that "DeleteUser", "AddUser" and "EditUser" are all part of the "Admin" group), linked entitlements (so you could say "You must be part of BOTH these groups to do this, not just one or the other"), and other things. I could also see Applications that use this system ship scripts for updating existing instances of the system themselves. For example if I were to ship a Forums application using this system I could also ship a small script that added some Forum specific groups to an already in-place system. That way you could easily set up the application by itself or integrate it easily with an existing application. Lastly I also plan (since this is something I've built for 4.5-based systems and really like) to include the ability to passed authentications from one system to another and define trust relationships across them. This will probably be done via web services, but the idea is that I could define a relationship on FirstNight.org that says "Anybody from DepressedPress.com is alright with me!" and allow them in. In that case there would be a special link on the sites that passed the authentication information, but the system would (almost have to) allow for full web service access to authentication: meaning you could set up a single authentication provider for multiple websites (although I can't guarantee performance!) Even with as much as I've described there's loads of room for improvement. >With your design, will you have a graceful way of disabling/re-enabling >an applications permissions? > >This is useful for periodic backups and upgrades. Well, I hadnt thought about it... but I suppose I should. As it stands the Credential has an "isActive" property than can be set to true to temporarily disable access to a particular user without deleting them. Now that you mention it however I suppose an Entitlement (Group) should also have a property like that, uh? Then you could "turn off" a group temporarily. I'm not sure how I'd implement it tho'... the simplest method would be to just return "false" when the entitlement was asked for. That would work, but how would the interface know that the user had access but that the group was disabled versus the user just not having access. I suppose that's just another thing I could leave to the interface... Good idea tho, even if I'm not sure how to best do it. >In your initial post you said (early on): > >"The security system would not secure itself. Perhaps this is > wrong, but I didn't want to make it that complicated" > >and (at th
Re: Security with CFCs [LONG]
On Jul 17, 2004, at 1:05 AM, Jim Davis wrote: > > Most of the systems, for example, call the database then create some > type of > user object then store that in the session scope. Thats fine, but > problems occur if an admin changes the persons permissions (since > they > wont take effect until the next log in) or the user ends up with > multiple > sessions. It just always seemed somehow flimsy to me (even tho > Ive done > it in the past myself). A rather brute-force way of handling permission changes is to force that (or all) user to re-login after a permission change, A bit inconvenient, but probably acceptable because you likely wouldn't do it often > The primary goal for me was to design a system that required very > little > knowledge of the application it was protecting. The system Ive > described > (but remember I havent built it yet so this is all conjecture) > will work > just fine if the application doesnt enabled the session scope (in > fact if > you instantiate it in the server scope you dont even need the > application > scope). I like that! > The outside application defines the touch points and keys used to > get at > the information. Im actually quite pleased with that fact: it was an > important turning point for me not to consider how to get things > into the > session and using the session as a cache point. So, conceptually, you are securing the server, thru that the application, and thru that the user, and thru that each user request. And, you can have as much (or as little) security at each level as you want, > The system is complex, but caches its information very aggressively > so (I > hope!) it should still be quite fast. The caching adds complexity > but also > enables us to deal with multiple entities working on the same data > very > gracefully. When I, as an admin, revoke or add permissions on your > account > youll see the change on the very next request. With your design, will you have a graceful way of disabling/re-enabling an applications permissions? This is useful for periodic backups and upgrades. > Once I get the damn thing done it should be a nice, clichéd black > box > you wont have to know how it works inside to use it. As I said the > system > itself wont have any interface at all (although when/if I distribute > it > Ill include a sample interface) so itll be applicable to pretty > much any > CF application. In your initial post you said (early on): "The security system would not secure itself. Perhaps this is wrong, but I didn't want to make it that complicated" and (at the end) "Although I'm truly pleased with the end-user side of things I'm not so sure yet about the admin side of things..." Isn't the logical resolution that: 1) To the "Security" system the Admin is just another, albeit special, application 2) The "Security" system must be robust enough to allow enough function to the Admin application, that it can enable/disable the "Security" system. 3) When disabled, the "Security" of the server (and all that flows from it) could be: Lockdown; or open access; Also, I wonder if this (security system) might be fairly easy to prototype. Consider that most applications have an Application.cfm file. You could have each request invoke the main security module main. this would, initially just gather/log/cache info and return. Another app could real-time monitor the log/cache with some sort/display/zoom options. You will want to have this app anyway as a security monitor control panel. If you write it early, it will help you design and implement the rest of the system You could implement the other functions (cfcs) as skeletons (gather/log/cache & return) and add the associated "touch points" to selected applications. This way you can simulate/observe the security system without affecting the applications. Jim, thanks for the additional explanation -- I think that I understand what "it" does & why I need it. Keep us posted. Dick [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
RE: Security with CFCs [LONG]
Actually Michaels not quite that strict: you can write and post more than 100 lines, but you get a message reminding you to trim your posts if thats the reason you went over. Im sure he also tracks them and will start sending stinkbugs to anybody that flouts the rule too often. ;^) Ive been struggling with the topic for several weeks now: youd be surprised how little information there is out there on actually building something like this. I looked at the papers by Yoder and Barclow (Patterns for implementing application security) but on one hand they were slightly over my head (requiring some knowledge of more general design patterns) and on the other hand they just didnt go deep enough (there were no object models, no examples of combining the various patterns, etc they just covered the most basic of conceptualizations). Theres one article at Macromedia.com that builds something like this but so painfully simply its really not worth looking at if you really want to do it (the article really covers general CFC creation in detail, but very little about the security system). I even paid for an article/sample code that (I think) Larry Lyons recommended, but it was also a bit on the simplistic side (although perfectly workable) and any caching or advanced features. It also (it seemed to me) lacked a cohesive philosophy of security. I tried several downloads from the Macromedia Exchange and just didnt care for them (again, mostly too simplistic and lacking in flexibility). Most of the systems, for example, call the database then create some type of user object then store that in the session scope. Thats fine, but problems occur if an admin changes the persons permissions (since they wont take effect until the next log in) or the user ends up with multiple sessions. It just always seemed somehow flimsy to me (even tho Ive done it in the past myself). Ive been banging my head against a wall thinking: there must be something Im missing. Some standard design that I can steal, some basic object model that I can start with. I just found nothing useful. As for what it does and why you need it well, I dont know why you need it; but I do know that I need it. And if I do (since Im nothing special) maybe some other people might as well. ;^) The primary goal for me was to design a system that required very little knowledge of the application it was protecting. The system Ive described (but remember I havent built it yet so this is all conjecture) will work just fine if the application doesnt enabled the session scope (in fact if you instantiate it in the server scope you dont even need the application scope). The outside application defines the touch points and keys used to get at the information. Im actually quite pleased with that fact: it was an important turning point for me not to consider how to get things into the session and using the session as a cache point. The system is complex, but caches its information very aggressively so (I hope!) it should still be quite fast. The caching adds complexity but also enables us to deal with multiple entities working on the same data very gracefully. When I, as an admin, revoke or add permissions on your account youll see the change on the very next request. Once I get the damn thing done it should be a nice, clichéd black box you wont have to know how it works inside to use it. As I said the system itself wont have any interface at all (although when/if I distribute it Ill include a sample interface) so itll be applicable to pretty much any CF application. Lastly, although I didnt go into this in the first post (it was more than long enough) but Ive planned the system for expansion: all of the persistence-layer stuff (database interaction) is completely segmented. Adding support for a new database is as easy as creating a new set of broker components with your database-specific code (although it doesnt have to be a database). Since the brokers to use are determined at run-time you can use the same codebase (as long as you have the brokers) to manage as many datasources/data types as you like. You could have two applications use Access, another use SQL Server and another use XML or LDAP. Although for my part Ill probably only be building SQL Server code (at least at first). Can you tell Im a little exciting my the idea? In the final analysis Im just building because I think itll help me and Im just publishing it for free to force me to wrote documentation for it (and maybe get some help with it). There very little selflessness in the process. ;^) Jim Davis [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
RE: Security with CFCs [LONG]
If you mean the eventual code then, yes, it will be made public/open source at www.DepressedPress.com (this code, along with a more generalized application framework is being developed specifically to rebuild DepressedPress.com although it will also be used on FirstNight.org, cfadvoacy.org and several other planned sites). I used to release lots of code to the public domain, but don't so much any more due to time constraints. I want to force myself to do so again simply because to ready the code for public use I have to document it - so in the end the whole process tends to help me immensely. ;^) However if you mean the explanation. well, then I have to beg off: it was hard enough getting the description I did out. ;^) Jim Davis From: Paul Kenney [mailto:[EMAIL PROTECTED] Sent: Saturday, July 17, 2004 1:10 AM To: CF-Talk Subject: Re: Security with CFCs [LONG] Is this perhaps something that could be generalized for public consumption? [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
Re: Security with CFCs [LONG]
Is this perhaps something that could be generalized for public consumption? On Fri, 16 Jul 2004 20:55:39 -0700, Dick Applebaum <[EMAIL PROTECTED]> wrote: > Jim > > How did you do that? > > You got 233 lines past Michael's 100-line filter. > > Now as to the content. > > I read through it and you present a very good case (but that's what you > do). > > I feel like here is a bit too much abstraction -- tho, I can't > specifically point to where > > I also feel (and I hardly ever use the word "feel") that this has been > done before (many times, many ways). > > You may, in fact have a breakthrough way of doing authorization, but I > got lost in the details of implementation. > > Tell me what it does & why I need it! > > Respectfully > > Dick > > [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
Re: Security with CFCs [LONG]
Jim How did you do that? You got 233 lines past Michael's 100-line filter. Now as to the content. I read through it and you present a very good case (but that's what you do). I feel like here is a bit too much abstraction -- tho, I can't specifically point to where I also feel (and I hardly ever use the word "feel") that this has been done before (many times, many ways). You may, in fact have a breakthrough way of doing authorization, but I got lost in the details of implementation. Tell me what it does & why I need it! Respectfully Dick [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
RE: Security with CFCs [LONG]
[Just reviving an old topic - thanks to Matt, Barney and Dave for setting some things straight.] Now that I've had some time to consider things (and head down about 50 dead-ends) I think I've got something good. I just wanted to run it by folks to get some opinions: My goal is to create a security system that can be applied somewhat painlessly to my web applications (it will, in the end, be an optional part of my personal implementation framework). The goals were to: 1) Build only the logical and persistence elements of the system (no presentation). That way I could customize the interface how I wanted per application. 2) Build a CFC-based (e.g object rather procedural) system. This was also to allow the system to extend several pre-built utility components I've already done. 3) The security system would not secure itself. Perhaps this is wrong, but I didn't want to make it that complicated. Instead the interface would use the security system to security "admin" type functionality - in other words such entitlement checking would be done outside the system. 4) The system should aggressively cache information for performance, but should err on the side of logical correctness rather than performance gains. 5) The system should allow for basic roles/groups entitlements. 6) The system should be flexible enough to add (later!) common security needs ("three strikes and you're out" authentications, blocked users, multiple log ins, etc) 7) The system should allow for admin/entitlement changes to be reflected immediately upon current authentications (i.e. banning somebody would take effect immediately not upon the next log in). Conceptually I've defined a few things: Group: An umbrella label for protected things/function (or sets of things/function) such as "Adminstrator", "Member", "Editor", etc. User: A virtual concept representing a person (or, I guess, something else) using the system. Each user has an associated Credential, Profile and Entitlement. Credential: User information specific to the security system (username, password hash, last login date, etc). Profile: User information not specific to the security system (name, phone number, address, etc). Entitlement: A list of groups that the user can access. Authentication: A representation of a "current log in". Contains references to the user, the session which authenticated and times of access. Considering that, this is what I've come up with (I'm only going to go over the basic components - each extends other components and has persistence-broker sub components and so forth, but I won't get into that). DP_SecurityConfiguration.CFC This CFC just contains basic installation and uninstallation routines (creation of data tables, scheduled tasks, etc). It's only used for installation (and installation). DP_Security.CFC The main entry point of the whole shebang. Contains system settings, creation/deletion methods (for users and groups), and authentication methods. Also contains the Authentications collection and the mediator (caching) components (described below). DP_Authentications.CFC A collection component for holding/managing authentications. Contains methods for retrieving specific authentications (using sessionkey) and expiring timed-out sessions. DP_Authentication.CFC Represents a current authentication and is keyed from SessionID. Contains the UserKey (which links an authentication to a user) and the ability to fetch and return that user's Credential, Profile or Entitlement from the mediators. Also contains the time of last access (used to control authentication time-outs). The authentication component could also be extended to manage a "three-strikes and you're out" rule by limited any specific session to three login attempts. DP_Credential.CFC Represents a credential. Takes a UserKey and has methods for loading and saving Credential data from the database. All system users have to have a Credential. DP_Profile.CFC Represents a profile. Takes a UserKey and has methods for loading and saving Profile data from the database. Profiles are optional (not all system users have to have a profile). So a "blank" profile can be returned. DP_Entitlement.CFC Represents an entitlement. Takes a UserKey and has methods for loading and saving Entitlement data from the database. Entitlements are optional (since not all system user have to have access to something). This also what's called to check entitlements (as in isEntitled(grouplist) ). DP_CredentialMediator.CFC All requests for Credentials will go through the CredentialMediator. It will determine if the requested Credential exists (returning an error if it doesn't) and return a reference to the component instance. The component instance will be placed in a collection cache. In this way requests for the same credential will also resu
Re: Security with CFCs
>My current thinking is that there are many functions specific to application >security - things like authenticating, adding/editing/removing groups, etc. >I've started putting them into a "DP_Security.cfc" which will be loaded as a >property of the DP_Application.cfc (I could have put them inside it, but it >was already getting a little long). This isn't a bad way to do things depending on your particular situation. If you have to do things like checking roles and other security-related stuff pretty frequently, using a single CFC for all that functionality might fit the bill. Particularly if you're doing something like putting a user CFC in your session, having another CFC that contains all your security related methods and having that interact with the user CFC in your session can work quite well. Since you said you didn't want to get too deep into design patterns, etc. I'll leave out the discussion of how you'd probably *really* want to do the interaction between the security CFC and the session user CFC ... >If a populated user's component means you've logged in, what should indicate >no log in? An empty component? A component that hasn't been inited or no >users component at all? There are any number of ways to handle this. In a recent project I used a session facade pattern for my user, and in essence this does end up creating an empty user object in the session scope if you check something like user.getEmail() and there is no object present. Depending on how you implement things you might have to do an IsDefined() on your user CFC *and* check for the existence of data like a user's role id or whatever. >Should the security system, when authenticating, return the user object or >just the UserKey and let the user object populate itself? There are numerous design patterns to help with all of this as well, but basically if you're talking about the log in process itself, what I would do it check for a valid login, get data back about that user, populate your user object, and put that in your session. Personally I'd have the security CFC (or however you implement this) either return a populated user object to the caller or just handle all the steps above itself. >In the end I want to easily say "isLoggedIn()" or "isAdmin()" or >"isEntitled()" - preferably from the session-based user component. But at >the same time it seems odd to me that a single set of DB tables has multiple >components operating on them. You might need to elaborate on this a bit. If by "from the session-based user component" you literally mean that the user CFC would have methods in it like isEntitled(), I wouldn't do that. I'd have my security CFC interact with the session user object (preferably via a facacde). In my mind the user CFC should just have information about the user, and you would do authentication, etc. via another CFC whose only job is to do those sorts of things. Hope that helps--feel free to follow up with me on any of this. I'm always very glad to see people using CFCs and OO more! Matt [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
Re: Security with CFCs
http://www.communitymx.com/abstract.cfm?cid=E4D4C [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
RE: Security with CFCs
Say I log into an application. And then open another browser and log in again. If my user object says I'm logged in, then I'll be able to identify myself as that user in the second window, and be logged in, without actually using a password. Same goes for Joe Hacker over in CountryXYZ. As soon as I log on, and he can identify himself as me, he's acting as me. So clearly we don't want to log users onto the system. Rather, we want to log browser windows onto the system, on behalf of a user. So I log in with my first window, and then try the second. I identify myself as me, but the system says "yeah, prove it. You might have logged on over there, but not here." Much better, and poor Joe Hacker is outta luck. Moral of the story? Don't log users in, log sessions in, and associate each session with both a user, and an identifiable single point of access. Usually done with a session instance of a user CFC and a cookie. To get to the real answer you're looking for, you don't want to have anything about authentication in your user component, you need a separate object (or perhaps even a boolean and a numeric field in the session scope). Now, on to authorization. I'm logged in, and want to perform the "Edit User" task on the system. Who are you going to ask if I've got permission? Certainly not me, I hope, because I'll obviously say "yes". I probably know whether I can do the action or not, but I'm a stinkin' liar. Rather, you should ask the security system, if user 'barneyb' has permission to do the "Edit Users" task. The security system is objective, and tied very closely to the database, unlike myself, who in addition to being a liar, could well have data that's an hour or three old, because I was given my specs when I logged in. If you have a dedicated security system, you get the added benefit of being able to cache data fairly aggressively. If all DB queries and updates go through you, then you can rest assured keeping some data in memory for faster access is OK, because nothing is going to manipulate the database without you knowing. Heavy caching is of particular benefit to security info, because it's often stored in a very distributed form, across many tables, and is needed on every request, almost always multiple times per request. To sum up, authentication is independent of users, because users can have zero to N sessions, and each session needs to be independent. Authorization is not a user task, it's a system task. Users can probably tell you about their various authorization levels, but they're not the authority. I don't use a separate authorization component (at least not that the controller can see), I put the methods directly into the service component that is used for managing the credentials. Nice consolidated package, and since it's that way, I can cache to my hearts content. It's late, I'm tired; sorry for the storytelling and longwindedness. Cheers, barneyb > -Original Message- > From: Jim Davis [mailto:[EMAIL PROTECTED] > Sent: Monday, June 28, 2004 8:41 PM > To: CF-Talk > Subject: Security with CFCs > > I know, old topic, but I'm currently converting my old CF > 4.5/5.0 framework > (which actually began with v3.x and has been updated ever since - so a > complete overhaul is long overdue) to a object-leaning > CFC-based setup. > > Note I say "object leaning" because I'm not trying to > recreate any major > pattern or do everything in OO - I'm trying to keep the best > aspects of > procedural code, but move the foundational elements into > CFCs. So far it's > been going great - I'm extremely pleased with what I've got so far. > > Basically there are now a bunch of CFCs: three of them mirror > CF's view of > the world so I've got a DP_Application.cfc (application > settings, DSNs, > etc), DP_Session.cfc (Session information) and a DP_Request.cfc > (page/request specific stuff like current paths and > settings). I've also > done CFCs (and DAO components) for Clickstreaming, Agent (browser) > Information and Navigation. > > Like I said - so far I'm very pleased. > > But now I'm trying to convert my security system over. The > data-side of the > system is as simple as can be. The usual three tables: > Users, Groups and > Users2Groups. In the users table I've got a number of fields > for use with > the security system itself (password hash, userID, login > dates, number of > logins, etc) and a very large number of fields to cover > personal information > (name, various addresses and phone numbers, IM IDs, email > preferences, etc). > > As you can guess each page can be restricted to certain > groups, users can > belong to multiple groups, etc. > > Anyway - what I'm trying to do now is determine how to do > convert security. > Anybody done this and want to share? > > My current thinking is that there are many functions specific > to application > security - things like authenticating, > adding/editing/removing groups, etc. > I've s