ColdFusion 8 到 ColdFusion 10 迁移:CFloginUser 未按预期工作 [英] ColdFusion 8 to ColdFusion 10 Migration: CFloginUser Not Working As Expected

查看:23
本文介绍了ColdFusion 8 到 ColdFusion 10 迁移:CFloginUser 未按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

After upgrading from CF8 to CF10, moving all files and databases and jumping through all the configuration hoops, the new version of the site is up and running, but the authentication/login is not working.

这里是环境:

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

Old server: ColdFusion Enterprise 8,0,1,195765

操作系统:Windows Vista*

Operating System: Windows Vista*

操作系统版本:6.0

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

Update Level: .... hf801-00007.jar

IIS 版本:7

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

(*not sure where that "Vista" comes from? The System Information says "Windows Server 2008 Datacenter without Hyper-V")

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

New server: ColdFusion Enterprise 10,0,11,285437

Tomcat 版本:7.0.23.0

Tomcat Version: 7.0.23.0

操作系统:Windows Server 2008 R2

Operating System: Windows Server 2008 R2

操作系统版本:6.1

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

Update Level: .... chf10000011.jar

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

Adobe Driver Version: 4.1 (Build 0001)

IIS 版本:7.5

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

I have a pretty standard ColdFusion login system, using cfloginuser in Application.cfc. After I login on the old site, outputting #GetAuthUser()# prints my username to screen, and all my role-based rules work.

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

On the new server, outputting GetAuthUser() prints empty.

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

cfauthorization_kllcms dXNlcm5hbWU6cGFzc3dvcmQ6YXBwX25hbWU= 

在新站点上,会话的 CFDUMP 根本不显示 cfauthorization_kllcms 值.所有其他会话值都存在于两个实例中.

On the new site, CFDUMP of session does not show a cfauthorization_kllcms value at all. All other session values exist in both instances.

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

It is the exact same codebase, database structures, etc. Naturally, none of my role-based rules work, because they all depend on validation of getAuthUser() and IsUserInRole("x") conditionals.

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

I know the initial login process itself is working, because it is correctly setting session variables with user information, and they are available on subsequent requests. But none of the traditional cflogin data is available on subsequent calls.

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

Any ideas what might have changed?

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

UPDATE: Per Adam's suggestion (below) I set up 2 test apps, one on the old server, one on the new.

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

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

使用test"和demo982013"​​作为用户名和密码.

Use "test" and "demo982013" as user and password.

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

Append ?logout=true to the URL to logout and re-test. These two apps have exactly the same code, same database. I am dumping session and form values to screen, along with GetAuthUser() value.

身份验证方法与 Adobe 文档中的描述几乎完全相同,如有必要,我可以在这里分享所有相关代码.

The authentication method is pretty much exactly as outlined in Adobe's documentation, and I can share all relevant code here if necessary.

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

Note that in the "new" server, the form loads each time you visit the page, whether you have logged in or not. This is exemplar of the fact that the cflogin session is not being retained or recognized, thus presenting the login form each visit (although not on initial form completion, which shows that cflogin is at least working on the initial login, I think).

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

UPDATE 2: I've been drilling deeper into this, and I am able to get cfloginuser to fire a couple of ways, just not as part of the standard Adobe documented application-based user security model.

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

Option 1: I created a standalone page, and placed the following code in it:

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

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

I then instructed Application.cfc to allow this past the cflogin gate. You can see the results by pointing your browser to: http://cflogin.cimhost.com/directlogin.cfm?bypass=true

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

Voila. 'cfauthorization_cicmstest' value has been set, and user is logged in. Subsequent calls to GetAuthUser() are successful. So I know now that CF10 and the application do allow cfloginuser, and the user session can be created.

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

Option 2: I then decided maybe it was something about my Application.cfc file, so I again bypassed the cflogin gate, and placed the hard-coded cfloginuser snippet directly in my Application.cfc onRequestStart function. Logged out and visited: http://cflogin.cimhost.com/index.cfm?bypass=true&noquery=true

