Why not just wrap the entire page or content section in an IF/THEN that
queries the member permissions if they can view it or not? If pass, then
view, if not, then "permission denied"?

That's how I'm doing my app.



On Wed, Jan 12, 2011 at 11:08 AM, 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 style="text-align:center;">#iX#</td>
> > <td style="text-align:center;">[#binaryByte#]</td>
> > <td style="text-align:center;">#InputBaseN(binaryByte,2)#</td>
> > <td style="text-align:center;">#FormatBaseN(InputBaseN(binaryByte,2),
> > 16)#</td>
> > </tr>
> > </cfoutput>
> > <!--- loop through the rest of the possible byte values --->
> > </cfloop>
> > <!--- end the table --->
> > </table>
> > <br>
> > <br>
> > <!--- dump the structure --->
> > <h1>The structure</h1>
> > <cfdump var="#thisStruct#">
> > <br>
> > <br>
> > <h1>The Test Case</h1>
> > <p>In this test case we are going to add existing members of the
> > structure (bytes) together. By adding these bytes together and then
> > converting back to base 2 (binary) output you will see how multiple
> > levels could be assigned to the same user.</p>
> > <!--- create a test case by adding together random bits from the 31
> > bytes created and stored in the structure --->
> > <cfset testCase = InputBaseN(structFind(thisStruct, 'this11'),2) +
> > InputBaseN(structFind(thisStruct, 'this16'),2) +
> > InputBaseN(structFind(thisStruct, 'this19'),2) +
> > InputBaseN(structFind(thisStruct, 'this2'),2)>
> > <!--- initialize an output string --->
> > <cfset testCaseOutput = "">
> > <!--- loop through the missing begining (left) zero bit's --->
> > <cfloop from="1" to="#32-Len(FormatBaseN(testCase,2))#" index="iX">
> > <!--- add the missing zero bits --->
> > <cfset testCaseOutput = testCaseOutput & '0'>
> > <!--- loop through the rest of the zero bit's --->
> > </cfloop>
> > <!--- set the output string to the zero's concantenated with the
> > binary output of the test case --->
> > <cfset testCaseOutput = testCaseOutput & FormatBaseN(testCase,2)>
> > <!--- initalize a role list to capture the role names --->
> > <cfset roleList = "">
> > <table cellpadding="2" cellspacing="0">
> > <tr>
> > <th style="text-align:center;">Test Case Binary</th>
> > <th style="text-align:center;">Test Case Decimal</th>
> > <th style="text-align:center;">Current Bit Binary</th>
> > <th style="text-align:center;">Current Bit Decimal</th>
> > <th style="text-align:center;">Result</th>
> > </tr>
> > <tr style="background-color:#FFDDDD;">
> > <td style="text-align:center;">[
> > <cfoutput>#testCaseOutput#</cfoutput>
> > ]</td>
> > <td style="text-align:center;"><cfoutput>#testCase#</cfoutput></td>
> > <td style="text-align:center;">[
> > <cfoutput>#structFind(thisStruct, 'this0')#</cfoutput>
> > ]</td>
> > <td style="text-
> > align:center;"><cfoutput>#InputBaseN(structFind(thisStruct, 'this0'),
> > 2)#</cfoutput></td>
> > <td style="text-align:center;">False</td>
> > </tr>
> > <!--- loop through the 31 bytes in the structure --->
> > <cfloop from="1" to="31" index="iX">
> > <!--- output the current test byte itteration (iX) information --->
> > <cfoutput>
> > <!--- perform BitAnd against the current byte (iX) and the testCase
> > byte --->
> > <cfif BitAnd(InputBaseN(structFind(thisStruct, 'this#iX#'),
> > 2),testCase)>
> > <!--- if BitAnd returns true, then the bit represented by the current
> > byte (iX) is present in the testCase byte --->
> > <tr style="background-color:##BBFFBB;">
> > <td style="text-align:center; border-left:1px solid ##000000; border-
> > top:1px solid ##000000; border-bottom:1px solid
> > ##000000;">[#testCaseOutput#]</td>
> > <td style="text-align:center; border-top:1px solid ##000000; border-
> > bottom:1px solid ##000000;">#testCase#</td>
> > <td style="text-align:center; border-top:1px solid ##000000; border-
> > bottom:1px solid ##000000;">[#structFind(thisStruct, 'this#iX#')#]</
> > td>
> > <td style="text-align:center; border-top:1px solid ##000000; border-
> > bottom:1px solid ##000000;">#InputBaseN(structFind(thisStruct,
> > 'this#iX#'),2)#</td>
> > <td style="text-align:center; border-top:1px solid ##000000; border-
> > bottom:1px solid ##000000; border-right:1px solid ##000000;">True</td>
> > </tr>
> > <!--- set the value of this byte in the role list --->
> > <cfset roleList = ListAppend(roleList,structFind(thisStruct,
> > 'this#iX#'))>
> > <!--- otherwise, BitAnd returned false, so the bit represented by the
> > current byte (iX) is *not* present in the testCase byte --->
> > <cfelse>
> > <tr style="background-color:##FFDDDD;">
> > <td style="text-align:center;">[#testCaseOutput#]</td>
> > <td style="text-align:center;">#testCase#</td>
> > <td style="text-align:center;">[#structFind(thisStruct, 'this#iX#')#]</
> > td>
> > <td style="text-align:center;">#InputBaseN(structFind(thisStruct,
> > 'this#iX#'),2)#</td>
> > <td style="text-align:center;">False</td>
> > </tr>
> > </cfif>
> > <!--- end checking current test byte --->
> > </cfoutput>
> > <!--- loop through to the next byte --->
> > </cfloop>
> > </table>
> > <br>
> > <br>
> > <h1>The result</h1>
> > <p>Listed below are the binary roles detected by the BitAnd checking
> > routine.</p>
> > <!--- output the roles randomly picked --->
> > <cfoutput>#roleList#</cfoutput>
> >
> > This is all, of course, subjective and there are a number of different
> > ways to handle authentication, session management and access control
> > in ColdFusion - this is one way. I never use the <cflogin> functions
> > myself so I'm not sure if they're even supported in OpenBD, but if it
> > is then that is another option for the authentication and session
> > management - access control is still up to one of the two methods I
> > suggested, though IsUserInRole() lends itself to the non-bit based,
> > textual approach which I find to be utterly and painfully slow so I
> > almost always use positional math based access controls for speed. But
> > then almost every application I write is chock full of encryption and
> > decryption so every millisecond I can squeeze out of my apps the
> > better ;)
> >
> > Anyway, I hope this answers your question, and if not, just shoot some
> > more specific feedback on what you're trying to accomplish and I'll
> > see if I can't help more ;)
> >
> > -- Denny
> >
> > On Jan 11, 4:21 pm, Skellington <[email protected]> wrote:> Hello,
> > > I'm working on a new application and I dont want to re-invent the
> > > wheel here. I would like to do access control in my application but
> > > I'm not sure how to handle this? Meaning, do I just create a group in
> > > a database table and add users to and then use "if" statements to do
> > > filtering or is there a cfc or plugin that helps with something like
> > > this?
> >
> > > Thanks,
> > > Charlie
>
> --
> 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

Reply via email to