omniauth google-oauth2 with devise - invalid_credentials and "Csrf detected" - devise

Dear Fine People of SO:
I am developing a Ruby app on Rails 3.2.12 (and I am still new to it).
I am trying to get Devise working with Omniauth... the first strategy I am trying is Google_oauth2.
I have it working to the point where Google has redirected back into my localhost:3000 instance after selecting the credentials I want to use in Google.
Upon this redirection back into localhost, I see a flash notice:
Could not authenticate you from GoogleOauth2 because "Csrf detected".
The server logs contain this:
Started GET "/users/auth/google_oauth2" for 127.0.0.1 at 2013-03-21 08:57:01 -0400
(google_oauth2) Callback phase initiated.
(google_oauth2) Callback phase initiated.
(google_oauth2) Authentication failure! invalid_credentials: OmniAuth::Strategie
s::OAuth2::CallbackError, OmniAuth::Strategies::OAuth2::CallbackError
Started GET "/users/auth/google_oauth2/callback?state=7849a3762d07e7f89e69b4aa46
7efc7b7b2c21655193396b&code=4/v-dSBwAvQUUZL87iNV_yk_Z8s_x0.cnqsdbDX4gUYaDn_6y0ZQ
NgQ9hAaewI" for 127.0.0.1 at 2013-03-21 08:57:40 -0400
Processing by OmniauthCallbacksController#failure as HTML
Parameters: {"state"=>"7849a3762d07e7f89e69b4aa467efc7b7b2c21655193396b", "cod
e"=>"4/v-dSBwAvQUUZL87iNV_yk_Z8s_x0.cnqsdbDX4gUYaDn_6y0ZQNgQ9hAaewI"}
Redirected to http://localhost:3000/users/sign_in
Completed 302 Found in 0ms (ActiveRecord: 0.0ms)
I noticed that I get exactly the same result if I simply put the callback URL into the browser directly, without any parameters supplied.
http://localhost:3000/users/auth/google_oauth2/callback
What can I try? What other info can I provide?

Answering my own post.... I'm past this. I'm not entirely sure why, but I have some clues that might be worth passing on.
There are a bunch of other similar issues reported related to the omniauth-facebook strategy. They did not seem to apply to google, so I didn't look too deep. Then I tried to configure the FB strategy, and got the same problem. The FB solution was to revert the omniauth-facebook gem back to 1.4.0.
gem 'omniauth-facebook', '1.4.0'
This also automatically reverted the omniauth-oauth2 gem (I've not wrapped my head around the gem thing yet). When I tried the google link again, it did not throw the same Csrf detected message... Hmmm... reverting the FB gem fixed google ---- Need a disclaimer here, other things might have been the problem here, but I think I have it correct.
There is another problem worth mentioning. The log i provided above showed 2 repeated log messages....
(google_oauth2) Callback phase initiated.
(google_oauth2) Callback phase initiated.
This reveals another (maybe related) problem. It means that the callback was executed twice. Once I got past the CSRF issue, i started getting the invalid_credentials problem all by itself. The reason for the error is the duplicate callback call. Apparently, Oauth2 only allows a single use of the credential. The second use is invalid.
I used railscast #235 as my guide:
http://railscasts.com/episodes/235-devise-and-omniauth-revised?autoplay=true
It had me add "provider" calls in the omniauth.rb initializer. and config.omniauth calls in the devise.rb initializer. I guess these somehow result in duplicate callbacks?!?!?
Removing the entry from omniauth.rb got me past that one.
So there you have it. My second SO question, and my second question where I'm the only responder. Not sure if its because they were dumb or hard... I hope the latter.

I had the same problem. In my case I have initialized google-oauth credentials in both devise.rb and also in omniauth.rb; because of this the callback was happening twice. After removing google-oauth credentials from devise.rb, this CSRF token problem got solved.

Just stumbled onto this issue, but your fix didn't work for me. I am using the following gem versions;
oauth2 (0.8.1)
omniauth (1.1.4)
omniauth-oauth2 (1.1.1)
omniauth-facebook (1.4.1)
omniauth-google-oauth2 (0.2.1)
What did fix my problem was adjusting my omniauth.rb initialiser to the following;
OmniAuth.config.full_host = "http://localhost:3000"
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, KEY, SECRET,
provider :google_oauth2, KEY, SECRET, :scope => "userinfo.email,userinfo.profile"
end
The key part was to add the 'scope' parameter for google_oauth2, without which I was getting auth failures.
I based my install of this blog: http://sreeharikmarar.blogspot.com.au/2013/01/omniauth-devise-authentication-using.html
A related post: OmniAuth using google oauth 2 strategy scope failure

Related

JWT::InvalidIssuerError: Invalid issuer. Expected accounts.google.com, received https://accounts.google.com

My website didn't have a problem in the past for login using Google oauth. Suddenly I am getting the above error.
You don't need to downgrade your omniauth-google-oauth2 version. You can simply add verify_iss: false to your config.omniauth.
config.omniauth :google_oauth2,
Rails.application.secrets.oauth_google_id,
Rails.application.secrets.oauth_google_secret,
verify_iss: false
For more info, look at the verify_iss in https://github.com/zquestz/omniauth-google-oauth2#configuration
I got same issue on RoR with "omniauth-google-oauth2 - 0.5.1". I have to user old version (0.5.0) and it's working fine. I think google has changed behavior on authentication process.

How to integrate Devise and SAML?

What is the best way to get SAML working with the widely used https://github.com/plataformatec/devise?
https://github.com/apokalipto/devise_saml_authenticatable doesn't do signed/encrypted auth requests and that's a deal breaker for us, and the usual sources haven't helped.
Devise's Omniauth integration, for example, requires an app ID and secret that Onelogin's SAML connector doesn't provide.
So, the answer that worked for me is to use the gemlfile and omniauth.rb settings as outlined in https://github.com/PracticallyGreen/omniauth-saml#usage and then to follow devise's omniauth tutorial at https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview, replacing facebook with SAML. Note that you mightn't need the UID field mentioned in the tutorial, depending on how your IdP stores their users (and you wouldn't get a permanent UID if you use the transient nameid format). Use whatever uniquely identifies your user at the IdP, which is quite possibly an email address.
The devise.rb stuff added by ioblomov doesn't seem to add anything and in fact causes an issue if you do it as well as doing an omniauth.rb file. This creates a situation where the IdP does two callbacks, one using the omniauth.rb settings and another using the devise.rb settings. Given that the devise.rb settings are not complete (they don't have a consumer url for example), I can't see how even having it on its own could ever work. It is not clear to me what "devise integration" even means in the context of omniauth-saml. Once you get an auth response back (which you will just from using the omniauth.rb settings), then all you have to do is use the devise method sign_in_and_redirect in your callback controller and then you have all the usual devise stuff available to you for that user. I will submit a PR to omniauth-saml but I wouldn't be holding my breath as the project appears to be sporadically maintained at the moment.
I had to deal with recently to hook a rails app up to a university network using Shibboleth for SSO. I ended up using devise, omniauth and running on Apache with mod-shib2. I am not sure if you are using Shibboleth specifically but it is built on top of SAML. The lightweight rack-saml implementation did not work for me.
Turns out the Devise config's parameters were wrong. I documented the correct settings in a fork/PR:
https://github.com/omniauth/omniauth-saml#devise-integration

Rails: OAuth::Unauthorized 401 Authorization Required using OmniAuth-Twitter

I have implemented several different strategies found in StackOverFlow, but so far, none seem to affect the error being thrown:
OAuth::Unauthorized
401 Authorization Required
I am following Ryan Bates' RC #241 and get to the point where I click "Sign-in with Twitter" and I get the error. I went ahead and added the response route to the routes.rb file as listed here:
routes.rb:
match 'auth/twitter/callback', to: 'user#update'
thinking that the error might be caused from the callback function. Same error. A look at my dev.log shows this:
Started GET "/auth/twitter" for 127.0.0.1 at 2014-09-16 18:52:08 -0600
(twitter) Request phase initiated.
OAuth::Unauthorized (401 Authorization Required):
oauth (0.4.7) lib/oauth/consumer.rb:216:in `token_request'
oauth (0.4.7) lib/oauth/consumer.rb:136:in `get_request_token'
omniauth-oauth (1.0.1) lib/omniauth/strategies/oauth.rb:29:in `request_phase'
omniauth-twitter (1.0.1) lib/omniauth/strategies/twitter.rb:60:in `request_phase'
omniauth (1.2.2) lib/omniauth/strategy.rb:215:in `request_call'
omniauth (1.2.2) lib/omniauth/strategy.rb:183:in `call!'
omniauth (1.2.2) lib/omniauth/strategy.rb:164:in `call'
omniauth (1.2.2) lib/omniauth/builder.rb:59:in `call'
...
script/rails:6:in `require'
script/rails:6:in `<top (required)>'
-e:1:in `load'
-e:1:in `<main>'
So I know the issue is with the authentication with Twitter going out. Must be the KEY and SECRET, right?
Now, I have put the KEY and SECRET in as ENV[] variables, as direct strings to the environment/development.rb file, taken out the "ENV[]" variables, etc., as per suggestions found all over Stack.
My KEY and SECRET now reside in a custom configuration as discussed here...
config/initializers/social_media.rb:
TWITTER_CONFIG = YAML.load_file("#{::Rails.root}/config/twitter.yml")[::Rails.env]
The config/initializers/omniauth.rb file:
OmniAuth.config.logger = Rails.logger
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, TWITTER_CONFIG['app_id'], TWITTER_CONFIG['secret']
end
Any ideas on the ActionController: Exception caught OAuth::Unauthorized - 401 Authorization Required? This is probably a Noob error, but my Google-Fu is just Google-F'ed right now...
After a night of tearing my hair out, I took at look at the callback URL on Twitter developer console.
Save yourselves some trouble and don't forget to set this. It's not mentioned directly in the RailsCast, although Ryan does briefly pass over it.
When you set the callback URL, don't just put //localhost:3000 it won't work. Instead use:
http://127.0.0.1:3000/
I had this same issue when working on a Rails 6 application with omniauth-twitter and devise gems
I had added the API Key and the API Secret Key to my Rails 6 application, but when I try to test the Twitter Authentication, I run into the error below:
OAuth::Unauthorized 401 Authorization Required
Here's how I solved it:
I added the following Callback URLs to my Twitter developer account:
http://localhost:3000/auth/twitter
http://localhost:3000/auth/twitter/callback
http://localhost:3000/users/auth/twitter
http://localhost:3000/users/auth/twitter/callback
Note: Replace localhost:3000 with your actual host. Also, the routes used for the callback URLs should match the ones that were set up in your application.
Resources: How to Sign in with Twitter using Devise, Omniauth, and Ruby on Rails
That's all.
I hope this helps

EmberAuth and Rails 3 - session cookie sticks around after signout, rails treats user as authenticated

I have an ember app accessing a Rails API with devise for authentication, more or less following the ember-auth-demo github project.
Everything works, but in my testing I've noticed that if I sign in and out and then try to register a new account, rails complains with:
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 2ms (ActiveRecord: 0.2ms)
Googling has revealed that this is to prevent authenticated users from creating new accounts, which seems like a sound policy I shouldn't necessarily circumvent.
However, it's curious because my front-end ember app is not in an authenticated state. Looking at my local cookie store, remember_token is successfully destroyed on signout. However the session cookie is still hanging around. If I manually destroy that, then everything is back to working as expected, the user is not considered authenticated by the back-end app and processes the request normally.
For brevity, the relevant files are in this gist: https://gist.github.com/DVG/5975064 , but my sign_out functions are here:
#EmberAuth Signout Method
App.ApplicationController = Ember.Controller.extend
signOut: ->
App.Auth.signOut()
App.Auth.destroySession()
#Rails SessionsController#destroy
def destroy
return missing_params unless params[:auth_token]
resource = resource_class.find_by_authentication_token(params[:auth_token])
return invalid_credentials unless resource
resource.reset_authentication_token!
render json: {user_id: resource.id}, status: 200
end
The issue was I was storing the token in the session. Had to disable it with:
config.skip_session_storage = [:http_auth, :token_auth]
in the devise initializer

where in the Rails 3 stack are cookie_store-based sessions verified?

Assuming one is using :cookie_store, rails session are stored client-side in a signed (but unencrypted) string in a cookie.
Relevant documentation implies that this signature is verified on the server for each request, but I haven't been able to track down where this actually happens. Where in the Rails stack is the session hash verified? Is there something I need to turn on or check?
This is distinct from protect_from_forgery, which as I understand it serves to protect non-GET requests (e.g. form submissions), correct?
It's part of the actionpack gem. File action_dispatch/middleware/cookies.rb, line 291