用P3P header解決iframe跨域訪問cookie[各種語言]

各種語言在頭文件中,加入P3P協議代碼,解決iframe跨域訪問:

理論很簡單,模式和大多請求返回狀態的SSO差不多.但是有幾個地方需要注意的。

1.頁面裏的COOKIE不能是瀏覽器進程的COOKIE(包括驗證票和不設置超時時間的COOKIE),否則跨域會取不到.這點做跨域COOKIE的人比較少提到.不過實際上留意下幾家大學做的方案,有細微的提到他們的驗證模塊裏的COOKIE是有設置超時時間的.

2.當利用IFRAME時,記得要在相應的動態頁的頁頭添加一下P3P的信息,否則IE會自覺的把IFRAME框裏的COOKIE給阻止掉,產生問題.本身不保存自然就取不到了.這個其實是FRAMESET和COOKIE的問題,用FRAME或者IFRAME都會遇到.

3.測試時輸出TRACE,會減少很多測試的工作量.

只需要設置 P3P HTTP Header ,在隱含 iframe 裏面跨域設置 cookie 就可以成功。他們所用的內容是:

P3P: CP='CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR'

ASP直接在頭部加了頭部申明,測試有效。
<%Response.AddHeader "P3P", "CP=CAO PSA OUR"%>

php的話,我沒去試,應該是如下寫法:
header('P3P: CP=CAO PSA OUR');

ASP.NET的話
通過在代碼上加Response.AddHeader("P3P", "CP=CAO PSA OUR")或者在Window服務中將ASP.NET State Service 啓動。 

JSP:
response.setHeader("P3P","CP=CAO PSA OUR") 


-----------------------------   以下是一個應用的跨域訪問流程案例   ---------------------------------------

目前在整合幾個應用時,遇到了iframe無法獲取cookie(session)的問題,經過google,終於把這個問題解決了,現在記錄一下。
    我的需求是這樣的。
   有一個應用是用.net開發的,主要是控制用戶登錄,用戶訪問權限的,部署在上海機房。現在就叫A應用吧
   還有一個應用是用java開發,主要是具體業務的操作。部署在北京機房,這裏叫B應用吧
   由於已經有一個用戶管理和權限的應用程序,所以java 開發的這個B應用就沒有開發用戶權限的功能,想直接使用.net的A程序。

   用戶訪問的流程是這樣的:
    1.用戶先在A處登錄,A設自己的cookie,在A的菜單裏有去B應用的鏈接
    2.當用戶點去B應用的鏈接時,A在鏈接上自動加上這個用戶的token,傳給B系統
  3.當B系統接收到請求後,把這個用戶的token信息設成自己系統的cookie,(B系統裏有表單post操作,如果不設cookie,session,那麼每個請求不管GET還是POST都要明確帶着該用戶的token信息,對於系統的改造量比較大,另外以後換權限驗證方法改動也比較大。)
4.用戶在B系統裏的每次操作都沒有明碼帶用戶的token,所以每次都要去cookie得到token信息,然後發送一個http請求去A,讓A系統驗證這個用戶是否有權限訪問。
    5.如果A系統的接口返回可以訪問的狀態報告,那麼B繼續執行;如果A系統指示沒有權限訪問,那麼B系統提示訪問受控警告信息。

一切開發都完成,到整合上線時,發現這個流程走不通,百思不得其解,想了半天也不知道 怎麼 回事,google了半天,才發現原來是ie在搗鬼,IE不允許跨域訪問cookie(好象firefox沒問題,ie自6.0以後改用w3c組織的P3P協議了),再看看我的應用,在第二步設的cookie,在第三步以後所有B應用的訪問請求,ie都把B應用的cookie blocked掉了(因爲用戶的訪問是從A應用發起,從A應用訪問B應用的東東,算跨域訪問,IE認爲有安全問題)。。。。(IE狀態欄有一個紅眼睛的button,點開可以看到哪些cookie給blocked掉了)

     知道原因就好辦了,再google知道可以用P3P header可以解決問題!
     下面是java的解決辦法之一,也是我的解決辦法,不過個方法不太好:
     直接往響應里加一個P3P的header
      response().addHeader("P3P", "CP=\"IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA\"");

其中CP=“XXX XXXX”這些是有具體含義的:
     CP就是compact policies的意思,
    另外
header的值也可以是policyref="http://myhost/P3P/PolicyReferences.xml",就是指定一個策略文件。

具體請看這裏 .

--------------------------     OK OVER      --------------------------------

下面是摘抄的一段Compact Policies 的具體取值範圍和設值含義。

 

 Compact Policies

Compact policies are essentially summaries of P3P policies. They can be used by user agents to quickly get approximate information about P3P policies, therefore improving performance.

For an in-depth explanation of compact policies, we refer to the  P3P1.0 [4] specification. Here, we limit to stating the syntax:

compact-policy-field  = `CP="` compact-policy `"`

compact-policy = compact-token *(" " compact-token)

compact-token = compact-access |
compact-disputes |
compact-remedies |
compact-non-identifiable |
compact-purpose |
compact-recipient |
compact-retention |
compact-categories |
compact-test

