Best security practices for OAuth 2 authentication in a Javascript application - javascript

I've a REST API, with an OAuth 2 authentication mechanism (FOSOAuthServerBundle on a Symfony 3 application).
To get/refresh a token, the URL look like : https://api.example.com/oauth/v2/token?grant_type=[password|refresh_token]&client_id=[client_id]&client_secret=[client_secret]&username=[username]&password=[password]
This works great on server-to-server calls, but can't be applied on Javascript apps.
How can implement API Oauth 2 authentication from a front application ? (JWT is not present on the server).

In the context you described, the best option (if not able to change the api) is to create a thin proxy to add another layer of protection to your token.
Given you are probably a javascript developer, you can easily use AWS API Gateway + Lambda to create that without needing a server.
A server dies every time someone implements OAuth in a single page is
web-app. Stop the genocide! Use a server side proxy! Act now!
— Alex Bilbie (#alexbilbie) (https://github.com/alexbilbie/alexbilbie.github.com/blob/master/_posts/2014-11-11-oauth-and-javascript.md)

Related

OAuth Implementation for JS based frontend application

So, I was looking at building a JS based front-end (probably with Vue.js) when I encountered a problem.
The backend already has OAuth based APIs, where I would need to authenticate all the API calls using an access token. So I went looking for ways to do so and found out that I should use Client Credentials grant.
The problem is that a frontend application would expose the client ID and secret. These can simply be tracked through the "Network" tab of the Browser's inspector. This makes it possible for anyone to obtain an access token and make dangerous API calls (like deleting stuff).
I also found that PKCE flows dont use client secrets.
However, I have 2 problems with PKCE as well:
Authorization is not needed for these APIs to call as these are very adminy (like user management) APIs.
PKCE will also expose the client ID.
Assuming that my understanding is correct, how should I implement the OAuth APIs such that it is secure and does not expose any credentials?
Also, if there needs to be more information, please let me know.

Authentication approach for REST API used by frontend app and another backend service

I have a rest api backend service A which is used by two other services:
B service which is web app running in a browser (separate node server)
C service which is also backend service (separate server too)
My initial approach was to use basic auth for A-B communication but this does not make sense for A-C since there is no way to safely keep credentials in a browser. On the other hand introducing session and tokens seems weird for A-B communication.
No matter what I do it seems like tug of war.
What do you think might be reasonable solution for such setup?
You need at least SSL for A-B and then only you can judge if basic auth works or not.
If C is going to use the same APIs as B then it makes sense to use the same authentication methods, just for simplicity, IMO.
You could also use a token based auth mechanism where each service (remote or local) authenticates and gets a token and uses that for subsequent communication.
See the following for more:
REST API Token based authentication
You can refer to AWS API Gateway for clues on how to implement authentication for REST APIs.
https://aws.amazon.com/api-gateway/faqs/#security
Summary:
Access Token
Custom Authentication
Enable CORS
Client side SSL certificate based authentication

Authentication in SPA using Auth0 and clients node.js server

Background
I have two apps:
Angular2 Single Page Application
Node.JS with express
I'd like to authenticate and authorize users logging into Angular2 app, by consuming API exposed by express server. I'd like to use Auth0 as my IDP. I want the whole app (client + server) to be made-to-measure.
At the same time:
I don't want to use Auth0 Lock
I don't want to use refreshes and redirects (for fine UX and simplified flow)
I don't want to ship auth0.js library to Angular2 app (to minimize payload and client-side code complexity).
I would like to keep auth data returned by server in localStorage (as opposed to passport.js setting cookies and refreshing)
Preferably, I wouldn't want to set up database for these purposes, although it's possible.
Proposed architecture
Red arrows indicate authentication flow.
5 is a generic API request.
Actual question(s)
Are there any contraindications to using such architecture?
How do I achieve it and what do I need to pass through each of 4 requests/responses? (the simplest scenario and prerequisites)?
Are there any resources which will help me get better understanding of OAuth and authentication in general, for beginners in this field?
Q1
Given that OAuth2 uses HTTP redirects for a significant part of the functionalities it specifies, going with an architecture such as that one and imposing that many constraints will reduce the number of possibilities you can leverage. Besides that, I don't see any major problems.
Q2
Given you don't want to use redirects the OAuth2 flow that you need to use is the resource owner password grant (ROPC), mostly because of the four flows that OAuth2 provides it's the only one that would meet your requirements.
❌ Authorization code grant (redirect-based)
❌ Implicit grant (redirect-based)
✅ Resource owner password grant
❌ Client credentials grant (aimed at client applications that want to access an API on behalf of themselves and not of an end-user)
In request 1 and 2 you pass the username and password credentials, first to your own server and then to the authorization server. In requests 3 and 4 the access token resulting from a successful user authentication is delivered to the AngularJS application that can store it in localStorage for later use.
This meets your exact requirements, but it's not the most common architecture in use. Normally, the SPA would use the implicit grant to get the access token. Given this grant is optimised exactly for this purpose it can be implemented with good UX characteristics, however, it would indeed make use of redirects.
Q3
The OAuth2 specification itself is not that hard on the eyes and it would be the best resource I would recommend. For a more high-level and quick intro into the topic I would also recommend https://auth0.com/docs/protocols/oauth2.

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.

Using OpenID (RPX) (and maybe OAuth) for a RESTful web service

How would you combine OpenID with a RESTful web service?
The personal project I'm working on is using the RPX SaaS to do OpenID. The key result of this is URL describing the logged in user. The app itself is heavily Javascript and I'm planning on using a REST api to communicate with the backend for database persistence and spatial processing.
The security requirements on this application aren't big. I want to know which user is making a request. I don't believe I need to use SSL to be confidential about the data and I don't want the overhead of running SSL.
I'm using Spring and would like to use Spring Security (Acegi) if possible but I'm not wedded to that idea.
Options:
Return the OpenID URL to the Javascript app, use this to retrieve the list of resources for the user and then retrieve/save/etc those resources by id.
Create a session table which connects the OpenID URL with a random session token. Return the token to the Javascript app which must then return the token with every subsequent request.
Use the session from option 2 as the Consumer Token, etc for OAuth. Initially, the session would be sent to the app using PKI encryption.
Rely on J2EE HTTP Session.
Of these options I'm leaning towards option 2. Hijacking the session would be difficult as the attacker would have to guess the session id and I don't believe the application requires protection from sniffing. Option 3 is essentially the same as option 2 but the session id isn't available for sniffing. Option 4 puts the OpenID URL into the server's memory and causes all the scalability problems REST is designed to avoid.
I'm grateful for any discussion on this.
So, 2 years 3 months later I can answer my own question. I implemented this for my personal project and I have separately implemented it for my employer.
Plugging into Spring Security is the best way to go. You can choose to use the pre-authenticated flow but you may find the CasAuthenticationFilter (and CasAuthenticationEntryPoint) work better as they have most of the flow you need.

Categories