Understanding Cognito Identities - amazon-web-services

I've been stumbling around for a few hours trying to understand Cognito and identity management in a mobile app. I'm relatively new to mobile app development. I've made a mobile app before, but never one with a back-end. so now I'm playing around with AWS intending to try just that.
I want to make sure that each user using my app can be uniquely identified so that I can store content that they submit to the server associated with them. But I also want other users to be able to see their submitted content. I haven't decided on a data storage mechanism yet (Amazon seems to offer a few), but whatever it is will have to be an indefinitely free service since I'm not planning on spending (or earning) any money on this app.
Part of what is confusing me is the need to create App IDs with whatever service I wanted to use with federated identities. I am starting to suspect there are multiple kinds of identities that I'm getting confused. Does the App have its own identity independent of a user's identity? I didn't expect to have to create Google and Amazon App IDs just to allow users to log into my app using their Google or Amazon accounts. I suspect I'm understanding the API wrong, and I'm having a really hard time finding applicable sample code usable from Xamarin.
I have this much code (unique identifier x'd out):
CognitoAWSCredentials credentials = new CognitoAWSCredentials(
"us-east-2:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", // Identity pool ID
RegionEndpoint.USEast2 // Region
);
And that seemed to run (in a debugger) without throwing an exception at least, but I'm not clear what it has given me. I'm doubting that this credentials object uniquely identifies the user after they might reboot their device, and start the app again the next day. For that I suspect I need something more, and I'm not clear what. What's the next simplest step to get a unique identifier for a user which I can store along with their content to associate it with them?

Are you set on having users use third part identity or do you want to provide user's their own identity? For federated identities (3rd party) you need to provide an Identity Pool ID which is created in Cognito to identify the federated identity provider. For your own identities in Cognito you create User Pools which also have an ID.
If you want to provide user sign-in and sign-up you want to use Cognito identities and not federated identities. The link below has some good references regarding this -
https://aws.amazon.com/cognito/dev-resources/

Related

Making scheduled requests to Google APIs with service accounts

I have a flask website.
i would like the user to be able to schedule repeated requests for data from one of their Google accounts (let's say Gmail).
From within the website, the user would first authorize the application to access their private Gmail data. From then on, the application, would retrieve the user's Gmail data on a re-occurring basis, without needing to get authorization each time.
Is this possible? I know it would require a service account but can anyone point me in the direction of documentation that describes how this particular scenario might work.
Would such a scenario be allowed to persist long term? Or will their come a time when Google will require the user to reauthorize the application?
Correction, you should not use App Passwords. OAuth is the correct way to do it I believe:
https://www.oauth.com/oauth2-servers/signing-in-with-google/
Here's Google's docs on it, which is more specific to your need:
https://developers.google.com/identity/protocols/oauth2

What links Federated Identities?

"The Facebook SDK obtains an OAuth token that Amazon Cognito uses to generate AWS credentials for your authenticated end user. Amazon Cognito also uses the token to check against your user database for the existence of a user matching this particular Facebook identity. If the user already exists, the API returns the existing identifier. Otherwise a new identifier is returned." - AWS Docs
Is Amazon Cognito only checking for the same Facebook user already in the database, or is it checking all users for matching fields, such as email? I am needing to allow for a user to sign in with email, Facebook, or Google and get the same data regardless. Basically I'm asking if Amazon Cognito links the users together automatically by email, or if this isn't the way to do it.
So if I understand your question correctly in line with what I've said above - I can't currently see an update to the features that I'm talking about - I'm happy to be wrong but....
Federated identities are very separate things if they're not the same session, in order for an identity to be linked they have to already be logged in with the old one and login with something else - in effect although on paper Cognito looks awesome this is why we hadn't used it, our problems were this:
(replacing # with !)
marc!marc.com signs into the user pool.
marc!marc.com signs in via facebook.
marc!marc.com signs in via anything else.
You'll probably end up with 3 users if they're three separate sessions - despite what AWS say if you read here it looks like you can link ID's you can but only if they logged in with the original ID first.
Yes this is silly, yes it really isn't fit for purpose - at a major hotel chain I talked in AWS offices about this and the upgrades were on the roadmap - I haven't revisited it since so hopefully I'm wrong!
NOTE
Please do not accept this answer for about 24 hours as I'd like to give anyone else the opportunity to chip in, I think I'm 100% correct but I haven't looked at Cognito for a while(and I'm a bit scared to because the docs aren't great(sorry AWS) and it nearly drove me off a cliff last time trying to do exactly what you're trying to).

Is there a way to implement "profiles" into an Alexa Skill?

I'm building a nutrition skill and I want to include some calculators. I could have Alexa ask for the parameters each time something is calculated, but I'd prefer to have users set up a basic profile for themselves to store age, height, and weight values.
I found a small section of Amazon's documentation that talks about how the userId element could be used to store attributes across sessions. Will that work for what I'm talking about though? Or will I have to add OAuth?
There are two way to do this:
1) You can use sessions.
In this method, your data will be vanish when session is end (user stop talking with your skill)
more details https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interface-reference#session-object
2) You should implement an oauth 2.0 server to store user data. It is not that easy but you can find some oauth server example in here https://oauth.net/code/
For connecting your skill to your oauth server, you can follow here
https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/linking-an-alexa-user-with-a-user-in-your-system
bonus: If you do not want to implement an oauth server, you can use Login with Amazon (or login with google) services. But you will still need a database server to store data
The userId that you get on your requests uniquely identifies an Amazon account, not a person. Despite the option to switch between different accounts on a single device (see: https://www.amazon.com/gp/help/customer/display.html?nodeId=201628040), the feature to identify people has been discussed (http://time.com/4683981/amazon-echo-voice-id-feature-2017/) but it's not available yet.
As already mentioned in the comments, you will need to persist the session information between sessions and you could use the userId to identify each account.
But in any case, you don't need account linking or using Oauth to simply identify a person.
Additionally, I'd recommend you to stay within the Amazon ecosystem and run your stuff in Lambda (with free tier and with development credits for developers publishing Alexa skills).
If you need help getting started, I have a single-file template for Alexa skills using Python and several examples:
https://github.com/josepvalls/ask.py

GAE Glass mirror creating multiple oauth signins per user

I've created a Glass app in Python. I began with the mirror quickstart for Python and have my app running fine except some users are getting multiple notifications. I only have one row per user in my Credentials table, however when I go and look at my own Authorized Access on my account I see that I have my Glass project listed 8 separate times.
Can anyone tell me how to check and see if the user has previously granted access to my app when they sign in and if so then skip creating a new token.
You can use the user's ID to prevent storing more than one credential for each user.
When you complete the OAuth flow, you'll receive an ID token along with the access and refresh tokens. If you decode this token, you'll see something like this:
{
"iss":"accounts.google.com",
"at_hash":"HK6E_P6Dh8Y93mRNtsDB1Q",
"email_verified":"true",
"sub":"10769150350006150715113082367",
"azp":"1234987819200.apps.googleusercontent.com",
"email":"jsmith#example.com",
"aud":"1234987819200.apps.googleusercontent.com",
"iat":1353601026,
"exp":1353604926
}
The sub key is the one you're interested in. Use this value to uniquely identify your user. If you see a user authenticate with a user ID that you already know, replace the old value.
If you update your question to include the code you're using for your OAuth flow, we can provide more specific advice. Or, you can learn more about this from Google's OAuth documentation.

Architecture for Authentication/Authorization of Mobile and Web Users

This seems to be a reoccurring problem for me as I seem to gravitate around mobile applications the last few years. I want to authenticate and authorize mobile users in addition to web users. I need to make this seamless enough so that users can ease into having a web account without causing interruption to their data. I want the solution to be architectural in topic, not specific to any language/framework.
Requirements/Assumptions
Mobile users must be able to use the native application without a login, including for contributing content (marking favorites, uploading photos, etc).
Mobile user should be securely and uniquely authenticating to the web service even without specifying account credentials.
Mobile user may have multiple devices, which will be unaware of each other.
Mobile user should be able to Register/Login, which should roll in any content into the account's ownership. This "synchronization" should occur with each account that is subsequently logged in.
It should not matter whether an account was created on mobile or web.
Architectures Considered
NO SHIRT, NO SHOES, NO LOGIN = NO CONTRIBUTION. Require login to contribute content of any kind. This prevents the need to "synchronize" device accounts with a master account. Simply require a single username/password + tokens in order for devices to login. Server objects: User, Role
Multi-device self-authentication. Server negotiates with device and hands it credentials which the device stores. Each device self-authenticates and is associated with an anonymous account until Register/Login occurs. If Register occurs, anonymous account is converted into known account. If Login occurs, content from anonymous account is moved over to known account and then thrown away. Devices that lose the self-authentication details will get new authentication details, and the previous anonymous account is abandoned (and then hopefully later thrown away) and not restorable since it was never converted into a known account. Server objects: User, Role, Device
What do you think is a good solution? One of these, or something else?
I would like to propose an idea similar to 2.
Generate an UUID per mobile device. It will serve to identify the device on later occurences when the user generates content and the content is sent to the server.
If, at any time later, the user wants to create an web account, he may register either on the web or on the device. If the user already owns a web account, he may opt to provide the existing credentials on his mobile device once (or devices) and the device is linked to his web account on the server-side.
On the server side, I would allow two different types of entities serving as identities: Web Users which are authenticated by credentials (OpenID comes to my mind as an addition) and devices which are authenticated by their GUID without user interference. Naturally, a web user entity may own several device entities. A device entity is linked to an account when the user opts to link his device to an existing account. Content is generally associated with an identity.
The linkage between user and device is kept and could also be used to display the origination of content.
You would not need to create/drop/convert accounts with generated credentials for mobile users. You would also not need to store the credentials on the mobile device.
There are still some security considerations left open, depending on the criticality of the context of your application. Without any security measures, an attacker would find it easy to abuse the UUID.
I think this is being looked at from the wrong direction. Define an identity on the server as being defined by an arbitrary value. Probably just a DB sequence. Associate any demographic information (name, email...) and usage history with this identity.
Separately, define an authentication entity on the server. This could be a user/password. It could be a device GUID/UUID. It could be a federated ID like OpenID. A given identity can have (and often will in your use-case) multiple associated authentication-entities. Very possibly multiple authentication-identities of the same type. (e.g. GUID for my smartphone, GUID for my iPad...)
Your front-ends (whether web or app-based), use a defined API to authenticate a user; using whichever of the mechanisms that front-end supports.
In some cases (particularly the native app), the presentation of an unknown ID triggers the creation of a new identity. However, as someone pointed out, in this situation you should ask the user if they want to connect to an existing identity. They need to provide authentication as that identity (once) in order to establish that connection.
One other point, whatever the server uses to uniquely specify an identity should be a value that is never provided to a client. Clients only know about the authentication mechanism and its data. That is, the GUID/UUID, username/password,...
In addition to the techniques listed above, something like OAuth is more secure than a locally-generated GUID. Those are one of a: easily-determined or b: easily-lost. If the value is highly predictable (say telephone #) it is easily spoofed. If it is generated at runtime and includes a hard-to-predict value like the hash of the current time when it is first generated, then it must be stored on the device and can be easily lost if the device is wiped. Good GUIDs can be generated, but they are often very type-of-device specific. Things like device serial numbers retrieved from ROM, IMEIs,... This is readily doable. But, is a lot more specific-device dependent than I'd likely be comfortable with.
The biggest real hurdle I see in this whole approach is that it will be awkward to allow an existing device-only (no username/password) user to sit down at a PC browser and connect to his existing account.
Number 2 is good enough as base decision. Users hate registration ;) So ability to use service without registration is good idea.
You can use GUID/UUID to identify devise. And use it as anonymous login before user login.
But what to do if 2 (or more) people use 1 device? Or device will be losed, stolen?
I think no one of the points cover these cases.
I have no idea what kind of web service you architect so can't advise more.
One solution is with a biometric. If the mobile device has biometric sensor, such as a finger print reader, user will enroll biometric with the device (only- due to privacy issues) at the time of purchase. The applications can be written such that every secure transaction requires the user to authenticate the biometric.
This does not seem to be too far off. Motorola Atrix has a fingerprint sensor...