我有一个启用了远程访问的CFC文件,我使用它来执行各种管理任务,例如从数据库添加/删除图像记录。对此CFC的调用是通过我的管理页面上的自定义JavaScript通过AJAX进行的。我将CFC放在我认为是安全目录的地方,但是有一些问题,图像自动消失,我发现它根本不安全。
我想获得CFC。我已经使用基于会话的安全CFC用于管理页面,并且每次请求一个管理页面时都会调用其保护方法,如果身份验证失败,则会重定向用户。我可以在我的CFC上使用这个吗?如果是这样,实施它的最佳方法是什么?如果没有,我该如何实现安全性呢?
以下是我的CFC示例:
<cfcomponent
name="test"
displayname="test"
output="false"
hint="test"
>
<!--- pseudo constructor --->
<cfscript>
variables.propertyImageDAO = CreateObject("component","cfcs.dataobjects.property_imageDAO").init(APPLICATION.dsn);
variables.propertyImageGateway = CreateObject("component","cfcs.dataobjects.property_imageGateway").init(APPLICATION.dsn);
</cfscript>
<!--- constructor --->
<cffunction name="init" access="public" output="false" returntype="any"
hint="Constructor for this CFC">
<!--- return this CFC --->
<cfreturn this />
</cffunction>
<!--- CRUD methods (create, read, update, delete) --->
<!--- CREATE: inserts a new property_image into the database --->
<cffunction name="createRecord" access="remote" output="true"
hint="Creates a new property_image record and returns a struct containing a boolean (success) indicating the success or
failure of the operation, an id (id), and a string (message) containing a message"
>
<cfargument name="name" type="any" required="false" default="" />
<cfargument name="alt" type="any" required="true" />
<!--- initialize variables --->
<cfset var results = StructNew() />
<!--- create property bean --->
<cfscript>
var propertyImageBean = CreateObject("component","cfcs.beans.property_image").init(
'',
arguments.name,
arguments.alt
);
results = propertyImageDAO.createRecord(propertyImageBean);
</cfscript>
<!--- return the struct --->
<cfoutput>#SerializeJSON(results)#</cfoutput>
</cffunction>
<!--- READ: reads a property_image from the database and populates the property_image object --->
<cffunction name="readRecord" access="remote" output="true" returntype="void"
hint="Reads property_image data from the database and returns a JSON">
<!--- take property_image bean as argument --->
<cfargument name="id" type="numeric" required="true" />
<!--- initialize variables --->
<cfset var results = StructNew() />
<!--- create property bean --->
<cfscript>
propertyImageBean = CreateObject("component","cfcs.beans.property_image");
propertyImageBean.setid(arguments.id);
propertyImageDAO.readRecord(propertyImageBean);
</cfscript>
<!--- return the struct --->
<cfoutput>#SerializeJSON(propertyImageBean)#</cfoutput>
</cffunction>
<!--- DELETE: reads a property_image from the database and populates the property_image object --->
<cffunction name="deleteRecord" access="remote" output="true" returntype="void"
hint="Reads property_image data from the database and returns a JSON">
<!--- take property_image bean as argument --->
<cfargument name="id" type="numeric" required="true" />
<!--- initialize variables --->
<cfset var results = StructNew() />
<!--- create property bean --->
<cfscript>
results = propertyImageDAO.deleteRecordById(arguments.id);
</cfscript>
<!--- return the struct --->
<cfoutput>#SerializeJSON(results)#</cfoutput>
</cffunction>
<!--- DELETERECORDS: deletes a property_image from the database --->
<cffunction name="deleteRecords" access="remote" output="true" returntype="void"
hint="Deletes property_image data from the database and returns a JSON">
<!--- take property_image bean as argument --->
<cfargument name="imageIdList" type="string" required="true" />
<!--- initialize variables --->
<cfset var results = StructNew() />
<!--- delete DB records --->
<cfscript>
results = propertyImageDAO.deleteRecordsByIdList(arguments.imageIdList);
</cfscript>
<!--- delete files --->
<!--- return the struct --->
<cfoutput>#SerializeJSON(results)#</cfoutput>
</cffunction>
<!--- DELETERECORDS: reads a property_image from the database and populates the property_image object --->
<cffunction name="deleteRecordById" access="remote" output="true" returntype="void"
hint="Deletes property_image data from the database and returns a JSON">
<!--- take property_image bean as argument --->
<cfargument name="id" type="numeric" required="true" />
<!--- initialize variables --->
<cfset var results = StructNew() />
<!--- delete DB records --->
<cfscript>
results = propertyImageDAO.deleteRecordById(arguments.id);
</cfscript>
<!--- delete files --->
<!--- return the struct --->
<cfoutput>#SerializeJSON(results)#</cfoutput>
</cffunction>
<!--- DELETERECORDSBYIDLIST: reads a property_image from the database and populates the property_image object --->
<cffunction name="deleteRecordsByIdList" access="remote" output="true" returntype="void"
hint="Deletes property_image data from the database and returns a JSON">
<!--- take property_image bean as argument --->
<cfargument name="imageIdList" type="string" required="true" />
<!--- initialize variables --->
<cfset var results = StructNew() />
<!--- delete DB records --->
<cfscript>
results = propertyImageDAO.deleteRecordsByIdList(arguments.imageIdList);
</cfscript>
<!--- return the struct --->
<cfoutput>#SerializeJSON(results)#</cfoutput>
</cffunction>
<cffunction name="deleteImagesByNameList" access="remote" output="true" returntype="void"
hint="Deletes property_image data from the database and returns a JSON">
<!--- take property_image bean as argument --->
<cfargument name="imageNameList" type="string" required="true" />
<!--- initialize variables --->
<cfset var results = StructNew() />
<!--- delete DB records --->
<cfscript>
results = propertyImageDAO.deleteImagesByNameList(arguments.imageNameList);
</cfscript>
<!--- return the struct --->
<cfoutput>#SerializeJSON(results)#</cfoutput>
</cffunction>
<!--- READ: reads a property_image from the database and populates the property_image object --->
<cffunction name="getByIdList" access="remote" output="true" returntype="void"
hint="Reads property_image data from the database and returns a JSON">
<!--- take property_image bean as argument --->
<cfargument name="imageIdList" type="string" required="true" />
<!--- initialize variables --->
<cfset var results = StructNew() />
<!--- create property bean --->
<cfscript>
qGetByIdList = propertyImageGateway.getByIdList(arguments.imageIdList);
</cfscript>
<!--- convert into JSON friendly format --->
<cfif qGetByIdList.recordCount GT 0>
<cfset images = ArrayNew(1)>
<cfloop query="qGetByIdList" startRow="1" endRow="#qGetByIdList.recordCount#">
<cfscript>
// create image struct and assign values
image = StructNew();
image.id = id;
image.name = name;
image.alt = alt;
// append to JSON response
ArrayAppend(images,image);
</cfscript>
</cfloop>
<cfset results.images = images>
</cfif>
<cfoutput>#SerializeJSON(results)#</cfoutput>
</cffunction>
<!--- READ: reads a property_image from the database and populates the property_image object --->
<cffunction name="updateRecord" access="remote" output="true" returntype="void"
hint="Reads property_image data from the database and returns a JSON">
<!--- take property_image bean as argument --->
<cfargument name="id" type="numeric" required="true" />
<cfargument name="name" type="any" required="true" />
<cfargument name="alt" type="any" required="true" />
<!--- initialize variables --->
<cfset var results = StructNew() />
<!--- create property bean --->
<cfscript>
propertyImageBean = CreateObject("component","cfcs.beans.property_image").init(
arguments.id,
arguments.name,
arguments.alt
);
results = propertyImageDAO.updateRecord(propertyImageBean);
</cfscript>
<!--- return the struct --->
<cfoutput>#SerializeJSON(results)#</cfoutput>
</cffunction>
答案 0 :(得分:1)
要强制执行您的身份验证逻辑,您应该使用此逻辑将Application.cfc中的所有远程CFC调用包装起来。
不幸的是,您使用的是CF8,因此无法使用Application.cfc的onCFCRequest
方法轻松包装所有远程请求。但是,您可以通过检查目标网页是否以onRequestStart
结尾来在'.cfc'
中执行相同的操作。
<cffunction name="onRequestStart">
<cfargment name="targetPage">
<cfif right(targetPage, 4) eq '.cfc'>
<!--- Perform authentication check --->
<cfif not loggedIn>
<!--- Return "unauthorized" to the client --->
<cfheader statuscode="401">
<cfabort>
</cfif>
</cfif>
</cffunction>
然后,在您的Ajax fail
处理程序中,检查401状态代码并向用户显示一条消息,指示需要登录。
答案 1 :(得分:0)
为什么不在每次进行ajax调用时都使用会话令牌。
答案 2 :(得分:0)
将您的身份验证逻辑(验证会话)放入远程外观,或者如果您使用任何MVC框架,请将身份验证逻辑放在控制器层上。
如果会话验证失败,则返回相应的HTTP状态代码(例如403),以便前端代码能够做出适当的反应。