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
