REST API: user-agent-based client (app) authorization - javascript

I have two separate web apps:
database API
and basic web-client (Flask) with some JS-code (Knockout.js) for interactive
features like filtering products 'on-the-fly', cart, etc.
To implement interactive answers through API I use JavaScript requests running in a user's browser. I want to control access to API and give it only to authorized web-apps, for example, my own client JS-code.
I read about HMAC and Oauth. The key point: the server and the client share the same secret which is used to generate a HMAC, for example.
But how should I generate a HMAC inside a user's browser using a secret and not exposing the secret to others? As I understand, if my JS-code has access to a secret, than anybody on the internet has that access, right?

JavaScript applications are what are called 'public clients' in OAuth 2.0. It basically means they cannot keep secrets and therefore you cannot do client (application) authorization.
So, if you are using a JavaScript application to talk to your API, you'll need to do user authentication and give users access to your API. Or switch to a server side application to access your API.

Related

Allow SPA client using client credential grant token and personal access token - Laravel Passport

I'll put them in context first.
I am developing a Rest API using laravel and as an oauth2 authorization method using Laravel Passport as an implementation.
On the other hand I am developing a Javascript client (Single Page Application or SPA) that will consume the API Rest.
The situation is as follows:
Some API Rest endpoints must always be accessible by the client (a valid client since the API is not public) and other endpoints must only be accessible by the client when a user is logged in.
In a first approach what has been proposed is that when the SPA is initially opened in the browser, you get a Client Credential Grant Token so that it is a valid client and can make requests to the "Basic" endpoints of the API. Later, when a user logs in, a Personal Access Token will be generated which will allow the client to make requests to all endpoints of the API Rest.
I'm a little confused as to how to put this into practice.
I hope, please, you can help me.

How to set up session token between JS and PHP API?

