我正在网站上工作,它有一个文档页面,只有来自其他网站的成员才能访问,而这个其他网站有一个页面,只有来自我正在处理的网站的成员才能访问该页面
目前通过查看http推荐人来完成此操作,因此其他网站有一个链接,可以说www.mysite.com/for-their-members-page/,如果http推荐人是www.theirsite.com / members /我们知道来自他们网站的有效请求,他们必须在他们的成员区域内签署,而另一方面也是如此。
我首先关注的是http推荐人很容易被伪造,但另一个问题取决于用户浏览器或安全设置,你可能甚至没有得到那个http推荐人。
是否有任何解决方案,以便我可以验证请求是否有效 - 即它是来自其他网站成员区域?反之亦然,他们可以验证对其网页的请求是否实际来自我们网站的成员?
感谢您提供任何帮助或指示:)
答案 0 :(得分:1)
一个“安全”的解决方案是使用ColdFusion会话变量。
在站点A上,您需要一个Session变量,用于标识用户已登录(例如,您有Session.UserName)。然后,您有一个简单的身份验证检查页面(check.cfm)执行此操作:
<cfif IsDefined("Session.Username")>1<cfelse>0</cfif>
站点A链接到站点B,如下所示:
http://siteB.com/page.cfm?remoteID=<cfoutput>#Session.CFID#&remoteToken=#Session.CFToken#</cfoutput>
现在,站点B可以通过执行以下操作来检查用户是否登录到站点A:
<cfhttp url="http://siteA.com/check.cfm?CFID=#URL.remoteID#&CFToken=#URL.remoteToken#"/>
答案 1 :(得分:0)
对于你的第一个问题,答案是肯定是的。 cgi变量很容易伪造,不应该用于任何类型的“真实”身份验证。
其次,没有一种“简单”的方案,每个人都用来做你想要做的事情,但有许多“单点登录”解决方案使用针对第三个来源的身份验证。例如,您是否曾经去过一个允许您使用Google或Facebook帐户登录的视频?他们正在使用oAuth--一种由大型社交媒体服务支持的SSO标准。
对于你正在做的事情来说,这可能有点过头了,但是当我不知道整体风险是什么时,真的很难“推荐”一些东西。
例如,您可以在服务器A上创建一个锁定到服务器B的IP地址的页面(反之亦然)。页面可以返回UUID - 您创建并存储在应用程序范围内的内容,并每天或每小时或5分钟轮换(适用于风险的任何内容)。然后,您可以存储OTHER服务器UUID并使用cfhttp定期刷新它:
<cfhttp url="otherserver/myUUID.cfm"/>
<cfset application.otherserveruuid = trim(cfhttp.filecontent)/>
现在每个服务器都知道两件事 - 它是OWN UUID和OTHER SERVER的UUID。
最后,将UUID附加到OTHER服务器的链接,并添加一个检查(在传入服务器上)以确保它存在并匹配来自服务器的UUID。
这个方案可行但是:
只要您了解并且可以使用这2个cavaets,这将有效。正如您可能想象的那样,有很多其他方法可以做到这一点。你可能会想到一些:)
答案 2 :(得分:0)
我会把这个留在这里,无论是谁可以从中提取一些东西,但this is the more elegant answer.,并禁用链接共享而不进行登录共享。
<cfif len(trim(Arguments.username)) is "">
<cfset results.state = 0>
<cfset results.message = "Username argument is not defined">
<cfreturn results>
</cfif>
<cfif len(trim(Arguments.password)) is "">
<cfset results.state = 0>
<cfset results.message = "Password argument is not defined">
<cfreturn results>
</cfif>
<cfif not isDefined("Arguments.CustID")>
<cfset results.state = 0>
<cfset results.message = "Customer ID (representing the user of your site) is required.">
<cfreturn results>
</cfif>
<cfquery name="ValidateSite"...>
select SiteID from othersites
where username = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.username#">
where password = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.password#">
and Active = 1
</cfquery>
<cfif ValidateSite.recordcount eq 1>
<cfset results.Passkey = Hash(Arguments.username & "_" & Arguments.custID)>
<!--- I chose hash because it will reliably create the same key when the referring site provides the same data. Wheras, a lot of other functions might not. --->
<cfquery name="CheckID"...>
Select SiteID
from PermKeys
where SiteID=<cfparam cfsqltype="cf_sql_integer" value="#ValidateSite.siteID#">
and PassKey=<cfparam cfsqltype="cf_sql_varchar" value="#results.PassKey#">
and custID=<cfparam cfsqltype="cf_sql_varchar" value="#Arguments.custID#">)
</cfquery>
<cfif CheckID.recordcount eq 0>
<cfquery...>
insert into PermKeys(SiteID,Passkey,CustID)
values(<cfparam cfsqltype="cf_sql_integer" value="#ValidateSite.siteID#">,<cfparam cfsqltype="cf_sql_varchar" value="#results.PassKey#">,<cfparam cfsqltype="cf_sql_varchar" value="#Arguments.custID#">)
</cfquery>
<cfset results.message = "Authentication for this customer created.">
<cfelse>
<cfset results.message = "Authentication for this customer previously created. Authentication Key will always be the same. Please store the authentication keys, passed back as passKey, on your own server so that a call isn't needed each time.">
</cfif>
<cfset results.state = 1>
<cfset results.siteID = ValidateSite.siteID>
<cfset results.custID = Arguments.custID>
<cfelse>
<cfset results.state = 0>
<cfset results.message = "User not found.">
</cfif>
<cfreturn results>
如果成功,这将返回
如果站点凭据验证失败或提供不正确,则返回
然后我调用webservice,获取用户的凭据并返回类似
的链接http://docssite.com/authorize/index.cfm?site=#siteID#&passkey=#passkey#&customerID=#custID#
authorize的index.cfm将检查这三个针对PermKeys的url参数,确保它是合法的,并将用户IN记录下来。您甚至可以直接在网址中传递docID,并将该决定用作是否显示docID。
如果您还在列表中传递了一个docID,您可以轻松地将所有参数与cfhttp连接到相同的URL并返回文档。
然后,您可以编写类似的Web服务来删除过期的凭据(比如从客户站点取消订阅的人,您不希望他们的凭据仍然有效)。
客户站点可以(并且应该)跟踪他们已经调用过Web服务的用户,并在他们自己的数据库中保存他们的密码和CustID(每个客户都是唯一的),这样他们就不需要重复了调用您的Web服务获取相同的信息。