Why using an authentication_token instead of the normal authentication process? - ruby-on-rails

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.

Related

spring security role-based needed for full stack app?

I am implementing a basic login app. here are the features:
Upon successful login, there should be a welcome page that shows the name, username and role (manager/user).
If the user has a manager role, the welcome page will have a link to access a restricted webpage.
This restricted webpage can only be accessed by a manager role and not by other user roles.
implement logout functionality.
If the userid or password is not valid, I should remain at the login page with an error message "Invalid userid or password".
All data should be stored in a database.
The application should demonstrate MVC pattern...
my schema:
enter image description here
i am using react js for the front end. i build the backend using spring security with the role-based authorization where certain url can be accessed by certain role. i already do a testing on backend end using postman where i try to access /restricted and it responded with 401 if i use ROLE-USER instead of ROLE-MANAGER by using the mvcMatchers(). now the confusing part is the frontend
i noticed i can do all the necessary validation on the front end. i dont even need to do mvcMatcher() on the backend as i can just load the userdetails and roles and ask react to validate for me! hell, i dont even need to use role-based authorisation. i just need to add extra field in user table named "role" and use that to check for item 3 and display the role on item 1. i just need 1 table, not 3. i can even ask react to redirect to /login if user is trying to access /welcome without login, or disable /unauthorised if user role is USER.
but i dont feel right about this way. i'm confused.
a. whats the best approach?
b. is role-based only applicable to rest-api services, not full stack app? from what i see front end can do ALL validation
back end repo
front end repo
a. The Best approach is to have authorization at the back-end level because your React front-end is not the only way to access the back-end. If the back-end doesn't have authorization implemented, then even if you have validation on the front-end, a malicious user can use any other HTTP client to access the back-end without authorization.
b. Role-based authorization is applicable in all scenarios in which you want to allow access to resources based on user roles, no matter which stack is used.

How to add additional custom criteria for authorization or token creation in Spring Oauth?

We have implemented Spring Oauth authorization+resource server that can be used for external applications.
Now we would like to add custom checks before some oauth calls returns in the authorization server, most importantly for the authorization code but also before allowing returning a token sometimes.
An example use case might be that which users that are allowed to login for a specific client_id might vary and if not allowed this should generate a redirect back with an error.
So for example a user might trigger a login from a third-party app, redirected to our authorization server and shown a login page, however after login it is discovered (through our business logic) that this specific user is not allowed to authorize access to that specific app/client id.
What is the best way to achive this result in a way that is consistent error handling in Spring oauth?
Also, a related question is also how to resolve the client details before the login screen shown so more specific client details can be shown when logging in?
We could parse the client_id parameter manually but maybe there is a more elegant way to hook into Spring oauth to solve this?
(sorry for dual question but its sort of related and the first question is the most important one)

Rails Devise multiple concurrent sessions

I am developing a web application using rails and devise for the authentication. There are two types of users, one who are able to have multiple concurrent sessions (super) and the others who can only have a simultaneous session (normal). In order to implement this behaviour, I have added a new field on the User model to store the authentication_token (generated in the SessionsController#create). Also, I added a new filter to the ApplicationController which check if the stored token in the session is equal to the saved on the User model when it is a normal user. When it is not the same authentication token, we logout the normal user.
Now I am developing a new ionic mobile application which needs to login to the same rails application. However, in this case all user types can have multiple concurrent sessions. In order to do this, we would like to continue using devise (although we have also considered to use doorkeeper with password flow).
I am not sure about the best approach to get this. The main problem is to detect if we are accesing the API with the rails or ionic application. One approach is to add a parameter but I don't like to use a parameter in all requests. Another approach it is to use browser gem, but we can access the web from a browser in the mobile.
When we uses the rails application, we can use the same behaviour described above. Otherwise, I think it is not necessary to do anything because devise permits concurrent sessions by default.
Another posibility it is to use a new model to store the authentication token and its type (rails or ionic). If we are using the rails application, then we query the rails authentication token and override it (or create if it does not exist). On the opposite, we add the new authentication_token as a new instance related with the user model. With this behaviour we can manually control the expiration of the tokens and store more information (IP, browser...).
I am not sure about the best approach to achieve this behaviour. Thanks in advance.

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.

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.

Resources