HTTP basic authentication over Devise - ruby-on-rails

I am trying to use HTTP Basic Authentication over Devise for my Rails app. I have done following settings ->
config.http_authenticatable = true in the devise initializer
And
:database_authenticatable strategy in my USER model.
When I try to access a web service
mysite.com/user/list.json?email=test#mysite.com&password=test123
The username password is not recognized. A credentials box pops up where on entering the credentials I am authenticated to use the data.
How can I provide the credentials in the URL and avoid the pop up prompt?

HTTP Basic Auth, is passed through HTTP Headers, not GET or POST params.

I found a way of doing this-->
http://username:password#test.com/users/list.json?

Related

Rails Devise Token Auth Reset Password Flow - How to deep link from 302 redirect

I am trying to implement a reset password flow with devise token auth gem: https://github.com/lynndylanhurley/devise_token_auth
The end client will be a mobile device (e.g. iOS, Android). I am uncertain as to how the native clients will be able to catch the url to reset password and display a password form through deep linking. Here are the general steps as I understand them:
Fire a POST to auth/password with an email and redirect_url
This will send an email with a link to reset the password and an included reset_password_token query param.
Clicking on the link fires a GET to auth/password/edit
This GET then fires a http 302 redirect to the redirect_url sent in the first request with the reset_password_token in the query params. The redirect_url should route to the form intended to display a password field to reset a user's password. On mobile clients, ideally this would be handled as a deep link.
I am confused as to how the mobile apps will handle step 4. I heard it's difficult to deep link in a native app through a 302 redirect/may not be possible. Is there a part of the flow I am misunderstanding perhaps? I'd appreciate any clarity on how I can implement this flow successfully for mobile clients.
For reference here is the guide I am following from the official docs: https://devise-token-auth.gitbook.io/devise-token-auth/usage/reset_password

Devise/OmniAuth Override default callback url

