AWS API Gateway Method Authorization - angularjs

I have domain with aws example.com, currently I have record set so that when user goes to example.com, it serves static website from S3 (done with angular) and backend api (Lambda and API gate way). And I don't have sign in process, as the purpose of site is public facing.
I can use apikey on method to authorize the http call, but I still have to save it in js code somewhere, which I don;t want to do. And I am not sure how IAM role can help me in this scenario.
Is there any way I can let api allow calls from specific domain ?

You can use IAM Role defined for Unauthenticated user in AWS Cognito Federated Identities. The AWS document will guide through the process assigning IAM Role to the Unauthenticated user.
Then you can enable "AWS_IAM" Authorizer option in the API Gateway for any specific API's resources.
This question has similar approach in implementing the IAM Role - based to access API, in which the implementation is using External Federated Identities (Google) instead of unauthenticated user identities.

There are a few ways to skin this cat.
The least painful way is likely to be using AWS Signature V4-- unfortunately, there's no great answer for a site that doesn't have an auth system built in already. Someday they'll let us park API Gateways inside of VPCs, but that day isn't today.

Related

Authentication flow Service to Service Microsoft Graph and Bookings API

I am building a custom mobile application that has a client, custom backend server (I'm building) and interacts with numerous other api's. One of these api's is Microsoft bookings.
The problem I'm facing is I need to be authenticated via server to server, with a shared client secret. I'm aware of the numerous docs from MS but have yet to find a solution. I'm wondering if Server to server is even possible with Bookings.
I am able to get an access_token server to server with these permissions. (I have granted 'all permissions' to this app in Azure AD already).
"roles": [
"Calls.JoinGroupCall.All",
"OnlineMeetings.Read.All",
"OnlineMeetings.ReadWrite.All",
"Application.ReadWrite.OwnedBy",
"Calendars.Read",
"People.Read.All",
"Application.ReadWrite.All",
"Calls.InitiateGroupCall.All",
"Directory.ReadWrite.All",
"Calls.JoinGroupCallAsGuest.All",
"Sites.Read.All",
"Sites.ReadWrite.All",
"Sites.Manage.All",
"Files.ReadWrite.All",
"Directory.Read.All",
"User.Read.All",
"Calendars.ReadWrite",
"Mail.Send",
"ProgramControl.Read.All",
"ProgramControl.ReadWrite.All",
"Calls.Initiate.All"
],
Those are the permissions from the decoded token. When I go to make calls to the Bookings api I receive 401.
I can however use this token to access different graph endpoints no problem.
I will note, that I am able to make successful calls to the bookings api through Graph Explorer with my account, not related to this 'Application in Azure AD'.
Does this resource in Azure AD need a bookings License?
Is this even possible S2S?
Are there any other ways to bypass this without user credentials?
Thanks.
So I spent over a week trying to solve this problem due to the MS doc nightmare. I'm only posting to help others!
Bookings doesn't support service to service yet. So if you wan't to implement this without a user physically signing in, IE. If you have a dedicated booking admin account credentials you have to hard code the clients credentials.
I found my answer here https://stackoverflow.com/a/49814924/9105626
Microsoft Bookings API doesn't seem to support "Application Permissions" so far.
Only permissions available are "Delegated Permissions", which means your token has to be acquired with the context of a signed-in user.
Here are two Microsoft documentation sources that I came across:
Microsoft Graph Permissions Reference - Please look at the "Bookings Permissions" section.
Microsoft Bookings Samples
I know you mention Server to Server authentication using a client secret. AFAIK, that case will NOT work directly, because clientId and clientSecret only provide an application's identity (which can't be assigned any permissions because there are no relevant application permissions available for this API).
Just in case you can have some User context involved, here is code from bookings samples link above, to acquire the token in a Native application using ADAL
var authenticationContext = new AuthenticationContext("https://login.microsoftonline.com/common/");
var authenticationResult = await authenticationContext.AcquireTokenAsync(
"https://graph.microsoft.com/",
clientApplication_ClientId,
clientApplication_RedirectUri,
new PlatformParameters(PromptBehavior.RefreshSession));
// The results of this call are sent as the Authorization header of each HTTPS request to Graph.
var authorizationHeader = authenticationResult.CreateAuthorizationHeader();
Suggestions on ways to make this scenario work
On Behalf Of Flow
Your mobile application client could prompt a user for credentials to act on Behalf of the user and call your backend web API, which in turn calls the downstream API like Bookings API. This is called Service to Service Calls on behalf of the User
Here is a code sample which shows exactly this with a native application (WPF) and an SPA. In your case, just replace the WPF application with your mobile client application for understanding purposes and rest of the scenario becomes very similar.
Calling a downstream web API from a web API using Azure AD
ROPC Grant (Not Recommended)
Resource Owner Password Credentials grant can help as your application will have end user password available to it, but it has multiple issues and any security guidance will discourage you from using it.
ROPC opens up security risks, doesn't follow best practices and has functionality issues as well. ROPC doesn't work with MFA enabled users as well as federated authentication users.
For all practical purposes, you should avoid ROPC as long as possible. You can find the same recommendation in ADAL documentation itself and multiple other documentations from Microsoft or even generally about OAuth 2.0.

