Down-scoping Oauth access-token, possible? - javascript

I am developing an open source javascript project. It has client side database, Oauth Connect login and bear-token base access to cross domain resource servers like (GData, Google cloud storage, AWS via proxy). The main focus is on consumer cloud data (you know, developer got free data storage).
The main goal to provide database to the web app without using backend server. It is achieved by keeping Oauth 2 refresh token in the server, providing access token to the web app so that it can populate its client side database, directly from resource servers. Dumb proxy server may be necessary for updating back to the resource server.
Login user may share his data to other login user. Server provides access token as necessary. In that case I wish to down-grade the access token. Generally once a new user start using the app, the server request off-line multiple scopes read-write grant. Currently, I as far I can understand a refresh token can generate access token of exact scopes.
Is that possible to request a down-graded access token from an offline refresh token? Even down grading from read-write to read-only is very useful.

Related

Storing API access token server-side

I have built an app in React that uses the Dropbox API & will be stored on AWS S3 & CloudFront. The app accesses the Dropbox folder using a token. At the moment this token is client-side and obviously is completely accessible.
I have tried reaching out to Dropbox, looked into cookies & HTML5 web storage but can't seem to find a simple explanation.
What would be the simplest way of securing this token on the server?
There are few pros and cons of storing an access token in the server.
However, the most secure way of storing it on your server is sending it to the server via https link.
One major disadvantage of storing an access token in the server is that you, as the owner of the service, is bound to take the responsibility of securing the token. If your server is ever compromised, the hacker gets access to all the data of all the users by having simple access to all their access tokens.
You can always store the dropbox access token on the client side as a storage variable. Each storage is accessible only to the scripts served from the same domain.
~Edit~
If the Dropbox account is owned by the owner of the website and it should be hidden from the end user, you need to operate the Dropbox account from within the server. This DropBox accessing microservice has to be utilized as a proxy for accessing files.

Separated frontend with backbone.js and node.js backend token

