Limit user access to api calls? - rest

I am creating a rest api to be the backend for a messaging app. I want a user to only have access to their own data. For example user1 can call /users/user1 but not /users/user2. How would I go about doing this.
So first the user will login and be authenticated via their username and password. But where do I go from here? I was thinking of storing a token with the users data so when they access it I can verify that the pair matches but there must be a better way to do this. Do I need to restructure my api?

After the user logs into the system, you should provide them a token or initialize a session for that user. In each consecutive call, the user should send the token to the API. As long as the token/session is alive user should be able to call the API.
You should have a way to verify the user token in the backend for each API call. A very popular way of doing this is to use JWT(JSON Web Tokens) based authentication.
See here for an example using python and flask: https://realpython.com/token-based-authentication-with-flask/
Once you verify the user, you should parse the user id to the database query in order to filter out the data for that user.
Even though I don't understand your full use case, it seems like you need to restructure your API calls as well. You should not provide API calls per user. What happens when the numbers of users increase in your system dynamically?
So you should either accept user id as a parameter or you should let the JWT authenticator take care of it.
Example REST API call would be
GET /user/data?userId=1234

Related

Call REST API with and without user context

I have a user microservice. This microservice uses token authorization. Now it's consumed by web application. Workflow looks like this:
user logs in to web application using AzureAd OpenIdConnect;
web application receives access token (authorization code flow);
web application gets user details from user service passing access token in HTTP request header.
Also I have a daemon microservice where I don't have a user context. I want to allow this daemon service to get user details from user service too. I'm going to use client credentials flow for that case.
How to organize user service rest api properly?
I'm thinking about this approach:
user's data is available at this URL /users/{userId}/info;
applications with user context (i.e. access token is issued for particular user using authorization code flow) can consume data only for current user or current user is an admin and can work with another user's data;
daemon applications without current user (i.e. access token is issued for the application itself using client credentials flow) can read data for any user.
What is the best practices for such cases?
I think the best and more restful approach to define this API is to build a unique endpoint /users/{id}.
Where id can be an actual real user id or a predefined value like 'me'. It is the user service the one who has to retrieve from the token the user information in case that the id value is 'me'.
The other changes that I would make is to use users instead of user because rest good practices say that the elements in the URL are collection.
And the last one, to not use info because it is redundant. Because when you query for an entity obviously you want its info

Shiro: Is it possible to get the URL in doGetAuthenticationInfo(AuthenticationToken token)

I am trying to create a RESTful web service using Jersey framework on google appengine. I am using apache shiro for authentication.
Let's say I have the following scenario:
There is a admin user pre-configured which creates other user and provides the username and password offline to each of those users.
For the normal users, there are a number of REST APIs. There is one API:
GET /tokenInfo which should use username and password for authentication and return a UserId and token as response.
For all the other REST APIs, I want the credential used for authentication to be the UserId and Token instead of Username and password.
So basically it a scenario where the credential pair used for authentication varies based on the API.
How can I achieve this in shiro. From what I understand, doGetAuthenticationInfo() passes the credentials sent by the client and expects you to validate, but in this case, I need to know which API is called. So is there a way to get the URL?
If no then what other way is there to achieve this?
Sounds like you would need to create a custom filter, to build the type of token you want to pass to your realm, take a look at one of the defaults as an example:
https://shiro.apache.org/web.html#default-filters

How to identify the user is active in REST webservice java?

I am using a REST in Java and also I am using a token system for that. I need to know that, how we need to maintain the user session? Since REST is stateless we can not maintain user session, then how we need to find the active user in server side?
After user is authorized and given access to the REST API a kind of a token or cookie should be returned with authorization response. The obtained token should be added all subsequent requests that need authorization. Using this token and assuming it's in one-to-one relationship with user you can easily identify the user.

Restricting REST API results based on the user

