AWS Amplify with Amazon Cognito not remembering device with hosted UI - amazon-cognito

I want to be able to remember a user's device using Amplify's hosted UI with React. I set up MFA as required in the user pool. In "devices" I set Do you want to remember your user's devices? to "User-Opt In" and Do you want to use a remembered device to suppress the second factor during multi-factor authentication (MFA)? to "Yes". In the React side I'm using the withAuthenticator HOC.
The problem is when I login, I get redirected to the confirm sms code page without the application or amplifying remembering the device. Also if I look at the device in the user pool, it has the status: note_remembered.
Is there any way to configure this through the hosted Amplify UI and if not how would I do it programatically?
I looked through all the docs and don't see anything even though this seems like a pretty ubiquitous use case.

It has been a while since I developed an Authentication Engine using Amplify. After going through the official Amplify Auth documentation and several Github threads, I was unable to find any API or technique to implement Cognito's Device remember feature.
In this case, I would recommend using a hybrid approach and using the GetDevice, ConfirmDevice, and UpdateDeviceStatus API calls in the native AWS JavaScript SDK, as the functionality is completely supported there.
Apropos which, Amplify is lacking a lot of imperative Cognito features, and I would implore you to raise a support request with the concerned AWS team.

Related

Can we store and read keys in Fido2 device (yubikey)

I am working on an android and iOS application that needs to have a password-less solution for login. We are trying to implement WebAuthn/Fido2 device.
The problem is that Fido is still new and there is no React-Native library that implements that. So I have a few questions regarding it.
Can we read and write our own key in the Fido2 device?
=> Till we get a proper library, I want to store an encrypted password on the fido2 device as a key, read it every time on login, and decrypt it. Is it sounds good to implement and is it possible to do?
#DevPy
To support WebAuthn/FIDO2 from your React Native iOS application, the recommended solution is to integrate one of two Apple iOS system browsers (ASWebAuthenticationSession or SFSafariViewController) that support WebAuthn APIs. ASWebAuthenticationSession would be my first choice as this browser is for authentication through a web service, specifically the OAuth 2 flow. This provides the interface, built-in APIs for interacting with the FIDO2 authenticator, like the YubiKey, and gives the developer control with callback to the session and authentication token. Another way to integrate WebAuthn is to utilize a third-party SDK for communicating with OAuth 2 providers. For example, AppAuth for iOS has a React Native bridge, available here. I believe the AppAuth SDK uses the ASWebAuthenticationSession.
As for the initial question of writing/reading your own custom key, the FIDO2 devices are limited in storage space but the YubiKey offers two options that may work for you. One is the option to create a static password (not encrypted) or utilize the Yubico OTP. Both options use the system keyboard to type out the password or OTP into any text/password field within your app. No SDK or system browser required.
FIDO2/WebAuthn is specifically a browser API. Since you're talking about authentication within a (React) native app then you'll probably want to fall back to equivalent native OS API's instead.
For Android you can use the Fido2ApiClient, which will let you leverage existing FIDO2 credentials on your server for in-app authentication:
https://developers.google.com/android/reference/com/google/android/gms/fido/fido2/Fido2ApiClient
I think the equivalent on the iOS side of native app development is Authentication Service. They have a page specifically about leveraging "passkeys" in your app that will probably help get you started:
https://developer.apple.com/documentation/authenticationservices/public-private_key_authentication

AWS Cognito how to query for the JWT Token after receiving an authorization code

my application requires an authorization code grant flow integration with Cognito and the website responded to me that Auth-Code accordingly.
https://<poolName>.auth.eu-central-1.amazoncognito.com/login?client_id=<clientID>&response_type=code&scope=email+openid+profile&redirect_uri=<redirectURI>
Now I want to know what email address has logged in. As fas as I understood, this is where I would need the JWT token.
How can I query the email adress of the token I have just received?
Any help is much appreciated!
As I was going through that, actually, I still am. I have talked a lot with Amazon Engineers for past weeks, have done a bunch of research on my own and let me clarify couple of things.
Hosted UI is a way to go if you can accept the limitations. This is after all hosted ui, you can only change that much. BUT (!!!!) and I can not stretch this enough: it works only for simple usage. If you start searching you'll see that it doesn't support CUSTOM_AUTH flows which is extremely useful if you want to implement even something as basic as MFA. So if you dream of Revolut-like login page with just phone number email verification - pity, hosted ui will not help.
Hosted UI is more than just UI! It's a whole server! That's why you can't simply replace it.
Now, as we established what hosted UI can't do. What are the alternatives? Of course, you can use other providers like Okta or Auth0, but I assume, you're here because you want to use AWS. But the recommended (by AWS) alternative is to actually implement your own authentication using Amplify SDK. It's quite simple to use, I must say that. But what they don't tell you explicitly, is that it's no longer OIDC flow. Instead, AWS suggests to use their custom flows, such as USER_PASSWORD flow or SRP (Secure Remote Password), where password doesn't fly over http(s) at all.
You might ask: can't I have OIDC with Cognito AND custom flows? Well... you can, but it's not that simple. Long story short, you can use both hosted ui and amplify and possibly create your own cool SSO. For details look at their github page where AWS Labs go through some details.
If you can't afford spending next 2 months working on SSO, but you don't necessarily need OIDC flow and get settle for another solution, you can easily go for SRP or USERNAME_PASSWORD flows.
If you're like me and you're migrating from the old legacy authentication system done... wherever (;)), go for USERNAME_PASSWORD and utilise user migration lambda trigger in Cognito, where you can automatically migrate users once they login with their old credentials! Neat
AWS Cognito is full of traps... Consider that as well
First, make sure your Cognito client includes the email OAuth scope. User Pools > my-user-pool > App client settings > Allowed OAuth Scopes.
Then, decode the id token and you will have the email. You can use JWT.io to quickly decode tokens for testing and development.
UPDATE: You can use the POST /oauth2/token endpoint to fetch the tokens. But in general, if you're creating a frontend for users, it's better to use someone else's UI. The Cognito hosted UI works, although it looks a bit dated and it doesn't support MFA/TOTP. The modern approach is to use the Amplify UI Authenticator component, which supports TOTP and all the flows you'd expect (sign-up, password reset, etc).