I'm using Devise 3.5 with Omniauth in a Rails 4 app. I've created an integration with Facebook that allows a user to connect their Facebook account to my app. Currently when the user clicks the connect button, they're sent to /user/auth/facebook and then redirected to the callback url that Omniauth generates: /user/auth/facebook/callback. What I'd like to do is manually override this callback url in some cases - meaning that I don't want to override it in an initializer - with a fully qualified url. For example, if a user starts out on http://www.example.com/ I might want to override the default callback url with http://app.example.com/user/auth/facebook/callback.
My app has dynamic subdomains and a user will (almost) always begin the authentication process on a subdomain. Unfortunately it seems that Facebook doesn't support wildcards in oauth redirect urls, which is why I want the ability to detect if a user is on a subdomain and adjust the callback url to something that I have whitelisted on my Facebook app so that the authorization process succeeds.
From what I've read, the url helper omniauth_authorize_path accepts additional arguments to be passed on as parameters. I've tried passing a custom callback path in like so, but without success:
user_omniauth_authorize_path(:facebook, callback_path: #custom_callback)
I've also tried changing callback_path to redirect_url and redirect_uri, but nothing seems to work. When I look at the link that's generated, it does indeed include the callback as a parameter in the url, but when I click the link, I'm redirected back to the default callback url instead of the custom callback url.
Here's how I solved this problem. I'm sure there are other ways, but this seems like the simplest most elegant solution I could come up with.
In config/routes.rb I set up an auth subdomain. All my Oauth connect requests will start on different subdomains and then Facebook is set up to forward those users back to the auth.example.com subdomain.
constraints AuthRedirect do
devise_scope :contact do
get '/auth/facebook/callback' => 'omniauth_callbacks#facebook'
post '/auth/facebook/callback' => 'omniauth_callbacks#facebook'
end
end
Here is /lib/auth_redirect.rb. This just checks if the subdomain is auth and captures that traffic. This is placed at the top of my routes list so as to take precedence over other subdomains.
class AuthRedirect
def self.matches?(request)
request.subdomain.present? && request.subdomain == 'auth'
end
end
Then in my client, when a user clicks the Connect with Facebook button, I send them to /auth/facebook?contact_id=<id>. From here Devise directs them to Facebook, which then redirects them back to https://auth.example.com/.
Then in OmniauthCallbacksController#facebook I can pull the user's id from the omniauth params like so:
auth = env["omniauth.auth"]
contact = Contact.find(env['omniauth.params']['contact_id'])
From here I can persist the credentials to the database and the redirect the user back to the appropriate subdomain. This solution avoids problems with CSRF tokens and more importantly does not require me to use Ruby/ERB to build the omniauth authorize path that the user is sent to when they click the connect button.
have you tried with redirect_uri ?
user_omniauth_authorize_path(:facebook, redirect_uri: #custom_callback)
EDIT: sorry I missed the second part of your post.
I actually have the same problem in production but it works perfectly on a staging environment. The only difference is about the callback url on staging which has one more subdomain *.staging.domain.com
By the way you can provide a static callback_url in the devise initializer file:
config.oaumniauth :facebook, ..., callback_url: 'url right here'
I'm on this issue this yesterday.
Either I provide a static callback url but facebook raises me an CRSF error:
omniauth: (facebook) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected
Or I let devise set the callback_url dynamically which gonna look like
https://*.domain.com/DEVISE_MODELS/auth/facebook
and in this case I get a straight non matching/whitelisted callback url during FG loggin in process.
EDIT2:
GOOD! I made it. I'm able to get oauth login in with wildcard subdomain.
Provide a static callback_url in your devise initializer
add the domain to your session store as :
domain: ".domain.com"
With that I'm getting neither CRSF error nor nunmatching CB url/whitelisted.
Hope it'll work for you !

Devise multiple domains authentication

I have 2 domains on one app - example1.com and example2.com. It is necessary to log in at all, when authorization in any of them via rails4 devise gem.
How is it implemented?
Check this answer. You must redirect your login request in domain1.dn, after if login success, redirect to domain2.dn and set cookies !

Rails 3 + Omniauth: pass extra params to the api server (DoorKeeper)

I am creating an API for my application. On one side, there is the API server (and the main app) and on the other, the client. The sever uses DoorKeeper to secure the API using OAuth 2.0 (basically turning the main app into an OAuth 2.0 provider) and the client is using OmniAuth with a custom strategy for my app.
The main app uses multitenancy using subdomains; so every client has its own subdomain. There is also a oauth subdomain that is routed to the DoorKeeper interface.
When a user clicks on the "Log in with my app" link, he gets redireced to the oauth subdomain. If he is not logged in to the main app, he needs to get redirected to the login page under the correct subdomain. So I need to pass the client's account name to the server so that DoorKeeper knows to which subdomain to redirect to.
How can I achieve that please?
I've researched on the subject and found out how to pass to OmniAuth params that will get passed to the callback action. Will those params be available to the server?
EDIT: I am not using Devise!
EDIT 2: Here is some code.
Client app session controller create action (log in with my app)
def set_client
self.current_client = Client.find(params[:client][:name])
redirect_to "/auth/catapult?client=#{self.current_client.account_name}"
end
As you can see, I append the client param to the OmniAuth route, but this param is not passed to the server app (DoorKeeper), so I have no idea where to redirect to on the server app.
DoorKeeper config
resource_owner_authenticator do
p params
User.find_by_id(session[:user_id]) || redirect_to(log_in_path)
end
In the redirect above, I need to specify the client's account name as subdomain, but I don't have this info (client's account name) since the params hash does't contain the client's account name that I passed (the client param)
I found out how to fix my problem. I had to dig in deeper into the OmniAuth source code. what I had to do is override the request_phase method in my custom strategy as follow:
def request_phase
redirect client.auth_code.authorize_url({:redirect_uri => callback_url, :catapult_client => request.params["client"]}.merge(authorize_params))
end
Where :catapult_client is, add any extra params you want to pass and it just works!
The simplest way is to pass the place-to-redirect-to-after-authenticating-successfully as a query param when they are redirected to the login page, so it's there as part of the GET request's querystring. Store it, and on a successful auth, redirect them there. You don't need to involve this data in the OAuth process at all.
Of course, I'm assuming that they all start at their subdomain too.
Edit:
When a user clicks on the "Log in with my app" link, he gets redireced to the oauth subdomain.
Assuming the user starts at mysubdomain.yourapp.com, they click on the "Log in with my app" link.
The link also contains a query parameter with the subdomain in it, so oauth.yourapp.com?redirect=mysubdomain.yourapp.com (or just oauth.yourapp.com?redirect=mysubdomain)
The user arrives at oauth.yourapp.com. The app stores the query parameter. The user puts in their details or is redirected to a serviceā€¦
The OAuth process is finished, the user has been authenticated.
Redirect the user back to the redirect parameter stored earlier.
This is how I do it, just not with Rails, but I don't see why you couldn't use this process with any framework. This, as I mentioned, depends on the user starting on the correct subdomain.

disable devise http authentication, when called with ajax

i am using devise in an application, and when a call is made via ajax, and the user has been signed out due to session expiry, devise shows http authentication... is it possible to make it so that it can send a js to let the caller know that the user is logged out...
Add this code to your Devise initializer file
config.http_authenticatable = false
config.http_authenticatable_on_xhr = false

Resources