Testing Auth0 locally on a serverless application using AWS Lambda Functions - reactjs

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

Related

How to test with Google Sign In for local development?

I'm using Google's Java Client for server-side JWT authentication, along with their HTML snippet for the frontend. I'd like to do some testing locally to make sure my user flow works - but I'm not able to get my JWT from the frontend sign-in steps.
https://developers.google.com/identity/gsi/web/guides/display-button
I've entered my correct client ID, but I think it's upset that I used localhost:3000/login as the redirect route. Does anyone know how to set this up for local development?
[GSI_LOGGER]: The given origin is not allowed for the given client ID.
I tried to fetch my actual JWT using the Google Sign In HTML snippet. I expected this to work fine, since it's my actual google account and a legitimate client ID.

Using postman to login into a website configured to using Azure AD (SAML)

We currently have a website that is setup to use SSO through Azure AD. it is configured to with SAML.
Yet, we have third application that needs to connect to this website using specific email and password.
This application can do any default connection that POSTMAN can do.
What I do notice is that web all cookies are removed from the browser. the website allows me to enter
the email address and password.
I am trying to configure POSTMAN to test login to this website. And using the POSTMAN configuration i will be able to configure the application.
Any Guidance is greatly appreciated. Thank you!
I have try configuring post using HTTPS POST BASIC Authentication. Not sure if this correct manner as I am not postman expert nor have attempted such authentication method before.
Our expectation is the POSTMAN could login into the website and create a cookie that has an active session.
Postman is not a browser so it doesn't "log in". The authentication in Postman is related to webservice calls. So imagine you have an online shop and you expose your API to a third party (let's say a sponsor or partner). For example you let another site (the partner/sponsor) add items for your common client from his site (instead of him having to logout of that site then login to your site, it's easier and your partnership makes both sites profitable, let's say for our example - so their site would be more like a sort of forwarder - when the user adds an item on the partner's site, they actually add it in the cart on your site).
In our example, they would call your API (for example, adding an item in the cart). The question is, how do they do that? How do you stop abuse from a malicious user? Simple: you add authentication. So what your (theoretical) shop's partner does is use some auth method (as you said, Basic Auth) to call the endpoint that results into adding an item into the cart for purchase.
But this auth is not what the client uses to log in to your partner or your site. It's an internal auth, like a sort of a "technical" user. And what you would do in Postman is simulate that call and the Postman login would be to allow it to call endpoints.
If, on the other hand, you have a separate login call that this is all it does, logging in, then yes, you can use Postman to login, BUT, keep in mind that the login auth info would not AND SHOULD NOT be the same as the API call login info. So you would still use an auth to allow the API call and a (hopefully different) auth for the actual login url as params.
In other words, Postman auth in any POST or GET call is just a way to tell the remote server they can trust you because you identify yourself. A login window like the Microsoft one is one for user accounts which is something totally different.

How to call admin endpoints on GAE without resorting to low level tools?

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.

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.

How to allow mobile apps to login with Facebook and Google to access web service on GAE?

This is in relation to my other question about the need to create a Facebook app.
I've been reading a lot about how to best approach login for mobile apps users (iOS and Android) that access my web service running on Google App Engine. I'm still not clear how to best do it as I would like to offer login with both Google and Facebook. The app and the web service does nothing with Facebook or Google other than I would like to piggyback on their login.
Having only login with Google for GAE is very easy and the same goes for using OpenIDConnect. Facebook unfortunately does not support this.
Reading an old question here on SO where someone wanted to do the same as I it looks like the app should do Facebook Login and then get a token that it passes to my backend which needs to be validated by contacting Facebook. Is this how to do it today?
I also found Google Identity Toolkit, which seem to be what I need. However, I do not have a website or just apps. I would need to have the apps do the Facebook login and somehow provide my web service with something so it can validate the login info.
Later on an app user should be able to log in using randomly Facebook, Google and my custom username/password. The app and the web service should know the user is logged in and authorize it to access the REST API.
How do I accomplish this? BTW, I'm using Go on GAE.
I would really appreciate if someone could explain if there are several options how to do this, pros and cons, and provide an overview of the best approach and what needs to be done.
Many thanks for any help with this!
UPDATE
OK, thanks a lot everyone for the help and pointers. I have successfully run the quickstart sample app for iOS for my GAE backend. Basically, created a Facebook app and permissions credentials on my web service on GAE so that the sample iOS app can log in.
A bit of a gap still before I have an authenticated user in the datastore and can authorize successive API calls.
Main open questions at this point:
how to get the gtoken in the iOS app after successful Facebook or Google login?
should I explicitly call an API on my web service to pass in the gtoken or is this somehow automatic with Gitkit API enabled?
Thanks for any help!
UPDATE
To answer #1 and #2 myself, there's a "successful sign-in url" that can be given in the app engine config so the app knows where to call with the gtoken. Then after that it's like explained in the answers.
Looks like you have an app and a backend on GAE.
If you are using google identity toolkit, it will allow you to signin with Facebook, Google, and email/password.
When user successfully signs in to your app using identity toolkit, your server should receive a gtoken. You have two options here:
Pass the gtoken to your app and save it there. When your app makes API calls to your backend, you app should attach the gtoken to every request. Your backend should verify the gtoken(https://developers.google.com/identity/toolkit/web/required-endpoints) for every API that needs authorization.
Verify the gtoken, generate a token that your backend can recognize/identify the user. Then pass the token to your app and everything else is the same as option 1.
If you do not want to use identity toolkit, you can implement facebook login on your app/backend and use facebook token to communicate between your app and backend.
Whatever your decision is, apps that use your API should pass you something that your backend can recognize/authorize the user.
The answer is about using Google Identity Toolkit (GIT). GIT itself is an identity provider, which would be integrated with your apps and backend. The flow works along these lines:
your app requests login via its GIT API
GIT will perform the federated login with Facebook or other 3rd party provider (transparent to your app) and returns a GIT token to the app (representing a unique user from your end-to-end system perspective, i.e. apps plus backend)
the app makes a request to the backend in which it passes the GIT token
the backend verifies the GIT token validity (using this go GIT client API, for example) and from it can extract the identity of the user and thus validate the request
You can find more detailed info about the backend token validation in the backent endpoint doc, look for these sections in particular:
Understanding the Identity Toolkit cookie/token
Getting information for users
Now the actual token validation on the backend may take a few seconds, so it might not be practical to do it for each and every REST request from the app. If so you'd need to somehow:
save the info that the user of that specific app instance is
authenticated in something like a "session" managed between your app and the backend
map a specific REST request received by the backend to a specific such authenticated "session"
But I'm not sure how exactly is this "session" functionality done in the apps+backend context, I didn't write any apps yet.

Resources