2014-10-16 60 views
0

我在一个站点上工作,它有一个文档页面,应该只能从另一个站点的成员访问,而另一个站点有一个页面可以从我正在从事的网站的成员访问。在两个站点之间共享数据(如果请求有效)

目前,这是通过检查http引用来完成的,所以这个其他网站有一个链接可以说www.mysite.com/for-their-members-page/,如果http引用链接是www.theirsite。 com/members /我们知道它的成员区域内有来自他们网站的有效请求,他们必须签署,并且相同。

我首先关心的是http referrer很容易被伪造,但另一个问题是依赖于用户浏览器或安全设置,你甚至可能不会得到那个http referrer。

是否有任何解决方案,以便我可以验证请求是否有效 - 即它是来自其他网站的成员区域?反之亦然,所以他们可以验证对他们页面的请求实际上来自我们网站的成员?

感谢任何帮助或指针:)

+0

站点H =数据的主机,站点C =要共享数据的站点。我将在Site H上设置一个Web服务,Site C可以使用它来请求许可密钥。站点C然后可以将权限密钥传递到站点H上的网关页面(通过传统的浏览器请求)以允许用户查看文档 – 2014-10-16 17:54:58

回答

0

你的第一个问题的答案是是是是。 cgi变量可以很容易伪造,不应该用于任何类型的“真实”身份验证。其次,每个人都没有一种“简单”的方案来做你想要做的事情,但是有许多“单点登录”解决方案使用第三方来源的认证。例如,你有没有去过一个可以让你登录你的谷歌或Facebook账户的视线?他们正在使用oAuth--由大型社交媒体服务支持的SSO标准。

这可能是你想要做的事情的矫枉过正,但当我不知道总体风险是什么时,实际上“推荐”某些东西确实很难。

例如,您可以在服务器A上创建一个锁定到服务器B的IP地址的页面(反之亦然)。该页面可能会返回一个UUID - 您在应用程序范围内创建并存储的内容,并每天或每小时或5分钟轮换(适用于风险)。然后,你可以存储其他服务器UUID和使用CFHTTP定期刷新:

<cfhttp url="otherserver/myUUID.cfm"/> 
<cfset application.otherserveruuid = trim(cfhttp.filecontent)/> 

现在每个服务器就知道两两件事 - 它自己的UUID与其他服务器的UUID。

最后,你的UUID追加到链接到其他服务器,并添加检查(拨入服务器上),以确保它的存在,并匹配从在未来的服务器预期的UUID。

该方案将工作但是:

  • 它不是非常安全 - 只是很难伪造。例如,如果您每天只更改一次UUID,则有人可能只是在一天中将链接传递给任何人。
  • 它没有粒度。从你的问题,我把这个作为你想要的。您不想要验证特定的用户。你真的不关心他们是谁 - 你只关心来自其他网站

只要你明白,并可以与这两个cavaets生活,这将工作。正如你可能想象的那样,还有很多其他的方式来做到这一点你可能会想到几个:)

+0

感谢您的回答,正如我在其他两个答案中所说的那样,我将尝试这个周末出去看看什么效果最好。 – luke 2014-10-17 12:03:44

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> 

这将返回,如果成功的话

  • 国家1.
  • SITEID,数字ID
  • 密钥的,唯一的每个CUSTID
  • 客户ID(如通过由Arguments.custID)。在这个例子中实际上并不需要。
  • 消息。

如果网站证书验证失败或未准确地提供,这将返回0

  • 一条消息,说明为什么

    • 状态。

    然后我调用web服务,为用户获取证书,并返回类似授权

    http://docssite.com/authorize/index.cfm?site=#siteID#&passkey=#passkey#&customerID=#custID#

    Index.cfm链接将检查这三个网址参数对PermKeys,确保它是合法的,并登录用户输入。您甚至可以直接在URL中传递docID并将该决定用作是否显示docID。

    如果您还在列表中传递了一个docID,您可以轻松地将cfhttp传递到具有所有参数的相同url并获取返回的文档。

    然后,您可以编写一个类似的web服务来删除过期的凭证(说某人退订客户网站,您不希望他们的凭证仍然有效)。

    客户网站可以(也应该)跟踪他们已经调用过webservice的用户,并将他们的密钥和CustID(每个客户都独有)保存在他们自己的数据库中,这样他们就不需要重复调用您的web服务以获取相同的信息。

  • +0

    感谢您的详细解答!我将在本周末查看各种解决方案,看看哪些方法最好。 – luke 2014-10-17 12:02:35

    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#"/> 
    
    +0

    感谢您的回答,我喜欢这个解决方案。我将在本周末检查并尝试3种不同的解决方案,并看看哪种方法最好。再次感谢。 – luke 2014-10-17 12:01:42

    +0

    我不认为会话变量是安全的。如果同一用户在两个站点上使用不同的浏览器选项卡,会话变量可能会混乱。 – 2014-10-17 12:11:10

    +0

    根据我的建议,用户可以在同一浏览器中双方登录,并有两个单独的会话 - 他将有两个不同的会话标识符。 – xpa1492 2014-10-17 12:25:02