compact-access = "NOI" | "ALL" | "CAO" | "IDC" | "OTI" | "NON"

compact-disputes = "DSP"

compact-remedies = "COR" | "MON" | "LAW"

compact-non-identifiable = "NID"

compact-purpose = "CUR" | "ADM" [creq] | "DEV" [creq] | "TAI" [creq] |
"PSA" [creq] | "PSD" [creq] | "IVA" [creq] | "IVD" [creq] |
"CON" [creq] | "HIS" [creq] | "TEL" [creq] | "OTP" [creq]

creq = "a" | "i" | "o"

compact-recipient = "OUR" | "DEL" [creq] | "SAM" [creq] | "UNR" [creq] |
"PUB" [creq] | "OTR" [creq]

compact-retention = "NOR" | "STP" | "LEG" | "BUS" | "IND"

compact-category = "PHY" | "ONL" | "UNI" | "PUR" | "FIN" | "COM" |
"NAV" | "INT" | "DEM" | "CNT" | "STA" | "POL" |
"HEA" | "PRE" | "LOC" | "GOV" | "OTC"

compact-test = "TST"

另外這裏還有一個P3P的驗證工具:http://www.w3.org/P3P/validator.html ,可以驗證一下自己設置的P3P是否正確。

這裏還有一個老外寫的不錯的blog,也可以參考一下。http://www.sitepoint.com/article/p3p-cookies-ie6/2
----其他--------------------------------------------------------------------------------------------------

IE6/IE7支持的P3P(Platform for Privacy Preferences Project (P3P) specification)協議默認阻止第三方無隱私安全聲明的cookie,Firefox目前還不支持P3P安全特性,firefox中自然也不存 在此問題了。

在frameset裏面,也就是裏面的frame是來自第三方站點(不同IP或不同域名),那麼默認情況下IE會自動禁用這些站點的cookie, 也就是在請求某url時在HTTP header裏不發送它們的cookie,包括session的cookie。注意,這些站點在response裏面設置的cookie還是會被髮送到瀏 覽器的。

在用戶瀏覽a.php時 A.com寫入的爲第一方Cookie,其嵌入的iframe 指向 b.php.這時B.com寫入的就爲第三方Cookie了,所以它是被IE當在了大門外。 所以,每次當用戶提交的cookie提交時,就掛掉了.因爲傳不到真實的服務器.

解決方案.

PHP 程序 , 可以直接在B網站中寫入

PHP代碼

<?php  

header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"' );  

?>  

這樣就能接受第三方的Cookie啦。

 

lighttpd的服務器

 

XML/HTML代碼

server.modules     = ("mod_setenv")  

setenv.add-response-header  = ( "P3P" = >  " CP = 'CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR' ")  

apache的服務器

XML/HTML代碼

< VirtualHost >   

Header set P3P 'CP = "CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR" '  

</ VirtualHost >   

IIS的服務器

增加一個網站http頭來解決問題;
管理 工具——〉選擇一個網站 ——〉屬性——〉 http頭,增加一個http頭
然後輸入頭名:P3P
輸入頭內容:CP=CAO PSA OUR

jsp頁面:

XML/HTML代碼
  1. < %  
  2. response.setHeader("P3P","CP = CAO  PSA OUR");  
  3. %>   
java代碼最簡單的辦法,增加一個filte:
Java代碼

public   class  TransNameFilter  extends  HttpServlet  implements  Filter {  

private   static  org.apache.commons.logging.Log logWriter =  

   LogFactory.getLog(TransNameFilter.class .getName()); 

public  TransNameFilter() {  

   super ();  
}  

/* (非 Javadoc)  

   * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)  

   */   

public   void  init(FilterConfig arg0)  throws  ServletException {

}  

  

/* (非 Javadoc)  

* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)  

*/   

public   void  doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  

   throws  IOException, ServletException {  

   HttpServletRequest hreq = (HttpServletRequest) request;  

   String transName = hreq.getParameter("transName" );  

   if  (Util.isNullOrEmpty(transName)) {  

    logWriter.fatal(" there is no transName for this request" );  

   } else  {  

  

    logWriter.info(" transName is "  + transName);  

   }  

   HttpServletResponse res = (HttpServletResponse) response;  

        //iframe引起的內部cookie丟失   

   res.setHeader("P3P" , "CP=CAO PSA OUR" );  

   if  (chain !=  null )  

    chain.doFilter(request, response);  
}

/* (非 Javadoc)  

   * @see javax.servlet.Filter#destroy()  

   */   

public   void  destroy() {  

}

}  

此文整理來自:http://www.cnblogs.com/Guroer/archive/2011/02/15/1955426.html

其它幾個跨域訪問文章:

http://blog.csdn.net/lanmao100/archive/2008/04/25/2328491.aspx   用P3P header解決iframe跨域訪問cookie/session

http://viralpatel.net/blogs/2008/12/how-to-set-third-party-cookies-with-iframe.html   How to set third-party cookies with iframe

http://hi.baidu.com/aullik5/blog/item/cde7f31efc3953f2e0fe0b46.html   P3P Header Tips

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章