I have designed a simple HTML/CSS and JS/jQuery application, and now it's the moment of authentication integration. On the server side, I have done a REST API which allows clients to get some data. But, now I want to authenticate each request with access and/or session token.
I read many websites to find agreements or advice to establish security between the client (JS) and the REST API (PHP), but unfortunately I found nothing or not interesting.
So I ask you to enlighten me (if you want) to know what to do, what to implement, conventions, etc.
What I read:
Designing a Secure REST (Web) API without OAuth
Token Based Authentication for Single Page Apps (SPAs)
I cannot post more links according to my reputation...
Just give me advice, ways how to store private token (RSA) or access/session token for API.
Don't hesitate to give your reaction, and tell me if I'm not exact or something else.
You need to use a token-based authentication for your REST API. JWTs are the best in this particular case.
Why Use JSON Web Tokens?
Tokens are stateless. The token is self-contained and contains all the information it needs for authentication. This is great for scalability as it frees your server from having to store session state.
JWTs can be generated from anywhere. Token generation is decoupled from token verification allowing you the option to handle the signing of tokens on a separate server or even through a different company such us Auth0.
JWTs have fine-grained access control. Within the token payload you can easily specify user roles and permissions as well as resources that the user can access.
This will be your typical authentication flow process:
A user signs up/logs in, during the login process, you generate a JSON web token from the server and return it to the client. Since you are using PHP, you can use this library for the generation and signing of the token.
Store the JWT returned to the client on the browser Web Storage(local/session storage). It can also be stored in a cookie.
For subsequent HTTP requests from the client to the server, you send the token via headers/query, then the server validates the token. If it's valid, the user is authenticated otherwise the user is rejected.
BTW, if you don't want to implement authentication yourself, you can use Auth0, check out VanillaJS SPA and PHP quickstart
I hope this information helps. Cheers!
Authenticating REST API's with JavaScript front-ends is difficult because the JavaScript code is completely readable by anyone visiting the site so storing any kind of login credentials is no good.
With a standard Server to Server set-up simply using basic auth over HTTPS is more than enough but basic auth is no good for JavaScript SPA's as the credentials are in plain view.
For SPA's you need to be looking at JSON WebTokens, as your back end is in PHP you need to be looking at PHP-JWT from firebase. You can get the code here: https://github.com/firebase/php-jwt or recommended using composer:
composer require firebase/php-jwt
The package makes implementing JWT super simple see the docs for a complete code example. Also check out the JWT for a complete break down https://jwt.io/
I suppose Jwt (https://jwt.io/) is good solution for your question.
On the client side you can store the token on the localStorage or some global variable (for SPA).
You can transfer token on the HTTP header or as request parameter. It works.
Also you can see https://auth0.com/blog/angularjs-authentication-with-cookies-vs-token/

Implicit flow & identity Server 3: Is it possible to grant a JavaScript client an access token without having the user log in?

I have a public API that i want to secure using Identity Server 3.
I have an MVC application and a Javascript application and I want to ensure that only these clients can access the API regardless of Users / Resource Owners being logged in or identified. This is easy to do using the client credentials flow in the MVC app but does not seem possible using the implicit flow. (http://oauthlib.readthedocs.io/en/latest/oauth2/grants/implicit.html) <- relies on the resource owner being identified.
Does anyone know if this is possible? I'm using the oidc-token-manager.
Thanks much.
M.
You can only securely rely on the identity of the client, if the client is "confidential". That means the client can securely store its client secret.
This is true for server-based applications (e.g. client creds flow server to server, or a code based flow invoked by a server).
This is not possible for clients that are outside of your "control" like SPAs or desktop/mobile apps.
IdentityServer always includes a client_id claim - but the above caveat applies.

Access the force.com REST API with a pure Javascript page

I want to develop a front-end in Javascript (possibly with one of the fancy frameworks around such as AngularJS) that consumes the REST API of my Salesforce org.
I don't want to embed my project in Salesforce technologies, so basically
no Visualforce pages
no Force.com Sites
I do want to write my own front-end on a separate server that just makes AJAX calls to the Salesforce back-end.
In addition, I want the application to be accessible for any user, even if he/she does not have a Salesforce account. So the AJAX calls should not require that the user logs in on Salesforce. I want anonymous users to be able to retrieve public data from my organization and create new entries when it is useful (in the case of a survey for instance).
Even though these requirements generate some security concerns, I can imagine that Salesforce takes care about the requests rate limits on their API endpoints and that it is possible to restrict the access to the API on a host name base (e.g., only requests with origin host my-trusted-domain.com should be allowed, send a 403-Forbidden otherwise). I would be surprised if SF does not provide such basic features.
How would you proceed? Is there a minimal Javascript code that works out-of-the-box on any domain without getting into troubles with CORS?
All REST API calls to Salesforce must be authenticated. If you want anonymous API access then you will need to proxy authenticated calls through a server (like on Heroku) that adds the auth token. Or you can use Heroku Connect to expose your Salesforce data to a Heroku app as a Postrgres database.
If you go the REST route then checkout the ForceServer and my CORS Proxy for Salesforce. Both are not setup out-of-the-box for the anonymous access you are looking for but could easily be tweaked to support that use case.
BTW: When allowing anonymous access to your Salesforce data through a proxy make sure you are dealing correctly with security and request limits.

Pure Javascript Front-end connecting to a BaaS (Can it be done?)

I am quite determined to do a pure Javascript front-end (Using JS and GWT) connecting to a back-end using Ajax on a separate server. My concern is with security.
What could be a solution for a Pure Front-end application?
For example, a user-generated content site:
When we look at it at a perspective of an app that to gain access to it it needs to ask user to login, so here Oauth can take over. The app is authenticated properly and access to any content is based on the authorization given.
The problem is here: For an application that can allow anonymous users to view user generated content without logging in thus there is no chance for Oauth to take place.
Connecting to a BaaS:
There will be no Java middleware to store application key for Baas access (e.g. Kinvey etc.)
Even if obfuscated the application key can easily be snooped from the HTTP requests.
What could be a solution for a Pure Javascript front-end to connect to a BaaS or independent backend? In terms of securing application keys? Where Baas or independent backend can know if it is to serve data to the requesting client (even its a web app) since its not from the same domain.

Categories