How to call admin endpoints on GAE without resorting to low level tools? - google-app-engine

We're using Google App Engine (python) and Google Cloud Endpoints (OpenAPI).
We have some endpoints for admin-exclusive use. In our app.yaml we have something like this:
handlers:
- url: /_ah/api/appname/v1/admin/.*
script: main.api
login: admin
Usually I use Postman when I need to POST a special request, but for requests to login: admin endpoints, Postman redirects to and opens source of the Google Login page, which doesn't actually allow me to login.
If I open such redirect URL in the browser, I'm actually able to login, but after that, I'm redirected to the GET version of the endpoint, which doesn't help as well. I don't think the browser has a feature which easily allows me to make a custom POST requests after I've login.
So in the end I see two alternatives... one would be "importing" the authentication cookies into POSTMAN after login. The other would be use javascript in the browser's console to "manually" make the POST request I'm trying to make.
Both options seem to me somewhat overcomplicated, and I feel like I gotta be missing some easier way of doing what I'm trying to do.
So my question is what's an easy way to make a POST request to a deployed google cloud endpoint which is protected by login: admin?

Upon investigating I see you're using App Engine with Python 2.7 runtime and that the login: admin endpoint is authenticated with Google Accounts. When you protect the endpoints all requests made to it need to be properly authenticated in order to be accepted, therefore you actually need to provide your authentication credentials to the server with every request. Since the credentials posseses a Time To Live for security reasons you cannot simplify the process permanently storing them in a file.
The answer is indeed in your question, if you want to use POSTMAN you have to import the cookies after login or create a script that handles both the authentication process and the subsequent request. Here's the documentation for POSTMAN if you decide to go this way and here's Google's documentation on making authenticated API requests.
Nevertheless, there are some important things to note. Python 2.7 is sunsetting, this means that security vulnerabilities may appear and probably won't get patched which could result in huge security breaks and/or the need to rewrite your whole backend in the newer python runtime; Google's documentation encourages the switch.
Additionally, the users library will be deprecated at some point too, so you might consider changing your authentication scheme to use Auth0 with the advantage that this option is available for both runtimes.

The cookie associated with authenticating this kind of endpoint protection is called SACSID, and the domain is your own application domain, that is, in the format project.appspot.com.
You should be able to call an endpoint using the browser, which will redirect you to the google login page, and after authenticating you should be able to copy the cookie into Postman, allowing you to make authenticated endpoint calls from there.
When adding it in Postman, you'll need the domain, the cookie name and its value.

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.

Testing Auth0 locally on a serverless application using AWS Lambda Functions

