How to accomplish google oauth authentication using nancy api and angularjs? - angularjs

I have been looking around for this issue and haven't found anything yet.
I want to create a webapp that requests offline access to google api, and the my main concern is that I'm using angular as a front-end and I'm consuming a api created in nancy.
I have been able to get access but only for a couple of hours, but I need the user to grand offline access to the app because it's going to have a task running every amount of time needed.
Have anyone already accomplish this one? Tried? Experience? I've tried to call the google oauth api to request the token but it returns 405 method not allowed.

You can use Simpleauthentication, which has Nancy specific NuGet package. Just follow the instruction to set ip SimpleAuthentication in a Nancy app.

I've never used nancy. But in general, your OAUTH concerns should be handled server-side. The user validates against the google oauth, that google oauth flow returns to the back-end server, and the back-end server gives up a key, cookie, or something like that, which your front-end now uses in its request.
That's at least how I handle it. I use a token-based scheme for all my $http requests from my back-end API, which returns 401 if there's no valid token on the request and 403 if there is a token, but that token doesn't authorize that resource. I stuck a httpProvider interceptor in angular that, in the event of a 401, initiates client-side login flow.
Specifically, the token just is a randomly generated series of bits turned into hexadecimal, and then I stash it in redis as a key whose value is the user_id associated with this login.
Of course all of this requires a real https stack to be secure, since I'm just pushing what amount to plain-text one-time keys around, but that's about all you can do about that.

Related

How to restrict the access to backend API to be only accessed by the react app?

I am creating a public facing SPA web application using React js.
The backend for this application are the endpoints available under Azure APIM. I would like to restrict the access to these APIM endpoints in a way that they are only accessible from my react app.
As the react app will be rendered in the user's browser, I cannot have any IP restriction on my APIM backend inbound policy, as the application could be accessed from anywhere ( public facing). But if anyone gets access to the API url by inspecting the network traffic in the browser , my backend API's become vulnerable.
How can I restrict that APIM endpoints are only accessible from the react app ?
I have tried using CORS policy to allow my domain , but still tools like POSTMAN are able to access the endpoints.
The short answer is you cannot fully prevent people from hitting your public API endpoint on their own.
The longer answer is that you can put protections within your API config so that this isn't a concern. If all requests need a valid user authentication token, for instance, it doesn't matter if that valid request comes from your React UI or an errant user's terminal window. Check out some best practices on protecting your API endpoints, and it will hopefully answer your question.
You can't. At best you can obstruct the user by making it harder to replicate a proper request to your API. Ultimately there's no way to identify whether or not a request came from a browser or some other tool though.
It's up to you to construct the API in such a way that the user can't abuse it by limiting the user to only perform actions that they should be allowed to make. If you are concerned by a user overloading your API you can add a policy to APIM to apply rate limiting (e.g. by IP).
It not be possible to prevent attackers from inspecting HTTP traffic and the vulnerable calling endpoints.
You should implement authentication controls on API. Whenever a user opens a new session on you SPA, the API grants that user a token that is valid for a fixed amount of time (~30 mins). Ensure that the API checks if that token is valid for each request.

How to keep authentication token safe in js web apps?

I am not sure if I should create it here on StackOverflow or another stackexchange channel, but let's try here.
We have a web api made in asp.net core which uses the basic authentication where another web app post some login data to the api and it respond a token for the next requests. The client app stores this token and the next request to get/post data uses this token key for authentication. It works fine from the api perspective.
The point here is our web app. We are building it using react.js and the point how to keep the authentication token safe. We store the token on the current app (which is executed in a web browser). We have a feeling about store it on the browser because bad users can access the console on devTools and investigate how to to get the token from the global variables on the react app (just a sample). Given this point the questions are: How to deal with it to keep the back-end and front-end safe? How make sure the users cannot get the auth token and use it on another apps?
We were thinking in creating a kind of server-side channel just to store the authentication token like the picture bellow:
The web browser app make requests to server-side channel to get/post some data;
The server-side channel make a new request the API defining the authentication token and repassing the get/post data;
The api process the request and respond;
The server-side channel get a response from api and send it to the browser;
The web browser app get the final response.
It could work and keep it safe, but another question is: How computationally expensive is that?
Is there any possible solutions or suggestions how to deal with it?
Thank you.
Use JWT access tokens against your API and authenticate your SPA with an identity provider using an Open ID Connect flow (OIDC).
https://www.ubisecure.com/single-sign-on/single-page-application-and-openid-connect/
There are lots of examples of this, Identity Server is a common OIDC implementation with examples, http://docs.identityserver.io/en/latest/quickstarts/6_javascript_client.html
Once you've gone through the OIDC flow and acquired an access token for the user, you can store this client side safely, as
The access token has an inbuilt lifetime and once it's expired can no longer be used. Good practice is to keep this lifetime short (thus limiting the attack vector) and provide some sort of token refresh logic to automatically keep the user working against the API, as long as they keep the SPA open.
Your netcore web api has all the libraries it needs to do token validation / lifetime valdiation etc. This has been made very simple at the API layer
NB: I mention safely as there is still an attack vector, someone who acquires the JWT can act as that user for the lifetime of the token against your API, they are the bearer of the token. It's up to you to make sure the lifetimes of your tokens are sane and the the process for acquiring a new token is as secure as possible
There are a lot of examples on how to implement this, and whether or not you want to use your own Identity Server or use a solution such as Auth0.
Don't try and roll your own security solution. Stick to the specs and standards and adhere to all the industry best practices, making use of battle-tested libraries.
store token in local storage in web browser in encrypted form

Is this user authentication process reasonable?

