Authenticating against external and then internal databases in rails - ruby-on-rails

A system I'm building requires us to authenticate against our clients database to pull user information from their database. However, they also want us to allow external users to log in and access this system. To authenticate against their database we're using DeviseLDAPAuthenticatable, and were planning on using Devise to add local users.
The plan of action at the high level is:
User puts in log in details
if ldap accepts these
log in
elseif local database excepts these
log in
else
fail
What I'm guessing is that I need to override the authenticate_user! method but it didn't seem obvious what I'd need to include to make sure that the LDAP users could still log in. This question seems like it would be helpful but doesn't explain how to get the session if we're authenticating with device.

Related

Centralised Login to multiple rails servers

The situation:
We have a rails application, which runs on 12 different servers (different sets of customers). User credentials are stored in the database of each server. We use Devise for auth.
We have an Android app that, when logging in, you have to select the correct server to connect to.
Requirements:
A centralised login page so users don't need to know which server/url to log in to. This is for the web and android. The user should either:
a) Type their username/email, and be forwarded to the correct server to login.
b) Type their username/email AND password, and be forwarded and logged in to the correct server.
Current Ideas:
Create a NoSQL db table with a list of usernames/emails with the server they need to log in to, the login page can grab the server and forward you on.
Use something like Auth0 to manage user data - however unsure how this would work with our current User credential tables spread across multiple servers.
This is not something I have a huge amount of knowledge on, and looking for criticism of the above ideas/better approaches.

Ejabberd and Ruby on Rails application

I have a Rails application with devise-like authentication and a lot of parts that depend on it. Now I want to add a chat between users using ejabberd (xmpp). I was searching through net and found that it's quite possible, but I can't understand how to make authorization in ejabberd server. For example user logins in a Rails app through login page with one credentials how to implement ejabberd loggining in this action? It will not be good to write like "please, put your user pw and ejabbered pw". Other way is to monkey-patch users registration, so ejabbered will use the same pw as user in the database and I will make authorization in one action, but will it be good? And how long user will be online in this way? Maybe I misunderstood something?
I've used rails extauth script like this https://github.com/geoiq/digitalgazette/blob/master/mods/chat/files/ejabberd-auth.rb and ruby_bosh gem for my application.
So now ejabberd is using my app to authenticate users. At login (for example) user's jid and password is using by ruby_bosh to make session and get jid, rid and sid saving them to session to use them later in a strophejs.

Why using an authentication_token instead of the normal authentication process?

I have a Rails web application, and I want to build a JSON API as well so I can have mobile applications bound to it.
I've been reading a lot about it, and I don't get it why so many people prefer to activate authentication_token authentication instead of the normal authentication process that Devise offers us.
So, the question is: why use authentication_token ? Any performance reason ? Any security reason ? What is the best way to authenticate through an API ?
authentication_token is basically used to authenticate user from outside
i.e. say you sent user a email containing the activation link containing the token, so when he clicks the link, he directly gets logged in.

Two tier sign in with Devise (Amazon style)

Let's imagine I have following scenario
User receives an email that there is a new item waiting for her
Clicks on a link and is able to either confirm or reject item (details skipped)
Can then access a list of all her items
The trick is that I would like to allow all this happen without user signing in but then limit access to other parts of the website (like sending an item to another user)
How I see it is that:
when user clicks a link she is signed in but only on tier 1 - with access only to confirm/reject action and read only to index of items (that's when Devise session is created)
when user wants to access other part of the website the sign in page is presented
when user comes to the website just by typing in the url http://example.com and wants to access own account she is asked to sign in.
after sign in session is "promoted" to tier which allows full access
after some time of inactivity session is downgraded to tier 1 for security reasons
My inspiration comes from how Amazon works - you can access in read-only most parts of the account but before performing any destructible actions you need to sign in.
Does anyone have any experience with such approach or can share some blog posts, etc?
I didn's find anything on SO and Google mostly returned things about two-factor auth which is not the case here.
I also understand that there are security concerns with links in email.
I have implemented a very similar behavior few months ago. I don't have very interesting resources to show you but I can explain a bit how you could organize or think about the problem to solve.
Description
For the problem you state, it looks like once you have identified a user, you have two different states you can give him:
limited access (perform certain actions, read most of the resources, etc)
full access (allows them to do anything they would normally do).
Having stated that, what you need to do is figure out in which cases you will give a user each access state (for example):
signing in with email token -> limited access
password -> full access
authentication_token -> full access
omniauth -> full access
After that, you will need to save this information in the user session. This should be done anytime the user is authenticated, as you will know what strategy was used to authenticate the user.
To know if a user can or cannot perform an action you will need two things, know what the user can do, and the current "access state". Depending on those you will decide wether the user is allowed or not to perform a certain action.
Whenever a user can't perform an action and is logged in with limited access you should bring him to the flow for verifying his crendetials. This flow is pretty simple, almost like a sign in but just with the password. Once you verify his crendetials you can upgrade his authorization to a full access one.
Implementation details
I recommend you to create a Authorization model which will represent the "access states" that I mentioned. This model will have to be serialized in the session so you should be able to build it from a simple structure and serialize it again into that structure. The simplest the better (a boolean flag, an array or maybe a hash). For the case mentioned, it looks like a boolean would do the job.
Regarding implementation details, I recommend you implementing this with a Warden after_atuhentication callback.
You could implement this with CanCan by creating you own Ability that would be built with an Authorization instance and a User instance.
I think you're confusing authorization and authentication. Devise is an authentication solution, meaning it handles the "proof me you are who you say you are" part. Authorization is the "Ok, I know who you are, now let's see what can you do". Devise doesn't provide an authorization system beyond the simple "logged/not logged". If you need a more complex authorization system, use an authorization gem. CanCan is very popular.

Block another user from accessing the Rails application with my authentication

I have hosted a rails application, an online examination system. The users need to get registered to get access to the system. So each user will be provided with a unique combination of credentials. Let us assume my user-name/password is demo/demo123. I want my app to block another person logging in to the system even if he knows my credentials. Any solution for such scenario.
Thanks for any help :)-
Using Cookie would be a better solution. When the user gets registered create a Cookie value specific to the User and System and in encrypted format (for security reason) and save it in the database corresponding to that user. Check for this Cookie token while logging in. When the user clears the cookie, s(he) can request the Administrator to clear out the DB cookie for creating a new one.
Using IP will not be a better solution since in a network, there can be dynamic IP's allocated to the PC's.
You could record the user's IP address in the database when they first log in, and only allow logging in using the same credentials but from a new IP address after some waiting period of, say, 1 hour, or until the current examination is complete. That should prevent more than one user being logged in to the same user account within a short time period.
The user's IP address can be accessed in a Rails controller using request.remote_ip.
You could use the lock gem to add a password to the entire application.
First, add to your Gemfile.
gem 'lock'
Then
bundle install
Next, create your password
rails g lock:create_password_file yourpasswordhere
Finally, add lock your application controller, or whatever you'd like (see documentation).
ApplicationController < ActionController::Base
lock
end

Resources