Google Cloud Endpoints - Authenticating users from internal database

(intro)
I am new to Google Cloud Endpoints and I have started to build some HTTP REST services.
The purpose of those services is to be consumed directly by the users of my application (Business to Consumer - not business to business).
(The question)
I need to secure my services in a way to have only registered users being able to retrieve sensible data (and after login). My main purpose is to have the list of registered users saved in my database on CloudSQL (Dont want to use FB of Google Accounts). I was not able to find particular information about this point in the official Google documentation regarding authentication.
Can anyone advise me of the way to proceed and suggest some tutorials?
Thank you in advance.
The Endpoints proxy can validate JWTs, and we provide a couple of alternatives for creating those. Both Auth0 and Firebase have good user management capabilities and client-side libraries for generating JWTs. Both allow you to choose an identity provider (like FB or Google) or simply use username/password.
Check out the documentation here.
If you don't want to use Auth0 or Firebase Authentication, you can sign JWTs yourself with a private key and just give the proxy the URL of the Public Key (see the "Custom" tab on that same documentation page).
As far as looking up individual users in the database, you would have to do that part on your own.

OAuth2 Resource Owner Credentials Flow : how to be sure the given client_id is the official app's one?

I have a REST backend secured with OAuth2 and a mobile application.
I would like to use the Resource Owner Credentials flow to authenticate the user from my mobile application.
Since I must provide a client_id to identify the application which is requesting authentication, how can I prevent a hacker to steal my client_id from my mobile application source code, and how can I revoke it ?
I really would like to know how the official Twitter Android application for example handle this kind of thing.
I know this is a very old post, but I just came across it in an unrelated search and saw it was unanswered.
To quote from the OAuth 2.0 spec,
The client identifier is not a secret; it is exposed to the resource owner and MUST NOT be used alone for client authentication.
In other words, the client_id is very similar to a username or email. I certainly wouldn't mind if someone found out my email address, even though that is half of the data required to log in and view my emails. To keep to that idea, the client_secret is a password that should be kept private through guarding your source code and sending POST requests only to HTTPS endpoints.
As for revoking privileges granted to clients through those credentials, most (if not all) major OAuth providers will allow you to do something through their OAuth portal. To follow your Twitter example, they have a button on the API Keys page to "Regenerate API Keys." If you are the service provider (I say this because you mentioned having permissions to Resource Owner Credentials) and you don't have a public-facing OAuth portal set up, it would be simply a matter of changing the strings in whatever data-store you use server-side, then making the same change in your client source code.

Python GAE app using 2-legged OAuth and 3-legged OAuth at same time