Best practice for first-party auth in a native app

We have an auth infrastructure based on OAuth2 that is integrated into a variety of web apps within our organization. We also have a pure native application with no middle-ware of its own, and we want to integrate authentication into this native application. This application already has its own internal login mechanism with a native login screen, and we don't want to have it start launching external components like web browsers in order to display login windows. We are both the app provider and the auth provider, so the concern of the app having visibility into the user's credentials is less of an issue -- we trust ourselves to not intentionally do anything untoward with the user's credentials, and it's the same people writing a login form in the app as writing it on a web site. :-)
We are trying to figure out how best to support having the application continue to collect credentials the way it does now, but use them to obtain an auth token within our auth framework. With the APIs in place right now, the only way I can see for it to be done is to bake a Client Secret into the native app so that it can use a Resource Owner Password Credentials Grant request, since the code that would normally be making this call doesn't have a server side to live in. This feels really wrong, somehow. :-P
As far as I can see it, many of the structures of OAuth don't really apply to this app because it's not living in the context of a web browser, it doesn't have any concept of a "domain" nor any sort of "cross-domain" restrictions. It has been suggested that perhaps we create middleware for this app just for the purpose of exchanging authentication codes for tokens, but the rationale for that seems to be that this middleware theoretically ought to be able to somehow vet requests to determine whether they are legitimately from the application, and I don't see any way to do that that couldn't be faked by anyone with access to the client application code. Basically, the only purpose such middleware would serve would be to make the Client Secret irrelevant with respect to getting auth codes for credentials.
One thought that came to us was, how does something like Windows do it? Windows very obviously uses a native login form, but then some flow exists whereby the credentials that are entered are used for authentication and presumably, deep in the internals of the OS, for obtaining an auth token. Does anybody know if this architecture is documented anywhere? Does Microsoft's architectural choices here have any relation to OAuth2? What is the "best practice" for an application if you take it as a given that it doesn't have middleware and has its own native login form?
FWIW you don't need a client secret to use ROPC Grant to obtain or refresh tokens if the client is configured as a public client, i.e. a client that isn't capable of storing a secret.
RFC8252 OAuth 2.0 for Native Apps encourages using a native user agent for your scenario, using authorization code flows with PKCE. Authorization services like Okta and Auth0 have jumped onboard too, although they still recommend ROPC if the client is "absolutely trusted".
RFC6819 OAuth 2.0 Security discourages ROPC, but also says "Limit use of resource owner password credential grants to scenarios where the client application and the authorizing service are from the same organization", which are first-party apps.
So while the security verdict seems to be that authorization code+PKCE is the best practice, the UX hurdle of showing a user a browser window to log into a native app seem to be keeping ROPC alive. It's difficult to tell if that UX is jarring because people aren't used to it or because people can't get used to it.

Google Cloud Messaging, registration handshake

I've been looking everywhere for an answer to this, it says it goes something like server > GCM > client, the client must register and then it sends the registration token back to the server, but the 'client' part im confused about, does this only work on applications on the device? or can the app be on a website too? so for example if my app is a website, can I have the registration process on a website instead of an actual app on the device?
Yes, the currently listed client apps are Chrome, Android and iOS. Fortunately, you can use Progressive Web Apps to handle push notifications to websites.
The usual prerequisites are listed there, such as creating the Google Developer Console project, and other PWA fundamental configurations (add, register, and install Service Workers). The succeeding steps are PWA-specific implementations for you to have push notification implemented on the web page.
Happy coding!

Can i create a custom authentication system on top of SkylinkJS

i'm building a website that uses WebRTC to share audio and video. Now i'd like to access WebRTC features on Android devices so i can create an app that can receives audio and video streams from the website.
I've looked for a technology allowing me to do that and I've found SkylinkJS.
It looks great but i'm wondering something. Can i build a custom authentication system on top of SkylinkJS logic. What i mean is that i'd like to make sure the connection to SkylinkJS rooms are initiated by users actually authenticated on my platform.
At the moment, i do that using socket.io but i can do it since i'm using raw WebRTC. How can i do that using SkylinkJS? Using the REST API?
Thanks.
PS: i cannot tag this question with 'skylinkjs' since it's a new tag, but it mights be cool if someone could do it.
Yes you can integrate that with the REST API in this Applications REST API link here - . You can generate your own credentials.
You can generate the connecting credentials from your server and then when the User logs in, generate the credentials for Users to connect to the Room. See more in their support article.
SkylinkJS uses key based authentication mechanism to authenticate against the Temasys signaling servers. This ensures that any application using Skylink can only connect to calls in your application if the app can provide the same secure keys (from your Temasys developer account).
Your best bet in looping in Android would be to use the android counterpart. http://skylink.io/android/