Thanks, I had a feeling so it's good to get a confirmation.
Charlie Sent from my iPad On Jan 13, 2011, at 11:39 AM, Denard Springle <[email protected]> wrote: > Hey Charlie, > > Yeah, LDAP and LDAP into AD are slightly different animals > depending on what you're wanting to do. For example, if you're wanting > to set roles in your system based on membership to Groups within AD > (or any LDAP for that matter) or if you're going to assign roles in > your own database, but it sounds like you've got all that worked out > already. > > As for how common it is to wrap elements of a page in access > control logic, the answer is that it is quite common practice, however > I will extend one caveat to your question, and application design in > general, which is that access controls should limit what a user can > see to only what he/she needs to see. Best practice in your case > suggests that you would not just hide the 'submit' button, for > instance, but instead would hide the entire form since they can't > submit it anyway and exposing the form to users who can't submit it > via your website leaves a surface area that can be attacked easily - > someone can view the source of your page and would be able to submit > the form by creating their own page with all the right fields (and > their own submit button or other submission process e.g. <cfhttp> > comes to mind) which posts to your form on your URL from some other > web server, for example. In the case that the page containing the form > is only a form, then you should limit both the entire page itself from > view by those without proper access, which can be done with a stern > 'You don't belong here' message or an automated redirect back to a > safe page (the index.cfm, for example), as well as any exposure to > links or other automated processes within your application that would > take a user without access to said page(s). It all depends on what > you're trying to accomplish, of course, but being an old linux guy I > tend to take the 'lockdown everything' method of access control where > I limit exposure of forms, elements, pages and directories that > involve processes that a specific user (or groups of users as is > usually the case) shouldn't have rights to use... in various > implementations as appropriate to whatever context I'm working in. > > I guess that's a long way of saying 'yes'. :) > > As for modules/methods to handle access control, and easy method is > to use a roll your own component that takes a list of roles allowed > access to the page/element/process as one argument, and a list of > roles assigned to the user as a second argument, and then parses both > lists for a match, returning true if any roles match, and false if > not. Then, you can simply call your component anywhere in your site > using <cfinvoke> or CreateObject (or any of the other methods of > invocation) and test the returned variable (let's say we call it > 'isAllowed') for true or false. e.g. <cfif isAllowed>... content > viweable only by users with access control <cfelse>... content > viewable by those without roles (e.g. a stern warning, redirect to > another page) or simply an ending </cfif> if no content should be > displayed to those without access. > > 'Content' can mean any element on a page, any group of elements on a > page, an entire page, etc. and is used here very loosely ;) > > -- Denny > > > > On Jan 12, 12:08 pm, Skellington <[email protected]> wrote: >> Denny, >> Wow, a lot more than I thought I would get, thanks. >> >> So a little more background. I'm trying to retrofit my current app to >> add some sort or Role Based access to different sections of the site. >> Right now I'm using Application.cfm and SessionManagment with a form >> based login that does a cfldap query to our active directory >> environment to validate the user logging in. While all of this works >> very well the data in the app/site is all ready only, for the most >> part. I guess my real question is, is it common to just use if >> statements to filter access to a page? For example if a user has read >> only to a page with a form, do I wrap the submit button in a if >> statement and check to see if they have edit access, if so allow them >> to submit? >> >> Sorry, if this response seems like I'm rambling :-) I have had my >> coffee yet. >> >> Thanks, >> Charlie >> >> On Jan 12, 6:06 am, Denard Springle <[email protected]> wrote: >> >>> Hey Charlie, >> >>> There are a number of ways to implement access controls in CFML >>> depending on your needs. I'm not clear what the scope of your project >>> is or what you're trying to accomplish but I can offer some >>> assistance... >> >>> You're going to need a few basic pieces to implement >>> authentication, session management and access control. Assuming you >>> haven't done the authentication piece yet, you'll need the following: >> >>> 1. A sign-up form and/or admin form for adding users to a user >>> database table so they can later authenticate against the stored >>> information. >>> 1a. A password reset and change password form and functions are also >>> recommended. >>> 1b. System generated random passwords for initial sign-up/adding of >>> users and password resets is strongly recommended. >> >>> 2. A FORM that gathers the username and password of the user and >>> submit to a processor page (can be the same page) >> >>> 3. A user database table to store the login information for your >>> clients, something along the lines of: >> >>> id int auto-increment >>> username varchar(255) not null >>> password varchar(255) not null >>> last_on datetime >> >>> 3a. NOTE: Use Hash() on your passwords and encrypt passwords and >>> usernames before storing them in the database. Use a javascript Hash() >>> routine on your login form to hash your users passwords before they >>> are sent to the browser. >>> 4. A processor that looks for the (encrypted) username and (hashed and >>> encrypted) password submitted by the user from the user database table >>> 4a. If there is a match, then you kick into session management and >>> access controls >> >>> 5. Session Management can be handled by the combination of either >>> SESSION scoped variables (be sure to <cflock> them when you set them >>> to prevent race conditions) or a COOKIE and another database table to >>> manage sessions, something along the lines of: >> >>> id int auto-increment >>> session_id varchar(255) not null >>> user_id varchar(255) not null >>> last_action datetime not null >> >>> 5a. NOTE: Generate a session id with CreateUUID() or another random >>> pattern generator, encrypt the session id and user id before storing >>> in the database. >>> 5b. Encrypt your encrypted session id (pref using a diff algorithm) >>> and then use that value as either your SESSION scoped variable value >>> or your COOKIE value >> >>> 6. Application.cfc session management is suggested. This is done by >>> having an OnRequestStart block that, if within a specific path >>> (CGI.PATH_INFO) of the site usually, reads in the SESSION scoped >>> variable or COOKIE on each request, compares the time of the last >>> request to some timeout period you've set as an APPLICATION variable >>> in the Application.cfc and the current time (e.g. if 15 minutes have >>> passed since the last user action on the site, for example) and then >>> either refreshes the session by updating the last_action field in the >>> session database table (if 15 minutes have not passed) or return them >>> to the login page (if 15 minutes have passed) with a 'session timeout' >>> message, and if you're crafty about it, the ability to return the user >>> to the page he was visiting before the session times out. >> >>> 7. Access Control is a means of limiting already authenticated users >>> to specific areas or specific content on your website. For example, an >>> average CMS site might have authors, content reviewers and moderators >>> each representing different abilities and access to different parts of >>> the average CMS backend. Authors would be able to write and modify >>> articles, content reviewers would be able to write, modify and publish >>> articles and moderators may simply only be able to approve content for >>> publishing, for examples. This type of access control can be >>> implemented in one of two standard ways, as follows: >> >>> 7a. Roles - you can either add another table to your database to >>> manage the role/user relationship, or you can use a list based >>> approach with a single field added to your users table called roles, >>> either one works and simply depends on preference and code required. >>> In both cases, you have to either have another table the represents >>> the relationship between pages or content on your site and the allowed >>> Roles able to access them - which is handled in a similar way to >>> handling user roles - either as a relationship table (page/role) or as >>> a list of allowed roles referencing one page (page/roles), or can be >>> hard coded into each page you wish to check (e.g. <cfif >>> Find(qGetUser.Roles,'Author')> ... allowed access content </cfif>). >> >>> 7b. In the event that you wish to assign multiple roles to the same >>> user, there is a mathematical way to handle this which is much quicker >>> than textual Roles and allows for a much smaller footprint in your >>> database. It is, however, slightly more complicated and complex. The >>> easiest way to explain it is with a bit of code I wrote to illustrate >>> that capabilities of using positional math with a single 32-bit byte >>> to assign (up to) 32 roles to a single user with one byte. 64-bit >>> systems running 64-bit CF can also handle 64-bit bytes quickly (32-bit >>> CF can also do 64-bit positional math, but it requires two processor >>> cycles), allowing for up to 64 roles to a single user in a single >>> byte. >> >>> <!--- >>> Name: using_bit_based_access_control.cfm >>> Author: Denard Springle ( [email protected] ) >>> Description: Demonstrate using binary objects and bit manipulation >>> Created: 05/06/2009 >>> License: Creative Commons Attribution-Non Commercial 3.0 >>> ---> >>> <!--- initialize a string to hold the binary representation of our 32- >>> bit zero byte ---> >>> <cfset zeroByte = ""> >>> <!--- initialize the zero byte ---> >>> <cfset zeroByte = RepeatString('0',32)> >>> <!--- set up a row color variable to alternate colors ---> >>> <cfset rC = 0> >>> <!--- set up a table to output the progress and results of this >>> operation ---> >>> <h1>32 Bit Combinations</h1> >>> <p>The following table represents the 32 bit positions available in a >>> 32-bit byte. By using these positions you can assign up to 32 access >>> control levels to the same user without depending on role lists (i.e. >>> IsUserInRole() style). Storage and processing of a single 32-bit byte >>> is demonstrated here in it's most basic form for easy digestion, >>> however the use of single 32-bit byte is an optimal mathmatic >>> calculation and storage method for tiered access controls.</p> >>> <table cellpadding="2" cellspacing="0" width="50%"> >>> <tr> >>> <th style="text-align:center;">Bit Pos</th> >>> <th style="text-align:center;">Bin Val</th> >>> <th style="text-align:center;">Dec Val</th> >>> <th style="text-align:center;">Hex Val</th> >>> </tr> >>> <!--- set up the first row (of zero's) ---> >>> <tr style="background-color:#FFFFEE;"> >>> <td style="text-align:center;">0</td> >>> <td style="text-align:center;">[ >>> <cfoutput>#zeroByte#</cfoutput> >>> ]</td> >>> <td style="text-align:center;">0</td> >>> <td style="text-align:center;">0</td> >>> </tr> >>> <!--- create a new structure to hold the access controls ---> >>> <cfset thisStruct = StructNew()> >>> <!--- put the zero byte in the structure (for later use) ---> >>> <cfset structInsert(thisStruct, 'this0', zeroByte)> >>> <!--- loop through the 31 assignable bits (e.g. excluding zero [0]) --- >> >>> <cfloop from="1" to="31" index="iX"> >>> <!--- initialize a string to hold the binary representation of our 32- >>> bit byte ---> >>> <cfset binaryByte = ""> >>> <!--- set the current column to 32 bits minus the current index of iX, >>> so, bit 31, 30, 29, etc. ---> >>> <cfset thisCol = 32-iX> >>> <!--- loop through the zero bits which make up the beginning (left) of >>> this byte (e.g. thisCol value) ---> >>> <cfloop from="1" to="#thisCol#" index="iY"> >>> <!--- add this bit positions false (0) bit to the byte string ---> >>> <cfset binaryByte = binaryByte & '0'> >>> <!--- loop through the remaining begininng (left) bit positions that >>> are zero ---> >>> </cfloop> >>> <!--- add this bit positions true (1) bit ---> >>> <cfset binaryByte = binaryByte & '1'> >>> <!--- init remaining columns ---> >>> <cfset newCol = 32-(thisCol+1)> >>> <!--- check if we're at the last element in the list ---> >>> <cfif newCol GT 0> >>> <!--- loop through and pad the right with zero (0) ---> >>> <cfloop from="1" to="#newCol#" index="iZ"> >>> <!--- add a zero (1) to the binary string ---> >>> <cfset binaryByte = binaryByte & '0'> >>> <!--- loop through the rest of the padded zero's ---> >>> </cfloop> >>> <!--- end checking if we're at the last element ---> >>> </cfif> >>> <!--- put this byte in the structure (for later use) ---> >>> <cfset structInsert(thisStruct, 'this#iX#', binaryByte)> >>> <cfif rC EQ 0> >>> <cfset rowCol = "##DDDDEE"> >>> <cfset rC = 1> >>> <cfelse> >>> <cfset rowCol = "##FFFFEE"> >>> <cfset rC = 0> >>> </cfif> >>> <!--- output the current bit position and byte values to the screen --- >> >>> <cfoutput> >>> <tr style="background-color:#rowCol#;"> >>> <td >> >> ... >> >> read more ยป > > -- > Open BlueDragon Public Mailing List > http://www.openbluedragon.org/ http://twitter.com/OpenBlueDragon > official manual: http://www.openbluedragon.org/manual/ > Ready2Run CFML http://www.openbluedragon.org/openbdjam/ > > mailing list - http://groups.google.com/group/openbd?hl=en -- Open BlueDragon Public Mailing List http://www.openbluedragon.org/ http://twitter.com/OpenBlueDragon official manual: http://www.openbluedragon.org/manual/ Ready2Run CFML http://www.openbluedragon.org/openbdjam/ mailing list - http://groups.google.com/group/openbd?hl=en