I'm coding a Python - Google App Engine application. There are 2 important things this app must do:
Write in user's calendar.
Write in user's profile (working with users in a Google Apps domain)
First operation is easy. If I understood OAuth, this is the classical 3-legged scenario. The scenario for which OAuth was originally developed. The logged user provides credentials to the client (my app) to access the user's data (calendar) on his/her behalf. So, this can be done just with the logged user's credentials.
Second operation is not so easy. It can't be done with just the logged user's credentials. This is a 2-legged OAuth scenario. So, I need to delegate in a Google Apps domain admin's account to access the users's profiles using Google Profiles API (via google data library). So far, I hardcode admin user/password in a json file, and my app loads that file. But that sounds kind of dirty for me.
At the end, my app needs to handle the classical 3-legged OAuth scenario (no problem, just need the logged user's credentials) plus a 2-legged OAuth scenario (need administrator credentials).
Is there any official or more elegant way to handle both scenarios in Google App Engine, working with Google Apps domain, that hardcoding admin credentials?
Many thanks in advance
AFAIK there is no way to authorize a write operation to Google Contacts Data API using 2-legged OAuth.
Google's documentation specifies which APIs are accessible via 2-legged OAuth, but it seems that someone at Google's forgot to specify that some of them are read-only :-S
Some people had the same problem here and here.
I look forward someone at Google to fix this. Until then, harcoding admin-level credentials is the only option I know that it works. I don't like it at all: it's dirty but effective. If someone knows a more elegant zen-level way, please illuminate us!

SalesForce to emulate a google session login

I'm pretty new to SalesForce and their Apex language. I've been reading some documentation and tried the integration between Google and SalesForce.
I'm wondering is it possible to emulate an auth token from google to SalesForce?
I'm trying to read a google spreadsheet and then fill up a SalesForce object automatically. The user login will always be the same/universal for this spreadsheet, so I have the credentials required to login.
I am working off of the sample that requires a visualforce, and I'm wondering how would I automatically do the session id token that the google spreadsheet API requires.
Any ideas?
The old-school, hard way would be to send a login() call to the API (available through SOAP messages). Salesforce API is well documented and plenty of examples are available (both in programming languages and for raw XML requests/responses).
But I have no idea what possibilities you have from Google side, if it's only JavaScript then you might not be able to send and retrieve AJAX-like calls to another domain...
Recently another option emerged and that is REST API (no SOAP needed). Looks more promising and easier in my opinion. Quick intro is available here and you'll find more documentation on the bottom of the page.
Last but not least - 2 interesting links:
http://code.google.com/apis/gdata/articles/salesforce.html for some integration tutorial
and built-in integration offered by Salesforce: http://www.salesforce.com/assets/pdf/datasheets/SalesforceGoogleApps.pdf
I've used custom settings to do this. Use OAuth to get a token for Google, then store that token in Salesforce custom settings (Setup-Develop-Custom Settings). You can then retrieve the token for callouts to Google from that custom setting for any user needing access to Google Apps. The downside is, every user will authenticate as your custom setting token user. The upside is that they won't need to individually authenticate. Custom settings are retrievable via Apex using a simple getter, and live as Apex-like objects.
Also keep in mind, Google requires each service to use it's own token. So, if your user wants to use Calendars and Spreadsheets, that's two separate tokens that will need to be stored and retrieved for the callout.
I generally allow users to create their own authenticated session tokens via OAuth if they want to do that, then failover to the custom settings to get the general admin token if necessary.
Are you trying to log into Google Apps from SFDC? There are options for Google Apps within Salesforce, go to Setup > Administration Setup > Google Apps > Settings. I've not used this and it requires some setup, but thought I'd point it out. Aside from that I can only blurt out OAuth (getting users to authenticate with Google from within Salesforce when trying to access Google Apps) and SSO (which I know can be used to authenticate from an external system, though not sure if it works the other way).
Look into the "Named Credentials" menu in salesforce setup.
There, you can store auth credentials for the services accessed via Apex:
"A named credential specifies a callout endpoint and its required authentication parameters. When setting up callouts, avoid setting authentication parameters for each callout by referencing named credentials."
a username/pass combo can be used, or a certificate, or an AWS signature, and there is a JWT option..
Help docs: https://help.salesforce.com/articleView?id=named_credentials_about.htm&type=5

Resources