I currently have a backend written in Django and a chrome extension which makes rest requests to the backend. The backend is set up for user registration and login through a webpage.
I'd like to authenticate users in the chrome extension such that they can login once and the chrome extension will maintain the session across multiple loads on different pages. All rest requests from the extension should then be authenticated with the ability to tell which user is making a given request in the handler for the request.
I am very unfamiliar with this type client-server authentication and after a look around it looks like oauth or simple https header authentication may be the way to go. I am uncertain about oauth as this seems overkill (and I am generally unfamiliar with it), while I'm not sure how to maintain the https authentication across uses of the extension. Could someone sketch out the necessary elements from the Django backend through to making the login and subsequent rest requests in javascript?
Related
I'm using Google Firebase, and unfortunately, Google Firebase put some countries under sanctions which means they must use a proxy (or VPN) to access the website.
Is there any way I can set a proxy setting for each client request that they can freely access Firebase without a VPN?
I know there are options for Node.js, but I'm looking for a web browser solution. Firefox has this proxy settings, and Google Chrome also has some options for extension developers, but I need a solution that works just in a web page, and it means when a user comes to my website, he/she does not need to set a proxy to access Firebase.
Example: when a user comes to my website from (for example) Syria or Sudan, they don't need to set VPN for their browser, because I have done some proxy configuration in my website
Short answer: You can't do it website-only.
Longer answer / explanation:
I know there are options for Node.js,
Good... that could work. Deploy your own Node.js server on Heroku or the like, which proxies requests to Firebase.
but I'm looking for a web browser solution. Firefox has this proxy settings, and Google Chrome also has some options for extension developers, but
This could work too, but as I'm sure you've considered... that would rely on the end-users installing those extensions before attempting to visit your site.
I need a solution that works just in a web page,
Nope. Not possible. The Google servers will not respond to any request coming from a sanctioned country. If a request comes from a disallowed country, the Firebase servers won't respond with your website - instead they respond with a 403. Firebase won't send the website. Your website won't be sent to the client. It doesn't matter what your website contains, it will never be sent to those end users in the first place.
Even if you host the site elsewhere, and just use the Firebase database, it still won't work - for the same reasons. When the Firebase servers receive the request from a browser running in a sanctioned country, they respond with 403.
The question then becomes: How to make the request appear to come from outside the sanctioned country, from the website only?
You can't, not when you only control the website itself. That part of the request/response cycle is, for end-user protection purposes, handled by the browser. Browsers do not expose that functionality to webpages.
If you want to handle everything for your users, without them needing a VPN (desktop, or browser), your only choice will be to send the request to a different non-Google server (such as a Node.js server you host on Heroku or the like), which then makes the request to Firebase on their behalf, gets the response, and responds back to the client. That way, to the Firebase servers, it looks like the request is coming from X* location.
*X: Where ever the Heroku server is running.
There is a sensitive page in my website, so I want to authenticate visitors before they opening a link like: www.examples.com/builder.
I know if I use cookie based authentication everything will be simple, as the browser will send the credential message in cookies automatically. But in my situation, I have to use token based authentication. Browser don't send token if there is no pre-load script.
So my question is how to achieve token based authentication when someone open a sensitive page directly.
As far as I can understand,
you're looking for a way to avoid double roundtrips to send authentication headers to your web-service.
If I am correct, then this would only be possible via service worker which is a not widely supported feature. https://developers.google.com/web/fundamentals/primers/service-workers/
If, depending on your requirements, you can't go for service workers, then, the only left option is to use cookies.
I normally have a secondary authentication flow which uses cookies allowing a web service to authenticate a user on its first get request (the one made by the browser).
There are also some spa framework which implement routing resolvers but this will require a double roundtrip (1. load javascript, 2. send the token).
How would you call the secured REST api from the Javascript script application that doesn't have the login?
I have a Javascript application (React) that doesn't have a user login. It needs to call some REST api services that uses Oauth (Azure Ad -
WindowsAzureActiveDirectoryBearerAuthentication).
Those REST services have CORS enabled.
I also registered my web application in Azure Ad.
The issue is that the javascript application needs to call https://login.microsoftonline.com/{{tenantId}}/oauth2/token to get the access token. I found no way to enable the CORS for that URL. My JS application doens't have any login so I can't show the login screen in popup or use adal js.
The solution that I come up with is that I put my Javascript application in NodeJS (Express). The JS call the NodeJS that calls the login.microsoftonline.com to get the token and pass it when calling other secured REST services.
It works great but I think there might be some security issues around that.
Is there any better way to design this kind of application?
What you are doing is the proper approach. It keeps all the Oauth tokens secure on your server without having to expose them client side.
That is the main reason most Oauth2 API's don't implement CORS
I'm a regular reader here at stack overflow but this is my first question.
I'm developing an authorization-server using the OAuth2 specs. And I just got stuck with how do I ensure the first-party client authenticity while using the password flow. I read many forums and this is what I got:
Javascript single-page clients
This blog post by Alex Bilbie, he states that to avoid the client_secret problem we should just:
It’s simple; proxy all of your API calls via a thin server side component. This component (let’s just call it a proxy from here on)
will authenticate ajax requests from the user’s session. The access
and refresh tokens can be stored in an encrypted form in a cookie
which only the proxy can decrypt. The application client credentials
will also be hardcoded into the proxy so they’re not publicly
accessible either.
But now this proxy can be accessed by someone impersonating my
angular app. And then I came across this blog post from Andy
Fielder: How Secure is the OAuth2 Resourc Owner Password Flow
for Single Page Apps. He basically says to rely on CORS to
avoid impersonating JS clients.
It is a good idea to use both approaches to secure my JS app?
Native Apps (Desktop and Mobile)
In the case of mobile apps, I only found cases for Authorization
Code and Implicit flows. This is not what I want, as the redirects
will compromise the user experience. So my thoughts on this is:
I will use the ROP flow and then register the client with a
client_id generated for this particular installation and attach it
to the user account, receiving the access_token and a
client_secret as response. Any other token request made by this
client MUST carry this credentials (as the client_id is specific
for the installation, I will be able to check if this client is
already authenticated). This way if someone uses any credential for
impersonating a client, or even registers a bogus client, I can take
mesures to revoke the user and client access.
I know that this can be overthinking, and I also know that some of this matters doesn't avoid anything. I just feel that is my job to protect my API as much as I can.
I would really appreciate your thoughts about this matters! Am I really overthinking? Should I just use the concept of a 'public client' and carry on?
Thank you all and happy coding!
First of all, this problem is not a common priority because most applications are developed first with website, and after with the API. This is probably the reason because no one knows how to deal first clients with oauth2, because everyone have developed other ways to do that and oauth2 is needed only to grant user access to third party applications.
Even if you have develop the oauth2 authorization server only for your first clients applications (thinking about a single authentication mechanism instead of developing many), you should try to develop the authorization code or implicit grant types. You will realize that you need a way to check what user is actually logged in.
The two common methods are:
user session (based on Cookies)
user access from localStorage (based javascript)
In either ways you need to check your application security, user session is vulnerable to CSRF, localStorage are vulnerable to XSS. There are a lot of articles about how to secure your website against either, so I will not suggest anything here, you just need to know that they exist.
Now that you choose your authentication method we can start to do some consideration about:
Javascript single pages applications
Proxy
Having a proxy that filter all requests in my opinion is like to have a door with the keys always inserted. It's useless even build the door.
However, for session based authentication it's the only way to do it. Allowing session authentication on your Rest API will open to CSRF security issues, so you need to have a proxy layer that get the user session, retrieve the access token from the session and do the request to the Rest API adding the Authorization header.
CORS
With this method you need to store the user access token in the localStorage, because the token is retrieved from the Js client directly.
Using CORS you are sure that other websites cannot do requests to your Rest API from a browser. But your first client need to be public (ie: it does not have a client_secret).
Native Apps (Desktop and Mobile)
In my first application I tried to use the same mechanism that you suggest to secure the auth flow. However that type of mechanism require that you identify every user client in an unique way. This is not possible in iOS for privacy reasons and with some probability it will denied in the future releases of Android. So you should rely on a public client and add only the client_id in your native application code.
This means that your native app client/your js client can be impersonalized? Yes, and there is no way to prevent this with oAuth2 resource owner password credentials grant type.
The main reason about this is because oAuth2 is not for authentication, only for third-party authorization, and that grant type was added only for specific third-party applications trusted enought to use directly the user password. You could read more about this argument here and here.
At the end
You still need a way to auhorize your user, and I think that the best you can achieve using oAuth2 is what Auth0 did.
Essentially this Saas manage your users with an oAuth2 server + OpenID connect, so you are always managing your users like its a third-party application and everything works fine.
Indeed, you can see on this page that for mobile applications they suggest to use a browser based login form, because the native one can be impersonalized by everyone that decompile your application, but if you wrap it into an authorization code flow it works fine.
I am attempting to write a plugin for a webapp that integrates it with facebook using the Javascript API. The application is installed by our customers on their own servers each with their own site names. This poses a problem to me as Facebook wants me to specify a site url for the application. This url is going to be different for every customer. Creating a new application for each customer is not an option.
In my research of this problem it seems that I have to pretend to be a desktop app and follow that authentication path. I cannot figure out how to do this.
Anyone have any idea how this can be done?
Are you going to host the app as a canvas app or outside facebook?
Is the url important to you? There is a strict one-to-one relation between base-url and application.
What many apps do is host the apps as directories in their domain. For example http://crazy-fb-app.com/customername
That's your options basically if you want to use Javascript SDK.
If you're going to be using server side technology you could have the user authorize the application while requesting permission to access user's data while he's offline. in that case you will receive a non-expiring (or long-expiring) authentication token which you can use from the server to make Graph API calls on behalf of the user. For some stuff you can obtain an Application Auth token (which is shorter and non-user-specific) to make calls to the graph.
Rotem