2009-11-18 26 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协议缓冲区。