2

从 CF8 升级到 CF10,移动所有文件和数据库并跳过所有配置箍后,新版本的站点启动并运行,但身份验证/登录不起作用。

以下是环境:

旧服务器: ColdFusion Enterprise 8,0,1,195765

操作系统:Windows Vista*

操作系统版本:6.0

更新级别:.... hf801-00007.jar

IIS 版本:7

(*不确定“Vista”来自哪里?系统信息显示“Windows Server 2008 Datacenter without Hyper-V”)

新服务器: ColdFusion Enterprise 10,0,11,285437

Tomcat 版本:7.0.23.0

操作系统:Windows Server 2008 R2

操作系统版本:6.1

更新级别:....chf10000011.jar

Adobe 驱动程序版本:4.1(内部版本 0001)

IIS 版本:7.5

我有一个非常标准的 ColdFusion 登录系统,在 Application.cfc 中使用cfloginuser。在我登录旧站点后,输出#GetAuthUser()#会将我的用户名打印到屏幕上,并且我所有基于角色的规则都有效。

在新服务器上,输出 GetAuthUser() 打印为空。

在旧网站上,cfdump var="#SESSION#"包括:

cfauthorization_kllcms dXNlcm5hbWU6cGFzc3dvcmQ6YXBwX25hbWU= 

在新站点上,CFDUMPof session 根本不显示任何cfauthorization_kllcms值。所有其他会话值都存在于两个实例中。

它是完全相同的代码库、数据库结构等。当然,我的基于角色的规则都不起作用,因为它们都依赖于对 getAuthUser() 和 IsUserInRole("x") 条件的验证。

我知道初始登录过程本身正在运行,因为它使用用户信息正确设置会话变量,并且它们可用于后续请求。但是在后续调用中没有任何传统的 cflogin 数据可用。

有什么想法可能会改变吗?

更新:根据亚当的建议(如下),我设置了 2 个测试应用程序,一个在旧服务器上,一个在新服务器上。

旧服务器: http ://cfloginold.cimhost.com/index.cfm

新服务器: http ://cflogin.cimhost.com/index.cfm

使用“test”和“demo982013”​​作为用户名和密码。

附加?logout=true到 URL 以注销并重新测试。这两个应用程序具有完全相同的代码、相同的数据库。我将会话和表单值连同GetAuthUser()值一起转储到屏幕上。

身份验证方法与Adob​​e 文档中概述的几乎完全相同,如有必要,我可以在此处分享所有相关代码。

请注意,在“新”服务器中,每次访问页面时都会加载表单,无论您是否已登录。这是cflogin会话没有被保留或识别的例子,因此每次访问都会显示登录表单(尽管不是在初始表单完成时,这表明 cflogin 至少在初始登录上工作,我认为)。

更新 2: 我一直在深入研究这一点,我能够让 cfloginuser 以几种方式触发,只是不是作为标准Adob​​e 记录的基于应用程序的用户安全模型的一部分。

选项 1:我创建了一个独立页面,并在其中放置了以下代码:

<cflogin><cfloginuser name="directtest" Password = "2519D6025B5191F754D01BE163972628" roles="1"></cflogin>

然后我指示 Application.cfc 允许它通过cflogin大门。您可以通过将浏览器指向以下网址来查看结果:http ://cflogin.cimhost.com/directlogin.cfm?bypass=true

瞧。'cfauthorization_cicmstest' 值已设置,用户已登录。后续调用GetAuthUser()成功。所以我现在知道 CF10 和应用程序确实允许 cfloginuser,并且可以创建用户会话。

选项 2:然后我决定这可能与我的 Application.cfc 文件有关,所以我再次绕过cflogin门,将硬编码cfloginuser片段直接放在我的 Application.cfconRequestStart函数中。登出并访问:http ://cflogin.cimhost.com/index.cfm?bypass=true&noquery=true

同样,cfauthorization_cicmstest值已成功设置,并且用户已登录。