I have separated projects,
Server side node.js with express to serve restful api but returning JSON instead html. All the examples in internet are returning html with ejs.
Frontend is and independent application with backbone and socket.io.
I want to do a login and registration page and I did it with passport.js on the server side, but I have not idea of how to send the token to the frontend and store it there to send It on every request to the server. If the user is out of session then the login page, ,must be shown.
I want a way compatible with oauth 2.0 for multiple authentication strategies.
Sorry for my English and I have a lot of dudes and I don't understand all the concepts.
Basically what you have is an API and a client, and you need two things:
The client to be able to open a session on the API.
The client to be able to embed its session credentials in every request so that the API knows who is doing the query.
First Step
For opening the session, you have figured it out: you want your API to be an Oauth Client.
So when a user wants to log in, your client will redirect it to http://api.yourserver.com/login/google which will redirect to google, which will redirect again to your API with a token that allow your API to access Google's API (hence, know who your user is).
This token cannot be used to authenticate against your API. Its only goal is to allow your API to act on the user's behalf on google services.
Second Step
Then you need to decide how will your client authenticate against your API. You can choose to use a cookie which almost everyone do (it's the sane default for express sessions).
Or, if your API is consumed by many different clients, and you don't have control over those clients, you can choose to implement an Oauth Server to protect your API.
The clients will then authenticate against your API using a "Bearer Token" (it's an HTTP header).

Client application and token authentication/validation OAuth

I am trying to implement OAuth with my javascript client application.
I already have the server up and running.
My workflow is as following:
Open app
Check if token is present
Validate the token
If not present or not valid go to oauth server for the token
Get back to app and repeat 2 and 3
I everything is ok show my app
I am not sure how to implement point 2. I understand that I need to make another call to the server for this but where is the validation endpoint?
I only have /authorize, /user and /logout
Also how should the request be formed? Do I attach token as a GET parameter and thats all?
What if somebody intercepts valid the token?
Depends on your application, but since you have a javascript web application, that most probably can't keep it's credentials secret, you'll need to implement the Implicit Grant as stated in the OAuth 2.0 spec. If however your application CAN keep it's credentials secret, you should implement the Client Credentials Grant (server side application) because it's more secure.
I am not sure how to implement point 2
You should store your access token somewhere in your web application, for instance in localStorage.
The first time a user will access your web application, the user will have NO access token and NO session with your authorization server. Your web application could see if you have an access token by doing something like:
if (!localStorage.getItem('accessToken') {
window.location.replace('https://your-authorization-server/authorize?response_type=token&client_id=<CLIENT_ID>&redirect_uri=<CALLBACK_URL>&scope=<SCOPE>');
}
If there's no access token, you'll need to redirect to your authorization server so that the user can log in with the authorization server. After the user has logged in, the authorization server will redirect the user back to your web application (after the user has granted permission to whatever resource your web application likes to access on behalf of said user) with a valid access token. This access token must be exposed as a hash fragment named access_token, i.e:
https://web-app.com#access_token=123456789X
Now your web application can extract the access token and store it somewhere.
I understand that I need to make another call to the server for this
but where is the validation endpoint? I only have /authorize, /user
and /logout
Your authorization server requires a token validation endpoint. This endpoint will be used by your web application to validate said token (the one you stored somewhere, for instance localStorage). When this endpoint is called with an access token and it turns out the token is valid, the user can continue, otherwise the user will be redirected to the authorization server. If the user already has a session with the authorization server, the user will be redirected back immediately with a new access token, otherwise the user needs to authenticate (login) first.
Also how should the request be formed? Do I attach token as a GET
parameter and thats all?
Some send a GET request with the access token as a url query parameter, others send a POST request with the access token as the payload of the request body.
What if somebody intercepts the valid token?
Always use https and your access token should be valid for a limited amount of time.
Something to keep in mind is that because your application can't keep it's credentials secret, you need to Implement the Implicit Grant, this means you immediately receive the access token when the authorization server authorized the web application based on Client Id and domain. As opposed to Client Credentials Grant where you first receive an Authorization Code that needs to be exchanged for an access token. When using Implicit Grant you can NOT use Refresh Tokens. This means the user NEEDS to go through the entire flow with the authorization server to obtain a new access token. But this isn't really a big deal, because the user will already be logged in with the authorization server, resulting in an immediate redirect, so when implemented correctly in the web application, the user won't notice.
This is just covering it in broad strokes, it really helped me (and I advise you) to read the OAuth 2.0 spec. Hope this helps you out a bit, OAuth is a complex subject!

How to implement OAuth 2.0 like token based authentication for rest API which is accessed from mobile and javascript web applications

I need to implement authentication and authorization mechanism for my REST API. This is rest api is accessed from a mobile application and web application.
Mechanism I would like to implement:
So as per my understanding, I am using password based authentication. Mobile application or javascript web application sends username and password over HTTPS post request to obtain access token for limited time.
Problem
As access token expires every 1hr or so. End user is again requested to enter username and password. This is not acceptable.
If we increase the time of the token for longer period, then if someone gets handle on token they can have access to Rest API for more time. As the web application is javascript application, its easily available in plan text.
So I am trying to understand how are applications like facebook and twitter implement authorization for their native mobile applications. Do they remember access token for ever by storing in local storage. So that if some malicious application have root access to android phone can access the tokens.
What are the improvements to above mechanism to make it work for both for both standalone web application which is developed in javascript and android application?
Access tokens are indeed meant to be short lived. To maintain authorization for a long period of time, OAuth2 has something called "refresh tokens".
If the provider supports it (and both Google and Facebook do), the OAuth2 consumer can request a refresh token in addition to the access token during the initial flow (Google calls that "offline access" I believe). The access token is used normally but when it expires, the consumer can request a new access token using its credentials and the refresh token.
See Google's doc for more info: https://developers.google.com/accounts/docs/OAuth2WebServer#offline.

Authenticate client-side app to REST API using CORS with local strategy

The Problem:
Serving a secure API to a client side app using only a local authentication strategy. The red arrows are part of the knowledge gap.
Context:
That is --- client.example.com is making a POST to api.example.com/login where on success client.example.com can gain access to a GET service like api.example.com/secret.
An idea!
Implimentation of OAuth 2.0 with hybrid grant type sitting in front of API.
Why hybrid?
It wouldn't be an Implicit Grant Flow aka Client-Side Web Applications Flow because there is no redirection to API server too grant access token. (i.e.) "Is it ok for so-and-so to access your data?"
It wouldn't be a Resource Owner Password Flow because a Client ID and Client Secret are passed along with the request so it's assumed the client app is server-side.
OK... so what about a little bit of both?
What if we used a CRSF token on page load of client-side app, and POST it with user credentials too OAuth 2.0 authentication endpoint to exchange for access token? You would authenticate each subsequent request with the access token and CRSF token after a successful login.
A good Node.js OAuth 2.0 library I found:
https://github.com/ammmir/node-oauth2-provider
Help Me!
I can not find a working example of an authentication measure that solves this problem! Point me in the right direction?
Ultimately, the goal here is too authenticate a client side app to a REST api using CORS with a local strategy --- i.e. username & password --- even if the convention above isn't possible.
To Accommodate Bounty:
This is a client side app, so let's stay trendy.
I'm looking for a working example using the Node.js OAuth 2.0 seed above for the API/Auth server and a front end framework like Angular.js or Backbone.js to make requests.
The example should match the context described above.
I'm working on an app with a pretty similar architecture though the services are .NET Web API rather than Node and we're using DotNetOpenAuth for the OAuth provider. Rather than the hybrid approach you're suggesting we're doing the following:
x.com serves up a login page
login page POSTs back credentials to x.com
server side logic at x.com combines client_id and client_secret with the credentials to submit a token request (resource owner password credentials grant that you've
mentioned above) receiving back both a temporary access token and a
refresh token
the refresh token is encrypted into a cookie issued by x.com
both the cookie (with encrypted refresh token) and the temporary access token are then sent to the browser
the client app (angular in my case) can now use the access token to hit api.x.com for services (It appears you're well aware of the limitations of CORS... we hacked a version of angular's $resource to facilitate this but it wasn't pretty since we wanted to use all HTTP verbs and support IE9)
when the access token expires, the client side app can request a new access token from x.com
server-side, x.com decrypts the cookie to get at the refresh token and issues another oauth call for a new access token
This is fairly high-level but hopefully gives you a sense for how to tackle your situation. In my case, and it appears in yours, we didn't want to use session state or a database to store the refresh token but obviously exposing that to the browser introduces security concerns so the encryption of the refresh token is important (among other security considerations) and the use of the cookie eliminates the need for session state or other persistent storage on x.com.
Not an answer running for the prize. Just my 2 cents :)
On my web server,
I do my authentication through a rest call with login/password with basic authentication over https. This call delivers a key to the client (a one page web app).
Then every subsequent REST call is signed with the key. The server checks that the signature is correct and everything still happen in https.
This mechanism is quite used I believe.
I don't see the issue with cross domain. I have a single source anf if I need something from another source, I'd use JSONP.
I use nginx as an https->http forwarder.
Not sure how it competes with an OAuth2 solution.
I've built this example using Node and PassportJS to show how to authenticate the users with Facebook or Local Strategy. Both sides are on different domains as you described and it requires CORS enabled.
GitHub: https://github.com/pablodenadai/Corsnection
Live demo: http://corsnection-client.herokuapp.com/
I can't promise that I have time to write working example but I can show you 2 paths :)
The biggest deal is CORS. After you solve that problem it is easy to use $http service. So, first and probably easiest may be to configure reverse proxy in x.com webserver which points to api.x.com. I wrote article here
Second approach is better, and created for exactly this purpose, to authorise specific domain to use your resource. It involves a bit of coding in api.x.com so you don't have to change anything in new web applications served in other domains. You simply need to authorise CORS requests in api.x.com service.
Create table in database where you can manage list of authorised domains
Add in that table record "x.com"
in api.x.com add request filter/interceptor what ever tech term you use for method which should be invoked after request is handled and add in response Access-Control-Allow-Origin: x.com if request comes from x.com (in other words check in request header refer value match to any value in table above and put that value in Access-Control-Allow-Origin response header).
That is all :) After this if you know how to use $http or jQuey.ajax you will be able to POST/PUT/DELETE/... any request to api.x.com from any authorised domain in just few minutes.
I very similar idea using vinilla js web app and cross domain authentication to GAE backend or OpenID connect.
The web app is run on CDN. When click login link, it goes to respective login server and redirect back to the web app (with XSRF security token and HTTPS only cookie). Login server accept cross domain request with credentials. XSRF token has to be set (in header) with every request. cookie is set by the browser. Since it is HTTP only cookie, JS cannot read it. The technique is very secure.
Once login, you can get secure assess from login server.
For detail description, you can find here and open source repo here.

Categories

Resources