I try to sync data for a Cognito authenticated user using the new User Pool.
From what's suggested here:
"Note that the generate client secret box must be unchecked because the JavaScript SDK doesn't support apps that have a client secret."
On the other hand for Android only apps with a client secret are supported.
So I added 2 apps to the User Pool, one with a client secret and one without it.
However, in the Identity Pool I can only add one App Client ID as an authentication provider.
So I get: "com.amazonaws.services.cognitoidentity.model.NotAuthorizedException: Token is not from a supported provider of this identity pool." when trying to use an authenticated token for the Android app.
Am I doing it right, or am I missing something?
Thanks!
Figured it out.
It is possible to add multiple (up to 100) apps or "audiences" to an OIDC provider through the IAM as explained here
So I set up the OIDC and added it as the authentication provider to the identity pool.
Since you already worked out a solution, one additional thought:
On the other hand for Android only apps with a client secret are supported.
The Android SDK for Cognito User Pools should allow you to handle apps without a secret, you should be able to just set that value to null. Check out the sample app for more details, if you are interested.
Related
Context:
I am currently working on an embeddable widget, something akin to Intercom or
Hotjar, and have the need to authenticate users. Thus far, I got away with
using Passwordless authentication using Firebase auth but users complain that
it's a high friction process, and they'd rather not do it at all. The ideal
authentication solution would be to let users use their Google or Facebook
account and authenticate via OAuth2.
Problem:
Firebase Auth restricts authenticating via 3rd party auth providers if the
domain the user authenticates via is not whitelisted in the authorized domains
list. So if the user puts the code in abc.com, and tries to auth via Google
firebase rejects it because abc.com is not in the whitelist. Whitelisting the
domain of every client is unorthodox. I feel like the way I'm approaching it
is wrong because I can't correctly build up a mental model of how this would
work out. Technically cookies, sessions, etc. are pointless.
Question:
How would I go about providing the ability to let users authenticate via 3rd
party auth providers? Is this even technically possible?
Potential Solutions:
Host the widget at the main app in a dynamic route (the website where the user
would get the widget's code) and render this route as an iframe in the
client's website. (ex: /widgets/{widgetID} would have the widget). I don't
want to do this really because iframes are a serious pain but this sounds like
the most feasible.
I'd like to know more/better solutions to address this particular situation.
It doesn't matter even if it's from a different cloud provider or a different
authentication service. The goal is to authenticate the user from the widget
ideally via a 3rd party auth provider like Google.
EDIT: This is the error that I currently receive:
widget.js:2 auth/unauthorized-domain This domain (xyz.com) is not authorized to run this operation. Add it to the OAuth redirect domains list in the Firebase console -> Auth section -> Sign in method tab.
Based on your use case, you need to verify the domain ownership xyz.com by following this guide
After that you need to add xyz.comto Authorized domains your, as the error message mentioned.
Add it to the OAuth redirect domains list in the Firebase console -> Auth section -> Sign in method tab.
For more information please check this guide
Is not possible enable Google Sign In by using a domain unverified or unauthorized, this is to protect the access to your sites/projects by restricting the usage of the Firebase/Google credentials only for configured domains.
There is no way to disable this setting, Google sign in uses Oauth2 as authentication framework
We have a web app that caters to a small set of users that are guaranteed to have an account on Office 365.
To save them from remembering one more password, and to use Microsoft's infrastructure for OAuth, we decided to allow them to login using their Outlook credentials.
It is a react app, we are using the msal library and we have successfully been able to receive the accessToken from Microsoft. (Thus, authenticating the user's identity.)
What I am not confused about now is what I should do with that token:
I need to have my own User database. What information should I store in it? Should I store the access_token as well?
How do I verify the user's identity on my backend server?
Basically, what is the ideal way of managing this kind of a scenario? Wherein a third party authenticator is used (and solely) used to confirm the identity of the user and get the name, profile image and other things only.
Any references to existing workflows or an explanation of the steps involved will be highly appreciated.
I need to authenticate users in browser (not mobile app) using AWS Cognito with username/pass, not FB/google IdProviders.
There are a lot of docs but they seem to be separate blocks which either incomplete, do not fit the requirements or do not fit each others :(
I created Cognito User Pool, then Identity pool and tied the userPool to the idPool, then I stuck. Do not know which library to use and how to use it.
The closest I find are:
https://aws.amazon.com/sdk-for-browser/ but my experience is not enough to convert their FB samples to not-using FB
https://github.com/aws/aws-amplify but using this lib I'll have to study React/Angular from the very beginning (I'm not a front-end developer, sorry) and I have no clue how to convert their npm-based samples to front-end javascript (npm is for NodeJS thus back-end, isn't it?).
All I need is plain html form with username/pass, send the request to Cognito and a way to check during the next page load whether the password was correct. If it matters I will use AWS Lambda as back-end for processing future tasks.
How can I do it? Is there a tutorial/doc for my case?
Thank you.
You can use AWS Cognito UserPools Hosted UI for your use case. The simplest form of authentication is using the Implicit Grant.
For more information about setting up Hosted UI refer Add an App to Enable the Hosted Web UI.. This will create a UserPool where users can register them self (If you plan to restrict this, you will need to either add users using the AWS Web Console, Cognito UserPools or using their SDK)
The steps are as follows.
Set up Cognito Hosted UI and register your application domain. This will create the login/registration pages for you where each of this will have a unique URL. What you have to do is, if the user is not authenticated (Let's discuss how to detect it later), you need to redirect the user to the Login page.
In the Login URL, you also need to specify the redirect back URL to the application so that after a successful login, Cognito will redirect back the user to the application providing the token in a query string.
You can then access the id_token from inside the application and use it for querying the backend.
Since the id_token is a JWT token you can verify it at your Backend using the public key available at the Cognito token endpoint.
To implement the JWT verification, you can also refer Cognito JWT Token validator NodeJS module.
Note: If you need to keep the user's logged in for a longer time period (Than 1 hr), you might need to use the Code Grant flow which will return a Refresh Token, which could be used to retrieve new id_tokens programmatically.
We have a native Android app where we are using the the latest version of the Cognito SDK to authenticate the user.
The problem we have is that the Android app uses a Web view and in this web view we will need to fetch the current cognitoUser with its authenticated session.
We are using the latest Cognito javascript sdk in the web view.
How do we share the auth between 2 clients that uses the same user pool?
Update 04/10-2017
I managed to bypass this by sending everything Cognito related i had in my local storage as query string parameters. Then "in" the webview i saved the settings to that local storage.
It is not right but it works ;)
I believe this is not possible. The web-view has its own storage that is not shared with the device storage.
So the user context - users tokens, login state etc - is not shared between the webview and the Android SDK on the device
I have now been in contact with persons that are experienced working with Cognito.
The judgment was that we can bypass this by sending all Cognito related values as query parameters to the application behind the web view.
The application in handling the web view will then take all those values and save them to local storage.
Problems I had:
I found out that if you have multiple Clients you will have to pass the clientId of the application behind the web view.
I have an ASP.NET MVC website deployed as Azure website (called website). That website has a section that needs authorization. I already have set up Windows Azure Active Directory (WAAD) to protect access to that section. Once that protected section has loaded, it will load a Javascript app that allows integration with the Azure Mobile Service.
I also have a separate Azure Mobile Service that I use for data storage (called mobserv). I want to access mobserv table and api endpoints from website. I am using the .NET backend for Azure Mobile Services.
Of course, I need to protect those mobserv endpoints using [AuthorizeLevel].
Tutorials show how to do this when I want to authenticate as Application (using [AuthorizeLevel(AuthorizationLevel.Application)]) - just add a reference to the proper Javascript Client (MobileServices.web-1.2.5.js), provide mobserv app id and token. CORS is set up to allow interaction. So far, so good.
But now, I want to protect certain endpoints using [AuthorizeLevel(AuthorizationLevel.User)]. So now, the request has to be authorized as User. Since the website already has been protected by WAAD, I do not want the client to perform a new sign in for the javascript client - I want to reuse the current WAAD authentication headers to have a Single Sign On Experience, so that mobserv will recognize the user.
I have not found any hints on how to do this. Tutorials only show application level auth against mobserv or using explicit login dialogs.
Does anybody have a clue how to do this?
Following up on vibronet's post, Mobile Services does support HTTP POST of an access token, but the access token must specify the audience as your mobile service. So a token issued for your website will not work on its own. You will need to transform it through one of the AAD flows.
So in AAD, you need you have two web application registrations, one for your web site and one for the mobile service. On the mobile service registration, you would need to define permissions that can be exposed to the other resource. The first section of the Mobile Services + ADAL tutorial ("Register your mobile service with the Azure Active Directory") walks you through this. Then, instead of registering a native client app which accesses that permission, you would go to your web site registration and configure the access there.
Once you have an AAD token for your website, you can leverage this permission to get a token for the mobile service. This can best be accomplished using an on-behalf-of flow in the Active Directory Authentication Library (JS or .NET, depending on where you want to do things). The AAD team has a nice sample on how to do this, and mobile services also has a tutorial which might be helpful, although it does mobile service access to SharePoint Online as opposed to web site access to a mobile service)
Then you can send the token to your mobile service using the "client flow" method, as described in "How to: Authenticate Users" for the HTML/JS SDK. For AAD, the call will look something like:
client.login(
"aad",
{"access_token": "<TOKEN-FROM-AAD>"})
.done(function(results){
alert("You are now logged in as: " + results.userId);
},
function(error){
alert("Error: " + err);
});
The user will not see any new UI, but they will be logged in, and subsequent calls from the SDK will be authenticated.
It might also be easier to do this from your MVC backend. I believe you can get the access token from the ClaimsIdentity, and then you can just use the Mobile Services .NET client SDK to do the login action and facilitate calls from the MVC site to your mobile service:
JObject payload = new JObject();
payload["access_token"] = "<TOKEN-FROM-AAD>";
MobileServiceUser user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, payload);
token reuse 'as is' cannot be achieved given that the tokens you get for website are scoped to your app and should be rejected if forwarded to any other resource. From the AAD perspective there are various flows that would allow you to trade in your original token for a new token meant to be used with a web API - all without requiring any new action from the user. However your scenario includes some Mobile Services specific moving parts, hence I am not sure how that would apply here. I am flagging this post for the Mobile Services guys, hopefully they'll be able to chime in.