2009-11-18 21 views
4

我有一個對象,我想抓住java中的內容。 唯一的問題是,目前是紅寶石。如何在java中解組ruby對象?

irb(main):050:0> blah 
=> "BAh7ByIeYXV0aGVudGljYXRpb25fc3RyYXRlZ2llczAiCXVzZXJpBg%253D%253D-\ 
-0cdecf4edfaa5cbe4693c9fb83b204c1256a54a6" 

irb(main):049:0> Marshal.load(Base64.decode64(blah)) 
=> {"authentication_strategies"=>nil, "user"=>1} 

我得到了base64部分 - 所以現在一切都是以字節爲單位。我將如何訪問第二個字符串?我認爲jruby可以做些事情,但我從未使用過,也不知道從哪裏開始。

讓我詳細說明我的問題。

1)這些都是我想在Apache

2)我不打算將它們存儲在數據庫中Tomcat上的servlet和Merb的應用程序之間共享的cookie。我曾考慮過在memcached中使用它們,但由於其他原因我想將它們存儲爲cookie(是的,我很清楚涉及的安全影響)

我目前正在查看jruby的紅橋/ jruby-嵌入,但是因爲這只是70字節,所以我需要看看,我認爲把所有這些開銷都變得如此簡單是很荒謬的。

,而不是啓動一個新的問題....代碼,我現在看起來像這樣:

 // using commons 
     Base64 b64 = new Base64(); 
     byte[] decoded = b64.decode(cookie.getValue().getBytes()); 

     ScriptingContainer container = new ScriptingContainer(); 
     container.runScriptlet("la = Marshal.load(\"" + decoded + "\"); puts la.to_s;"); 

顯然,這是行不通的原因元帥是要檢查前2個字節的解碼和怪胎,因爲它不匹配jruby的主要/次要版本.... hrmss ..

回答

2

好的!這就是我所做的。讓我再次重申我的全部目的,就是從merb獲得一個cookie會話,並在tomcat下運行一個servlet。

import java.io.*; 
import java.util.*; 
import org.jruby.embed.ScriptingContainer; 
import org.apache.commons.codec.binary.Base64; 
import javax.servlet.*; 
import javax.servlet.http.*; 

public class process extends HttpServlet { 

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    HttpSession session = request.getSession(true); 

    PrintWriter out = response.getWriter(); 
    Cookie[] cookies = request.getCookies(); 

    for(int i=0; i<cookies.length; i++) { 
     Cookie cookie = cookies[i]; 

     // base64 decode, then un-marshall ruby style... 
     // finally figure out what to do with our session secret key 
     if(cookie.getName().equals("_session_id")) { 
     ScriptingContainer container = new ScriptingContainer(); 
     container.setWriter(out); 
     container.runScriptlet("require 'base64'; puts \"" + cookie.getValue() + "\"; " + 
           "puts Marshal.load(Base64.decode64(\"" + cookie.getValue() + "\")).to_s; "); 
     }      

    } 

}  
} 

顯然這個代碼可以清理很多 - 例如:將base64解碼移回java - 但這會從merb獲得一個cookie。現在我只需要將驗證器放在那裏以確保這不是僞造的。

感謝您的建議,每個人!

+0

我可能是錯的,但是如果cookie中包含ruby代碼,這會不會導致注入漏洞?我知道這個話題很古老,但我想我會把它扔到那裏。 – jgrowl 2013-05-09 03:46:43

3

對於不涉及JRuby的解決方案,爲什麼你不序列化你自己感興趣的領域?例如,將它們作爲原始字符串保存到文件或關係數據庫中?

我意識到這可能不是正確回答這個問題,但它可能是一種可能性,你以前沒有想過!

編輯 - feydr已經明確表示,他不會談論對象序列化的數據到一個文件。因此,我推測序列化是針對進程間通信,在這種情況下,通過套接字交付的二進制協議(或任何真正的協議)是一個很好的解決方案,並且易於實現。你可能會比看看Google protocol buffers更糟糕(它甚至可以在Java端執行代碼生成)。

+0

文件io對於存儲會話信息是昂貴的,並且絕對不在...我們的主要網絡應用程序是紅寶石,並且每次頁面被擊中時我都無法查看文件 我沒有基準來證明它,但在會話中使用數據庫聽起來很難 - 謹慎提供關於此的任何案例。 真的mem​​cache是​​我現在的想法,如果沒有對這個問題的答案 – eyberg 2009-11-18 23:58:25

+0

道歉 - 我認爲,鑑於你在談論序列化/編組,這個文件IO *正是*你在做什麼!你總是可以嘗試在套接字上使用二進制協議 – 2009-11-19 08:06:37

1

您也可以考慮使用可用於RubyJava(以及C++和Python)的Google協議緩衝區。