Environment
Ruby 2.7.4 (Rails API only)
Rails 6.0.4.1
Devise 4.8.0
Omniauth1.8.1
Current behavior
Getting omniauth missing_credentials? error. The request.params is always an empty hash even though I provide username and password in the request body via POST method. I can see the body params when debugging actual controller, but it looks like those params are not passed to omniauth request.
Controller:
module Api
module V1
module Auth
class OmniauthCallbacksController < Devise::OmniauthCallbacksController #< ApplicationController#
include ActionController::Cookies
def ldap
puts request.env['omniauth.auth'] # => NULL
end
def failure
puts "request.env['omniauth.auth']: #{request.env['omniauth.auth']}" # => NULL
puts "request.env['omniauth.params']: #{request.env['omniauth.params']}" # => {}
puts "params: #{params}" # => { "username": "myusername", "password": "mypassword" }
render json: { status: "fail" }
end
end
end
end
end
Application.rb:
config.api_only = true
config.session_store :cookie_store, key: '_interslice_session'
config.middleware.use ActionDispatch::Cookies
config.middleware.use config.session_store, config.session_options
Routes.rb:
devise_for :users, controllers: { omniauth_callbacks: 'api/v1/auth/omniauth_callbacks' }
Devise.rb:
config.omniauth :ldap, :host => 'XXX.com',
:port => 389,
:method => :plain,
:base => 'cn=accounts,dc=int,dc=dostack,dc=io',
:uid => 'uid',
:try_sasl => false,
:bind_dn => "uid=XXX,cn=users,cn=accounts,dc=int,dc=dostack,dc=io",
:password => "xxxxxxxx"
Response:
Expected behavior
Authenticate using omniauth (LDAP or using any other omniauth provider)
Related
I'm authenticating against LDAP server in my rails application,
the code below is working locally but not on the server.
On the server it throws Net::LDAP::BindingInformationInvalidError (Invalid binding information) when trying to login in the app but works through the console
I'm pretty new to Ruby and can't figure out the proper way to debug it... I know the LDAP configuration is right because i can authenticate and bind from the console or on my local development environment.. I tried to pass :verbose => true to the LDAP constructor but without effect...
require 'net/ldap'
require 'devise/strategies/authenticatable'
module Devise
module Strategies
class LdapAuthenticatable < Authenticatable
def authenticate!
if params[:user]
ldap = Net::LDAP.new :host => 'XX.XX.XX.XX',
:port => 636,
:connect_timeout => 5,
:base => 'CN=Configuration,DC=internal,DC=XX,DC=XX',
:encryption => {
:method => :simple_tls
},
:auth => {
:method => :simple,
:username => ENV['LDAP_USER'],
:password => ENV['LDAP_PASSWORD']
}
result = ldap.bind_as(:base => "OU=Users,OU=XX,DC=XX,DC=XX,DC=XX",
:filter => "(userPrincipalName=#{email})",
:password => password,
)
if result
user = User.find_by(email: email)
success!(user)
else
return fail(:invalid_login)
end
end
end
def email
params[:user][:email]
end
def password
params[:user][:password]
end
end
end
end
Warden::Strategies.add(:ldap_authenticatable, Devise::Strategies::LdapAuthenticatable)
SOLVED
turned out it was the ENV variables that were not read.
Maybe that account is not authorized? Sounds like the problem is in the binding configuration: base => "OU=Users,OU=XX,DC=XX,DC=XX,DC=XX"
More information from other users who encountered this error:
https://gitlab.com/gitlab-org/gitlab-ce/issues/21937
LDAP groups authentication fails: Invalid Binding Information
I am trying to write tests for OmniAuth users and after setting up my test_helper, I am running into and a bad URI error.Sharing the details below:
test_helper.rb
# OmniAuth auth mock for testing
def setup_omniauth_mock (user)
OmniAuth.config.test_mode = true
OmniAuth::AuthHash.new ({
'provider' => 'google',
'uid' => '123545',
'user_id' => '2',
'first_name' => 'X',
'last_name' => 'XYZ',
'email' => 'xxyz#example.com',
'image' => 'https://lh3.googleusercontent.com//photo.jpg',
'oauth_token' => 'abcdef12345',
'oauth_expires_at' => DateTime.now,
})
OmniAuth.config.add_mock(:google, OmniAuth::AuthHash.new)
get '/auth/":google"/callback'
Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:google]
get '/auth/:google/callback'
end
The error I am getting:
test_validating_a_Google_OAuth_user#SessionsControllerTest (0.49s)
URI::InvalidURIError: URI::InvalidURIError: bad
URI(is not URI?): http://www.example.com:80/auth/":google"/callback
test/test_helper.rb:42:in `setup_omniauth_mock'
Now I followed the documentation here [Oauth Integration Testing][1]
[1]: https://github.com/omniauth/omniauth/wiki/Integration-Testing but I think there is something I am doing wrong.
Can someone please help me guide through this.
Thank you!
J.
I actually resolved it by cleaning things a bit.
My test_helper.rb now:
# OmniAuth auth mock setup for testing
setup do
OmniAuth.config.test_mode = true
Rails.application.env_config["omniauth.auth"] =
OmniAuth.config.mock_auth[:google]
end
#teardown OmniAuth mock setup
teardown do
OmniAuth.config.test_mode = false
end
#Google OAuth mock
def google_oauth2_mock (user)
OmniAuth.config.mock_auth[:google]
OmniAuth::AuthHash.new ({
'provider' => 'google_oauth2',
'uid' => '123545',
'user_id' => '2',
'first_name' => 'X',
'last_name' => 'XXYZ',
'email' => 'xxyzjam#example.com',
'image' => 'https://lh3.googleusercontent.com/photo.jpg',
'oauth_token' => 'abcdef12345',
'refresh_token' => '12345abcdef',
'oauth_expires_at' => DateTime.now,
})
end
I put the routes in the individual tests, and that allowed me to run the tests suite smoothly.
Hope I am able to save you some time and frustrations.
I am using Rails with Devise and I would like to use Mandrill to send out the different email messages.
I have found examples on subsclassing the Devise Mailer and using Mandrill, but the example uses Mandrills templates, which i don't want to use.
I would rather use Devise's email templates for this. My question is when I subclass the devise mailer, like this:
class MyMailer< Devise::Mailer
helper :application # gives access to all helpers defined within `application_helper`.
include Devise::Controllers::UrlHelpers # Optional. eg. `confirmation_url`
default template_path: 'devise/mailer' # to make sure that your mailer uses the devise views
def confirmation_instructions(record, token, opts={})
options = {
:subject => "Password Reset",
:email => record.email,
:name => record.name,
:global_merge_vars => [
{
name: "password_reset_link",
content: new_conformation_path(record)
}
],
}
mandrill_send options
end
def reset_password_instructions(record, token, opts={})
options = {
:subject => "Password Reset",
:email => record.email,
:name => record.name,
:global_merge_vars => [
{
name: "password_reset_link",
content: new_password_path(record)
}
],
}
mandrill_send options
end
def mandrill_send(opts={})
message = {
:subject => "#{opts[:subject]}",
:from_name => "Accounts",
:from_email => "accounts#example.com",
:to =>
[{"name" => "#{opts[:name]}",
"email" => "#{opts[:email]}",
"type" => "to"}],
:global_merge_vars => opts[:global_merge_vars]
}
begin
sending = MANDRILL.messages.send_template opts[:template], [], message
rescue Mandrill::Error => e
Rails.logger.debug("#{e.class}: #{e.message}")
raise
end
end
end
How do i generate the email from the devise templates to send to mandrill?
I want to use seperate admin login for my application using idenity provider.
I have written this in config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :identity, :model => Credential, :on_failed_registration =>SessionsController.action(:register)
provider :identity, :model => Credential, :name => 'admin', :on_failed_registration => SessionsController.action(:login_admin)
provider :google_oauth2, '000000000.apps.googleusercontent.com', '00000000000'
end
In config/routes.rb
match '/auth/admin/callback', :to => 'sessions#authenticate_admin'
In app/controllers/sessions_controller.rb
def authenticate_admin
auth_hash = request.env['omniauth.auth']
session[:admin_user] = auth_hash['user_info']['email']
if admin?
redirect_to '/'
else
render :text => '401 Unauthorized', :status => 401
end
end
But when i try to access request.env['omniauth.auth'], it always gets nil. While it is accessible when using default callback for normal users at sessison#create action. I just want to know if there is anything that has been missed in this code. I am following this blog http://www.intridea.com/blog/2011/1/31/easy-rails-admin-login-with-google-apps-and-omniauth.
I got Devise setup and working for my app. When i add
gem omniauth-google-oauth2
im getting an error in controller sign_in_and_redirect method.
Error:
NoMethodError (undefined method `serialize_into_session' for String:Class):
app/controllers/users/omniauth_callbacks_controller.rb:9:in `google_oauth2'
Code:
omniauth_callbacks_controller.rb
def google_oauth2
#user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user)
if #user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
sign_in_and_redirect sites_path, :event => :authentication
else
session["devise.google_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
user.rb
def self.find_for_google_oauth2(access_token, signed_in_resource=nil)
data = access_token.info
user = User.where(:email => data["email"]).first
unless user
user = User.create(email: data["email"],
password: Devise.friendly_token[0, 20]
)
end
user
end
devise.rb
require "omniauth-google-oauth2"
config.omniauth :google_oauth2, 'CLIENT_ID', 'CLIENT_SECRET', {access_type: "offline", approval_prompt: ""}
Please let me know if im missing something.
Your config is good, but I use for this situation instead omniauth-google-oauth2, this gem https://rubygems.org/gems/omniauth-openid.
Add to your /config/initializer/devise.rb the next:
require 'openid/store/filesystem'
config.omniauth :open_id, :store => OpenID::Store::Filesystem.new('/tmp'), :name => 'google', :identifier => 'https://www.google.com/accounts/o8/id', :require => 'omniauth-openid'
and after inside your omniauth_callbacks_controller.rb change the method User.find_for_google_oauth2... by User.find_for_open_id...
on your user model change the self.find_for_google_oauth2 by self.find_for_open_id.
Try with this gem please!