I'm building a rails 4 app with JRuby on Torquebox, and running into a weird issue with the sessions. I'm using the devise gem to handle authentication which works well, except that as per the rails security guidelines, I'm trying to reset the session when a user successfully logs in.
I've created a Warden hook which handles this for me, which looks like this
Warden::Manager.after_set_user :event => [:set_user, :authentication] do |record, warden, options|
if options[:scope] && warden.authenticated?(options[:scope])
request = warden.request
Rails.logger.debug "session - #{request.session}"
# backup = request.session.to_hash
# backup.delete(:session_id)
request.reset_session
# request.session.update(backup)
Rails.logger.debug "session - #{request.session}"
end
end
This method is definitely being called which is great, however the two outputs are both the same, and the session is not being reset at all. I'm using the TorqueBox session store, setup like
# session_store.rb
RtsBackend::Application.config.session_store :torquebox_store, {
key: '_RtsBackend_session'
}
# config.ru
use TorqueBox::Session::ServletStore
And it seems to be working as TorqueBox has inserted data, and session data from devise is working, but I just can't seem to clear it.
I was under the impression that devise did this automatically on login, but if it is then the same issue is occurring and rails isn't clearing it.
Any suggestions?
So after digging around, and speaking with one of the core TorqueBox developers, it turned out to be a bug. In rails 4, they changed the way sessions were reset which didn't involve clearing its contents.
Thanks to #bbrowning with this commit it should now be sorted pending a final test once the fix is pushed :)
Related
c9 ide, Ubuntu workspace, rails 4.2.10, ruby 2.4.0
When trying to use omniauth gem in developer mode with developer strategy, login link to 'auth/developer' successfully presents form to user. Upon form submission (where route is 'auth/developer/callback') this error is generated:
ActionController::InvalidAuthenticityToken in SessionsController#create
Would like to be able to use developer strategy during the remainder of application development. Documentation doesn't seem to specify anything else needed for the callback when using the developer strategy (in development mode). There does seem to be at least one small discrepancy in the doc, is something missing as well??
All code working properly when using actual providers or during test mode with cucumber.
Here is portion of initializer code (not including keys/secrets) which I started with in config/initializers/omniauth.rb:
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do
provider :developer unless Rails.env.production?
provider :github, 'redacted,'redacted',
{ :name => "github", :scope => ['read:user','user:email']}
provider :facebook, 'redacted', 'redacted'
end
Gemfile includes:
gem 'omniauth'
gem 'omniauth-github'
gem 'omniauth-facebook'
routes.rb:
match 'auth/:provider/callback', :to => 'sessions#create', :via => [:get, :post]
sessions_controller:
def create
begin
authenticator = Authentication.new(env["omniauth.auth"])
authenticator.disallow(session[:user_id]) if session?
authenticator.deny if authenticator.missing_information?
auth, message = authenticator.register_or_login
session[:user_id] = auth.user.id
etc.
app/controllers/sessions_controller/authentication.rb:
def initialize(omniauth)
# get Omniauth authentication hash
#auth_hash = omniauth
end
def auth_hash
#auth_hash
end
etc.
When successful (using other providers or in test mode), callback should be provided with valid token, path of code can then easily be traced through create method of sessions_controller to the constructor of the Authenticator class, etc.
When in development mode using developer strategy, the body of the sessions create method is never entered at all.
After getting valid token, I should see messages such as:
"Welcome <name> You've signed up via <provider>."
However, since error is raised before that point, only see the following in the server output:
Processing by SessionsController#create as HTML
Parameters: {"name"=>"Example User", "email"=>"example#user.com", "provider"=>"developer"}
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
actionpack (4.2.10) lib/action_controller/metal/request_forgery_protection.rb:181:in `handle_unverified_request'
I found this in another section of the Wiki:
Rails session is clobbered after callback on Developer strategy
The developer strategy callback is sent using POST request. Disable forgery protection for given action, otherwise session will be clobbered by rails.
skip_before_action :verify_authenticity_token, only: :create
This definitely works, but I still have a few questions.
Is the before_action defined and handled by omniauth itself, or should I add it to my controllers when NOT in developer mode?
It looks as though this scheme works by just adding that line in developer mode, and deleting it in production, which seems pretty unreliable. Is there a way to enforce it automatically instead?
I have seen many posts about this type of error, but it doesn't seem that any that I can find apply to my case.
This is the error I am getting back from Facebook:
Error validating verification code. Please make sure your redirect_uri is identical to the one you used in the OAuth dialog request
This is the website Site URL I have set up: http://landmark.dev/
This is the redirect URI I have defined: http://landmark.dev/auth/facebook/callback
this is my omniauth.rb (cleaned)
OmniAuth.config.full_host = "http://landmark.dev"
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, 'xxx', 'xxx'
provider :facebook, 'xxx', 'xxx', :scope => 'email'
end
OmniAuth.config.on_failure do |env|
[200, {}, [env['omniauth.error'].inspect]]
end
This is my routes.rb for the callback:
match 'auth/:provider/callback', to: 'sessions#create', via: :all
Twitter works great, by the way - it's just facebook that won't connect. I've been fighting with this for 3 days now and trying to find a solution. Thanks in advance for your help.
UPDATE: While waiting on an answer to this to help figure it out, I tried adding in omniauth-google-oauth2 as authentication through google+ is part of the plan for this project as well. It seems I get the same error from Google:
"error" : "redirect_uri_mismatch"
I would think this indicates some problem on my side, but I have no idea what it could be. The other odd thing is that Twitter still works just fine.
There is a bug introduced in the last update of omniauth-oauth2 gem. Dowgrande your gem version and it should work for while.
gem 'omniauth-oauth2', '~> 1.3.1'
You can see discussion here
https://github.com/intridea/omniauth-oauth2/issues/81
If you are trying this from your local machine (I guess you are doing so because I think that .dev domains are not available at this moment and you should be using a server like POW). The problem is that Facebook can't reach your machine.
You can use a solution like localtunnel http://localtunnel.me/ for development purposes or try to use localhost, I think localhost worked in the past although I'm not sure at this moment.
I'm having an awkward problem using Linkedin gem.
My app tries to get the user data using oauth. On development enviroment it works just fine. But as soon as I upload it to heroku it starts to give me errors like:
2014-07-17T04:25:07.552779+00:00 app[web.1]: NoMethodError (undefined method `picture_urls' for #<LinkedIn::Client:0x007f4f4cea65f8>):
2014-07-17T04:25:07.552783+00:00 app[web.1]: app/models/social_auth.rb:7:in `fetch_details'
The real problem is that it used to work and stopped from nowhere. I even gave a rollback on my git repositories to see if the past code is working but its not.
It seems like it does not answer me correctly even giving the correct callback (I'm sure the error is happening after the oauth validation).
Check the complete code of the definition (that is executed after the model save):
def fetch_details_from_linkedin
client = LinkedIn::Client.new(ENV["LINKEDIN_KEY"], ENV["LINKEDIN_SECRET"])
authkeys = [self.token, self.secret]
client.authorize_from_access(authkeys)
#linkedin = LinkedinUserData.where(user: self.user).first_or_initialize
#linkedin.avatar_url = client.picture_urls.all.first
#linkedin.profile_url = client.profile.site_standard_profile_request.url
#linkedin.save
end
Each item on this model have the token and secret used to validate the user with the 'authorize_from_access' method. I don't know why, but it seems that the callback is answering me an empty object.
Things I already thought about:
Live status on API - CHecked. It gives the error no matter the status of the app on the linkedin api
Callback URL: already checked, even with https. As I said, the callback is being executed. The error is an internal error (500).
I just contacted the developer of the gem and together we discovered that even not specifying the version, heroku for some reason was getting an old version of the gem since github was already on 0.4.7 and it was getting a 0.2.x.
So, I solved this problem by specifying the gem version. Don't know what is happening on heroku, but at least the problem is solved and linkedin is authorizing again.
gem 'linkedin', '0.4.7'
ps: if you get an dependency error, just declare in your gem file:
gem 'hashie', '2.0'
This happens because of an ominiauth dependency.
I'm trying to implement user authentication for web sockets in Torquebox, and according to everything on the internet, I should be able to access the HTTP session from within a stomplet if I'm running the web app along side the stomp server, which I am.
My configuration looks something like this
web do
context '/'
host 'localhost'
end
stomp do
host 'localhost'
end
stomplet GlobalStomplet do
route '/live/socket'
end
I've tried also commenting out the web and stomp blocks but nothing changes.
Basically, the sockets are working, I can connect, and subscribe. In my stomplet, the on_subscribe method has a few debug lines
Rails.logger.debug "SESSION = #{subscriber.session}"
Rails.logger.debug "SESSION 2 = #{subscriber.getSession.getAttributeNames}"
Rails.logger.debug "SOCKET SESSION = #{TorqueBox::Session::ServletStore.load_session_data(subscriber.getSession)}"
And any other combination of these sort of things, but in every case I am given an empty session. The only exception, is when I explicitly load the session (as in the last debug line above) my session contains a session ID and something like TORQUEBOX_INITIAL_KEYS, but the session ID is not the HTTP session, and is simply something like session-1 and nothing useful.
I have an initialiser in the rails app setting up the torque box session store
MyApp::Application.config.session_store :torquebox_store, {
key: '_app_key'
}
I don't receive any exceptions from anything so I assume there are no obvious problems, but I've tried everything I can think of and still don't have a session that I can use.
What am I doing wrong?
I'm using Torquebox 3.1.0, Rails 4, and jRuby 1.7.11
Well, it seems I wasn't doing anything wrong per-se, but there seems to be an underlying bug in Torquebox (filing a bug report now)
It seems as though torque box web apps are quite happy with me assigning a custom key for the session store, and every works as expected. Unfortunately, it seems as though the stomplets are looking for the normal JSESSIONID only, and ignore the custom defined key.
To confirm, I remove the custom key, and it worked. I then reintroduced it, and again it stopped working. With the key still in place, I manually set the JSESSIONID cookie value, and reconnected and suddenly my session appeared.
I have a basic Sinatra app deployed to Heroku. I have 'enable :sessions' in the app and nothing else do do with sessions except setting/accessing the sessions data. The app works well, but if I have a browser session open, and re-deploy to heroku, then when I use the same browser session, I get "Error H13 (Connection closed without response)" and a Application Error in the browser. I can't find out anything more about the error.
If I delete cookies for the domain, then the app starts working again.
so, again, it's: 1) Deploy app, use app in new browser session, all is well. 2) 'git push heroku master' 3) use same browser, E13
tried setting the Rack::Session::Cookie secret explicity but it makes no difference.
Have also run the app in production mode locally, but can't replicate this.
I'd rather not ruin anybody's day if they happen to be using the app when I do a deploy. Any ideas where else to look to track this down?
You need to set the session secret as well:
configure do
enable :sessions
set :session_secret, ENV['SESSION_SECRET'] ||= 'super secret'
end
This was a Rack 1.4.0 bug concerning the way invalid session digests were handled. github.com/rack/rack/issues/299 problem was solved by upgrade to Rack 1.4.1