I've been developing RESTful API server communicating with cross-platform clients such as Android, iOS, Web browser, and so on.
When a user login successfully by username and password, this server issue an access token(JWT, 5 minutes) and a refresh token(GUID, 20 days).
When we develop Android client app communicating with server, we just can store this tokens in mobile device and I believe it will not be a problem in terms of security( using SharedPreferences).
But when it comes to Web browsers, (React App) I had to tackle where to store these tokens. Finally, I decided HttpOnly Cookie, because I can manage easily CSRF attacks rather than XSS.
Soon, I doubt this is a typical design. For example, web browser users cannot logout whenever they want. So I determinate change the wrapper server(Node.js) between the React app and the RESTful API server.
In my second design, the React App and the wrapper server authenticate session-cookie model, using passport.js for exmaple. And when the wrapper recognize the request is authenticated, then the wrapper issue a short term access token(1 minute JWT) and reorganize the request by inserting the access token just issued in the header sent to the RESTful API server.
Is this reasonable process? Thank you in advance.
You could simplify your solution by removing the JWT access token altogether. The refresh token could be used as a session id. Every time a client issues an API call to the server the session id is sent in an HTTP header, so you can check if the request is legitimate.
Your approach of using a JWT token with a short expiration time is ok, but it brings some complexity to your system. In my opinion this approach is best suited for systems where you have an authentication service and a resource owner service. So the client would request an access token to the authentication service and use that token to communicate with the resource owner service. Then the resource owner can check the validity of the access token by just checking whether the signature matches the authentication service's.
I hope this helps you, let me know if I'm missing something.

Securing a React frontend and with Python API using AWS Cognito

I'm considering using AWS Cognito as a user management system for a single page web app I'm building using React along with a Python REST API backend (Pyramid). I'm struggling to see how all the pieces fit together for my architecture (the docs don't seem to be helping me). There are many great examples of how to implement authentication into the frontend using JS. My issue is how to integrate this authentication into my backend REST API.
In my current hand rolled user management system, the frontend calls the REST API on sign-in and is given a token which is passed to API again for every subsequent request. I'm then able to use ACL's on my API functions, check permissions to access resources, etc. If I were to use Cognito and perform the authentication on the frontend (as many examples do) how will my backend know if the token is valid when it receives it with a request? Surely I wont have to call Coginto from the backend to verify this for every request? Also how can I perform checks for information such as 'is this user in the admin group' if that group is defined within Cognito? Again, calling out to Cognito for every request seems very heavyweight and cumbersome.
I did see one example where a list of valid tokens was exported from Cognito as a JSON file and kept on the backend. This seems horribly static when users could be added and removed regularly.
Is Cognito really suitable for my use case? Some high level guidance and pointers to any relevant examples and docs would be greatly appreciated!
When authenticating with Cognito, the user can have 3 tokens:
Refresh
Access
ID
For python, boto3 can interface now with Cognito. There's also this python lib wrapper: warrant, to make it easier.
Once you have the token, it is possible to pass it to the API (eg: access) and it can be checked on the server side with python-jose, as per AWS docs
To pass the token, an example pyramid /login implementation can keep the information in the session before setting the request response:
request.session['my_token'] = str(a_token)
The default cookie session factory works, though it warns that the token is not sent encrypted.

Multiple Auth Providers with AppEngine, Webapp2, and Cloud Endpoints Proto Datastore

I'm working on a webapp that will allow users to authenticate using simpleauth. For now I will be supporting Google and Facebook. Other than logging in and out (using webapp2), the webapp will consist of Cloud Endpoint APIs. The clients will be web, Android, and iOS.
My questions is, using Endpoints Proto Datastore, can I have user_required=True and call endpoints.get_current_user() to get my user from an #Model.method if the user's auth provider is Facebook (or any of the other supported OAuth2 providers? If it is not possible, does that mean I should not have user_required=True, and should instead get a permanent user id from the provider given the OAuth2 token and keep it in the datastore, generate my own auth token for that user, and then pass that token to each request?
EDIT: Instead of passing the auth token around, would it make sense to have an authenticated user request an "API token" that they can pass to the API methods? Would this token have to be included in the POST or GET body, or can it be put in a header/cookie (I saw some questions elsewhere on SO regarding headers and cookies with Cloud Endpoints, but it's been some time since then). This is all assuming that non-Google auth won't work.
This answer is not going to directly answer your question but should give you a good idea how you can implement authentication in a safe way. I've implemented something similar recently and spent quite some time figuring out which is the best way to do authentication with Google AppEngine environment.
Google supports OpenId Connect protocol. Facebook's implementation should be very similar according to Getting Started with OAuth 2.0 book. I will focus more on Google's implementation, as I am more familiar with it but the concepts should be very similar when using other OAuth providers.
OpenId Connect will give you an id_token, after successfully authenticating the user. It will also give you an access token. Access token is something that should be kept a secret. Never send it over the wire. Id token on the other hand is very handy. It contains some information about your user, and it's encrypted so it doesn't expose any information about the user "just like that". You'd have to crack the id_token to find out anything about user. In the unlikely event that it gets cracked it doesn't expose anything critical about the user. What you can do you can store it as a cookie and then use it in all subsequent requests to verify it the user by checking if there's an access token that matches the id_token. The only drawback is that id_token is quite long - it takes around 650bytes. That would mean that every http request carries that payload. If sending that much information is too much for your use case you can send only first few characters, maybe 12 or so and then match just the first part. The id_token has can also be useful when analysing your data. It will show up when analysing http requests but will not reveal any information about the user and you can still differentiate requests that came from different users.
Also on a side note, don't try using AppEngine's users service as it doesn't work very well with any kind of custom authentication.
Hope this gives you an idea and puts you on the right track.

Resources