And likewise for individual sections. Yes, if they only have read
permissions, simply put a wrapper around elements which would allow them to
submit.

On Wed, Jan 12, 2011 at 11:10 AM, Jason King <[email protected]> wrote:

> 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