再次,cfauthorization_cicmstest 值设置成功,用户已登录.

Again, cfauthorization_cicmstest value was successfully set, and user is logged in.

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

However, logging in still fails if the cfloginuser directive is fired within the actual cflogin process in Application.cfc. Here is what that code looks like:

        <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.

I know that the query is successful, because I am setting an alert message that tells me the loginquery.userroles value was not empty, which is the condition for processing cfloginuser.

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

I know where the code is failing now, just not why. I've tried hard coding that cfloginuser value, and it still fails. I'm at a loss as to what to try next. The cfloginuser functionality works, just not in the one place (within the loginQuery.userroles conditional) that I need it to work.

更新 3:

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

Just to prove to myself it wasn't my code, I created 2 more test sites, one on the old server, one on the new server:

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

New Server (CF10) = http://cf10loginadobe.cimhost.com/securitytest.cfm

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

Old Server (CF8) = http://cf8loginadobe.cimhost.com/securitytest.cfm

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

I copied exactly Adobe's 3 files from their Application-based security example. I created a database table with their schema and values. I added my cfdump outputs to show the sessions being created.

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

Test with user of "Bob" and password of "secret". Even with Adobe's own code, the tests fail on CF10.

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

I'm not sure what to do next. Rewriting the application to not use cfloginuser is not an option, as we have more than a dozen applications we are migrating to CF10 that use this authentication model, across hundreds of templates.

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

It's possible it's something weird about how IIS7.5 is handling ColdFusion requests, but that seems unlikely given the ability to successfully instantiate cfloginuser outside of the query result conditional.

推荐答案

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

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

I have deployed two test sites, using Adobe's own example code for application based user security, copied in its entirety from the Adobe website. One test site is in ColdFusion 8, one is ColdFusion 10. The code and databases are identical on both sites. I added cfdump output to monitor session variables and login status as they are set.

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

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

使用Bob"用户登录和秘密"的密码;演示了 CF10 中的故障.最初似乎登录成功,但请注意会话的 cfdump 不显示 CF10 中的 cfauthorization_orders 值,其中 CF8 中的值存在.

Logging in using a user of "Bob" and password of "secret" demonstrates the failure in CF10. Initially it appears login was successful, but note that the cfdump of the session does not show a cfauthorization_orders value in CF10, where in CF8 the value is present.

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

In CF8 subsequent visits to the same URL after login correctly retain the logged in user status and do not present the login form. In CF10, no session was actually created for the user, and therefore subsequent visits to the same URL prompt for login again.

我对此进行了彻底的测试,包括绕过 cflogin 逻辑并强制 cfloginuser 成功在 CF10 中创建了经过身份验证的用户,证明 cfloginuser 支持.

I have tested this thoroughly, including bypassing the cflogin logic and forcing cfloginuser, which successfully creates an authenticated user in CF10, demonstrating that cfloginuser is supported.

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

It appears to me there is something about CF10's handling of the OnRequestStart function in Application.cfc that creates and then immediately kills the user session.

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

Workaround: The inelegant workaround I am using involves re-creating the cfloginuser session instantiation in a subsequent OnRequest function in Application.cfc. The code is as follows:

<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() 测试在请求另一个页面加载之前不会满足.

If there was an attempt to login in the OnRequestStart, I leverage the results of that request, check if it was valid (loginQuery.userroles NEQ ""), and then instantiate the authenticated session. There is a downside in that users have to click to a new page for logged in options to appear. The GetAuthUser() test is not met until another page load is requested.

在 Application.cfc 中对替代方案进行了广泛的测试,没有发现任何替代这种方法的方法.

Extensive testing of alternatives within Application.cfc did not reveal any alternative to this approach.

这篇关于ColdFusion 8 到 ColdFusion 10 迁移:CFloginUser 未按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