I am building a messaging application using BackboneJS which naturally persists using a REST interface.
The issue I'm having is that I don't know how to restrict what data a user can pull back from the API. For instance a call to /messages would, at the moment, return messages for ALL users. I would like that resource to only return messages belonging to the current user.
Searching online seems to indicate that oAuth2 is the best way to solve this issue but all the tutorials talk about been redirected to another place to confirm access and retrieve an access token.
Given that my users will have already logged into the message application and that the REST API is actually part of the same application I don't like the idea of asking the users to confirm that my own app can access my own API.
Is there a better way?
oAuth2 is probably your best bet -- you definitely don't want to roll your own security. However, the flavor of oAuth2 you are thinking of is probably not what you want.
oAuth2 has four different flavors, known as authorization grant types:
Authorization code: This is the type you are thinking about. It is often called three-legged oAuth, because there are three actors in the token granting process (app, resource owner, and user). The app asks the user whether it is ok for the resource owner to give specific type(s) of access to the resource. It is a rather complex process that allows the validation of user credentials without allowing the app access to them. This is not necessary in your case, since you are both the app and resource owner.
Client credentials: This is a method for authorizing a client application with the server. It does not use user credentials at all. If you completely trust your client application (all client applications) to correctly protect user data and not expose other user's data to the user using the app, or you are providing only non-user data via the API (for example, map data or catalog data), you might be able to use this fairly simple type of oAuth2. However, if you want to be vigilant in protecting user data (and not allow apps to get to the data without the user providing credentials), you might not use this one.
Resource owner password credentials: The username and password of the user is passed via https to your backend server, which authenticates and authorizes access by providing an access token. The access token can then be passed with each call, and it remains valid for accessing the backend until a configurable time period has elapsed. This means that someone intercepting the token could only use it successfully for a limited amount of time (some number of minutes, generally). The interceptor would not know the username and password of the user. In addition, you can supply the app with a refresh token, which can be used to get a new access token once it has expired (until the refresh token expires -- usually with a significantly longer expiration date). Since the credentials are not passed across the wire often (and must only be passed encrypted), this is often the best solution for protecting user credentials and not requiring the user to pass them in often (good user experience). Implementation is much simpler than for the authorization code grant type.
Implicit: This is the least secure method -- no credentials are validated server side at all. This is usually used for client side scripting languages where credentials cannot be stored safely. If you are worried about security at all, avoid this type if possible.
So, check out OAuth 2.0, and look for the resource owner password credentials grant type.

Identifying/Managing users based on session ID (Mapping between Session ID to User ID to User Data)

I wrote a web-app that authenticated a user via Facebook connect (o-Auth).
After the user have authenticated I have a facebook token.
Using this token I send a request to Facebook to grab its basic user information.
At this point I have the user unique Facebook id and I know who it is.
How should I link between the user, the token and it's data in the database?
Right now my schema is pretty simple: facebook_id is the Primary key, and there are some other columns that includes the token and the user's data. Is that the correct way to do it?
At which point do I need to set a unique SESSION_ID (cookie) on the user request? After it authenticated?
I am confused about this part (and with Session management in general). When i set an attribute on a session does the browser remember it an send it in every request to my server? across all pages?
And the most important question is, how do i map between the SESSION ID and the user? Once i set a session id on his request, i need to figure out on every request who it is. What's the best way to do it?
That is fine, all you really want to do is to be able to match to a particular Facebook User ID with the data created by or in your web app that doesn't come from the Graph API .
At the moment you complete the Login flow (when you receive the Access Token). When you set a session the browser will remember the key-value pair in it until the session is cleared. So you want your code to be able to associate someone using a browser with a particular user in your database (or not if they don't have a session). Thus, whatever session value you use, you need to also store this in the Database alongside the User ID.
See above.
Honestly though, the very easiest way of doing this is to just use the Facebook Javascript SDK. This will handle all the access token retrieval and user persistence through cookies automatically, without you having to write code for it. Ultimately this will mean that all you need to do is store the Facebook User ID in your database alongside the app-generated content and won't need to worry about storing access tokens or session variables. There's a simple step-by-step guide here:
https://developers.facebook.com/docs/howtos/login/getting-started/
(in Step 5 you'll receive the User ID and you can make an AJAX call to server-side code from here to store it in your database)