Before my question, it's important to note that the app I'm working with has been given to me pre-built with little documentation. Long story. I've never worked with a serverless application before, hence my complete confusion.
Here's some context:
I have a serverless application: React app that sits in a S3 bucket, being served by AWS CloudFront. It uses Auth0 for authentication. Currently, the logic is, if a user tries to visit the app's domain, Auth0 pops-up with a login prompt. The user enters their credentials which is then sent to an AWS Lambda function, which exchanges the confirmed login credentials for a JSON web token. This is sent back to Auth0 which then redirects the user to the app's domain (Please critique this explanation if you think I've misexplained something).
I'm trying to test Auth0 locally so that I can access the roles I've assigned to each user to eventually serve that user data specific to their role.
Problem:
However, I'm unable to test Auth locally. When I run npm start at localhost:3000, I'm taken straight to the main page, skipping login entirely.
I understand this could be because of numerous things, but here's what I've tried.
I've gone to my Auth0 dashboard, and under Allowed Callback URLS, i put http://localhost:3000/logincb. (logincb is the callback given during the AWS Lambda step).
I tried using ngrok to create a secure connection and then putting this url in Allowed Callback URLs, still no Auth0 pop-up on localhost.
I tried putting in conditons in the Lambda function if the request url is localhost:3000 i.e do the exact same thing as you would if the request url was the app's domain name
I can post the Lambda function if that's helpful. It's similar to the examples given on AWS Lambda's docs for example functions when using Amazon CloudFront. It has functions for handling cookies, webtokens, post request to Auth0, etc.
I apologize for the vagueness of the question, I just need some inspiration/ideas at this point.
Peace and love

Google Cloud Pub/Sub Publishing from Browser - How does Auth work?

I have a requirement to use Google Cloud Pub/Sub API directly from Browser ( similar to GA script). I was wondering how can in handle Auth without requiring going through a back-end server.
I want to invoke the Cloud Pub/Sub API directly from the browser. I tried and it says i need to authenticate first , my issue is how to secure the Auth Token.
Is there any javascript library that is available which i can use in Browser ( not backend) to invoke the Google Pub/Sub API.
Thanks in advance
The general approach in Javascript for authorizing and making authorized requests to Google APIs is shown at https://developers.google.com/api-client-library/javascript/samples/samples#AuthorizingandMakingAuthorizedRequests -- it's not specific to the Cloud Pubsub API, but it should work for all Google APIs. Similarly, https://developers.google.com/api-client-library/javascript/start/start-js for general Javascript access to Google APIs.
This is quite an old topic, but I've been recently assessing if it's possible. The simple answer is - yes, it is possible to send messages into PubSub topics directly from a browser application. The solution is as follows:
You need to post a message via REST API using fetch()
You need to send the Authorization header
Authorization header has to contain oAuth2.0 token identifying the user; it can be an anonymous authenticated user or fully authenticated, using firebase authentication library for example.
To have all three above working perfectly, you'd have to write a lot of code. It is not practical at all and architecturally not nice. Unless you absolutely need to do it that way, not another (I can't see why though), the simplified but involving a bit more components solution is as follows:
Authenticate user in-browser via firebase - can be either anonymous or full user
Do simple GET or POST to your cloud/firebase function with the required payload
In function validate the incoming request which will have authenticated user token
If validation is good then publish message into the topic
This way it's still secure, much more maintainable and clearly separated into functional components. Less code, a bit more infrastructure.

Authenticate to Google AppEngine application which use federated login from Windows Client Application

I'm plan on deploy a Java application to Google AppEngine and use federated login (still experimental according to Google). The application is pretty simple Java EE application which expose RESTful interface for simple CRUD operations.
I then want to be able to authenticate to this application using Windows Client Application written in C#.
I think the application should be able to open a window with a browser in ti which will present the login page of my web application and after successful authentication I should be able to get the login token or a cookie to use in the rest of my HTTP requests.
Is it possible to do such thing using federated login? I've found a post explain how to do it using google proprietary login.
Thank you,
Ido.
I've manage to make this work much easier then I thought it would be.
When I send HTTP request to my web service I get 302 Found response with response header name Location which point to the login page.
I use WebBrowser control, register to it Navigated even and navigate to the URL in the Location header.
When the Navigated even fire I use the code from this answer to get the cookies container.
I check each cookie until I find one with the name ACSID and store it.
For every web request to my service I add cookie name ACSID with the value saved at step 4.
This is not the most secure way of doing this. I will add check for the domain of the cookie but this looks good.

Can I use browser authentication to make RESTful calls to GAE?

We're writing a Desktop application that relies on Google Appengine to authenticate the user and retrieve and store data associated to it.
The way we'd like to authenticate the user is that on launching the application the browser is launched at the login url for our application. Then the user logins there, and then the application makes restful calls without any OAUTH object, but re-using the browser session. I'm questioned that this won't work, since we cannot so transparently use the browser session. Is that correct?
Any alternatives beside authenticating from within the app using the ClientLoginApi?
I'm aware of:
How do you access an authenticated Google App Engine service from a (non-web) python client?
The only way to do this is if you can capture the authentication cookie used by the browser, and send it yourself. Obviously, there's no browser- or platform- independent way to do this.
A better option would be to use OAuth, with OAuth for installed apps to obtain the original token.

Categories

Resources