RubyAMF and Rails 3.0 - Session Renewed Issue

105 views
Skip to first unread message

greenmile

unread,
Aug 12, 2011, 3:46:58 AM8/12/11
to rubyamf
Hi experts,

I am upgrading Rails-Flex application from Rails 2.3.5 to Rails 3.0.
My Ruby version is 1.8.7. My server platform is Unbuntu Hardy Heron
8.04.

I have tried to update the RubyAMF plugin using source code (V1.6.6)
at:

https://github.com/victorcoder/rubyamf_plugin (Thanks fosrias for your
good job!)

The updated RubyAMF successfully receives a request from Flash object
and navigate it to correct Rails Controller.

The problem is that, every time RubyAMF navigates the request from a
Flash object to the targeted Rails Controller, the session is renewed.
It cleans up all session variables, including the login "user_id" =>
The application fails to authenticate login user => The targeted
action could not be reached, because the system automatically
redirects to the login page.

More specifically, according to my investigation, the session is renew
after line #15 in gateway function in RubyamfController:

======
RailsGateway.new.service(request.raw_post)
======

When I say "renew", it physically means the current session record in
"sessions" table in Database (MySQL) is deleted and replaced by a new
one after the above command is completed.

I do not get this problem in the application version running on Rails
2.3.5.

I am really in need to fix this problem. So if you have any idea to
solve it, please let me know.

I am looking toward to your response.

Thank you very much in advance.

.Viet Trung.


Anjan

unread,
Aug 12, 2011, 11:22:59 AM8/12/11
to rubyamf
I faced the exact same problem.

I think this will help you: http://anjantek.com/2011/05/08/rails-3-rubyamf-flex-csrf-solution/

On Aug 12, 12:46 pm, greenmile <viettrung...@gmail.com> wrote:
> Hi experts,
>
> I am upgrading Rails-Flex application from Rails 2.3.5 to Rails 3.0.
> My Ruby version is 1.8.7. My server platform is Unbuntu Hardy Heron
> 8.04.
>
> I have tried to update the RubyAMF plugin using source code (V1.6.6)
> at:
>
> https://github.com/victorcoder/rubyamf_plugin(Thanks fosrias for your

greenmile

unread,
Aug 17, 2011, 1:58:18 AM8/17/11
to rubyamf, viettr...@gmail.com, tee....@gmail.com
Hi Anjan,

Thank you very much for your thorough answers.

On Sat, Aug 13, 2011 at 9:41 PM, Anjan <tee....@gmail.com> wrote:

> According to your suggestion, I took time to check the authenticity
> token in the Flex request parameters and realize that,
> while Rails 2.3 somehow does NOT check authenticity_token in the
> parameters of POST requests from Flex object,
> Rails 3.0 does.
>
> The issue and some explanation is already mentioned at:
> http://stackoverflow.com/questions/2392135/after-refactoring-to-rubyamf-rails-doesnt-seem-to-complain-about-authenticity-to.
> But honestly, I do not quite understand since the explanation is a bit
> brief :)

I have edited that answer on StackOverflow to provide few more
details. I guess my answer won't appear till it is approved. The gist
of it is:

When you make an AMF request to, say, the articles_controller,
update action, the request doesn't actually go to that controller and
action directly. This AMF request (which is a POST request) actually
reaches the rubyamf_controller, gateway action (AMF end point) through
the Rails router. The destination controller and action
(articles_controller, update action) are tagged on as parameters to
this POST request.

The mime_type set on this POST call is "amf". The RubyAMF plugin
adds this mime_type to the list of mime_types that are not checked for
forgery protection. Hence, the call to the rubyamf_controller, gateway
action goes through successfully, even without the authenticity_token.

From Flex, you may have sent some parameters to the
articles_controller, update action. These arrive as serialized AMF
object to the gateway action. These parameters are deserialized here.

The gateway action then internally calls the target controller and
action (articles_controller, update action). The target action does
its stuff and returns a response. The gateway action obtains the
response of this target action, serializes it into AMF and sends it
back to the client.

In Rails 2.x, this internal call did not invoke the forgery
protection mechanism. So, even if you do not send the
authenticity_token as one of the parameters to the target action, it
works fine.

This changed in Rails 3. Even the internal call invokes the
forgery protection mechanism. The target action checks for the
presence of the authenticity_token parameter. So, you need to send it
from Flex.


Very clear explanation. Now I understand. Thank you very much!


Currently, I temporarily disable forgery check for the action by
> using:
>
> protect_from_forgery :except => [:amf_xxxx]
>
> And it works OK (just a workaround).

This is not necessarily a "workaround" as you call it. If your
actions exist for the sole purpose of providing AMF responses, then
you can just do this in those controllers:

skip_before_filter :verify_authenticity_token, :only =>
[ :amf_action_1, :amf_action2 ]

It is perfectly safe to do this because AMF calls have their own
systems for protecting from forgery. So it doesn't need Rails to
provide forgery protection in front of it.


You set my mind at rest. Yes, the actions are for sole purpose of
providing AMF responses so far. So I decide to skip Rails
verify_authenticity_token on AMF requests as the solution. Everything
is OK now.


> Now I try to pass the authenticity_token along with the flex request.
> If you have any suggestion to do it effectively, please let me know?

I have explained how to send the authenticity_token from Flex in
your AMF request in the blog post, under the "CSRF Token in Flex"
section. Did you not understand how to do it from the article? If you
can tell me where you are stuck, I will try to help you.


I will read it again and ask you questions if any. Thank you very
much!


> One more thing, in your article, you suggest that we should declare
> the ParameterMappings to the config/rubyamf_config.rb file.
>
> However, in my application I set ParameterMappings.scaffolding = true.
>
> So I wonder if there is any conflict if I set
> ParameterMappings.register() using parameter index, e.g.,
> authenticity_token => "[0]", etc?

I don't think there would be any conflict. As the
ParameterMappings.scaffolding explanation says:
> For those scaffolding users out there, who want the top-level object to come as a hash so scaffolding works out of the box.

I haven't used that option, but I am guessing that it converts
only the first parameter to a named hash. You can send the
authenticity_token as the second parameter from Flex and use the
ParameterMappings.register to convert only the second parameter:
> :authenticity_token => "[1]"

But if you want my suggestion, I would turn off the scaffolding
option and control all the parameter mapping myself using the
"register" method.


OK, I get your point.

I am very thankful to you for your great help!

Best regards,

.Viet Trung.
Reply all
Reply to author
Forward
0 new messages