cfloginuser但是,如果在 Application.cfc中的实际cflogin进程中触发指令,登录仍然会失败。这是该代码的样子:

        <cfquery name="loginQuery" dataSource="mydatasource">
        SELECT id,username, userroles
        FROM myusertable
        WHERE
           username = '#cflogin.name#'
           AND userpass = '#HASH(cflogin.password)#'
        </cfquery>
        <cfif loginQuery.userroles NEQ "">
           <cfloginuser name="#cflogin.name#" Password="#cflogin.password#" roles="#loginQuery.userroles#">
           <cfset MyMessage = "#MyMessage#<br />The Login Query fired and returned expected - loginQuery.userroles NEQ ''">

        <cfelse>
           <CFSET MyMessage = "Your login information is not valid. <a href='index.cfm?logout=1'>If your session timed out, click here!</a>">   
           <cfinclude template="loginform.cfm">
           <cfabort>
        </cfif>

我知道查询是成功的,因为我正在设置一条警报消息,告诉我该loginquery.userroles值不为空,这是处理的条件cfloginuser

我知道代码现在哪里失败了,只是不知道为什么。我已经尝试对该值进行硬编码,cfloginuser但仍然失败。我不知道下一步该尝试什么。该cfloginuser功能有效,只是不在loginQuery.userroles我需要它工作的一个地方(在条件内)。

更新 3:

为了向自己证明这不是我的代码,我又创建了 2 个测试站点,一个在旧服务器上,一个在新服务器上:

新服务器 (CF10) = http://cf10loginadobe.cimhost.com/securitytest.cfm

旧服务器 (CF8) = http://cf8loginadobe.cimhost.com/securitytest.cfm

我从他们的基于应用程序的安全示例中准确复制了Adob​​e 的 3 个文件。我用它们的模式和值创建了一个数据库表。我添加了cfdump输出以显示正在创建的会话。

使用“Bob”用户和“secret”密码进行测试。即使使用 Adob​​e 自己的代码,CF10 上的测试也会失败。

我不确定下一步该怎么做。将应用程序重写为不使用cfloginuser不是一种选择,因为我们有十几个应用程序正在迁移到使用此身份验证模型的 CF10,它们跨越数百个模板。

cfloginuserIIS7.5 处理 ColdFusion 请求的方式可能有些奇怪,但考虑到在条件查询结果之外成功实例化的能力,这似乎不太可能。

4

1 回答 1

1

ColdFusion 10 基于应用程序的用户安全性被破坏

我已经部署了两个测试站点,使用Adob​​e 自己的基于应用程序的用户安全示例代码,全部从 Adob​​e 网站复制。一个测试站点在 ColdFusion 8 中,一个是 ColdFusion 10。两个站点上的代码和数据库相同。我添加了cfdump输出来监视会话变量和设置的登录状态。

测试站点 ColdFusion 8: http ://cf8loginadobe.cimhost.com/securitytest.cfm

测试站点 ColdFusion 10: http ://cf10loginadobe.cimhost.com/securitytest.cfm

使用“Bob”用户和“secret”密码登录表明CF10 失败。最初似乎登录成功,但请注意cfdump会话的CF10中没有显示cfauthorization_orders值,而在 CF8 中存在该值。

在 CF8 中,登录后对同一 URL 的后续访问正确地保留了登录用户状态,并且不显示登录表单。在 CF10 中,实际上并没有为用户创建会话,因此后续访问相同的 URL 会提示再次登录。

我已经对此进行了彻底的测试,包括绕过cflogin逻辑和强制cfloginuser,它成功地在 CF10 中创建了一个经过身份验证的用户,证明它cfloginuser是受支持的。

在我看来,CF10 对OnRequestStartApplication.cfc 中函数的处理有些东西会创建然后立即终止用户会话。

解决方法:我正在使用的不优雅的解决方法涉及在 Application.cfc 的后续函数中重新创建cfloginuser会话实例化。OnRequest代码如下:

<cffunction name="onRequest">
<cfargument name = "targetPage" type="String" required=true/>
<cfinclude template=#Arguments.targetPage#>

<cfif IsDefined("loginQuery")>
  <cfif loginQuery.userroles NEQ "">
    <cflogin><cfloginuser name="#loginQuery.username#" Password = "#loginQuery.userpass#" roles="#loginQuery.userroles#"></cflogin>
  </cfif>
</cfif>

</cffunction>

如果有人尝试登录OnRequestStart,我会利用该请求的结果,检查它是否有效(loginQuery.userroles NEQ ""),然后实例化经过身份验证的会话。有一个缺点是用户必须单击新页面才能显示登录选项。在GetAuthUser()请求另一个页面加载之前,不会满足测试。

在 Application.cfc 中对备选方案进行的广泛测试并未发现此方法的任何备选方案。

于 2013-09-09T18:55:08.933 回答