question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RFC: Auth Enhancements - Easier Federation with Cognito User Pools and Hosted UI

See original GitHub issue

Overview: Based on feedback there is a fair amount of confusion when using User Pools for Social Provider Federation, especially when building a custom UI and bypassing the default Cognito Hosted UI. While Amplify documentation gives an overview of using redirects within the OAuth flow, this is cumbersome, error prone, and seen as difficult by customers who are unfamiliar with these flows. Therefore we wish to build this into Amplify’s Auth category via a simple, declarative API. There are several phases and potential future options with different trade-offs which are outlined below.

Please reply with a +1 or detailed comment on a feature if you have specific thoughts around how it should work.

Related Issues: https://github.com/aws-amplify/amplify-js/issues/1316 https://github.com/aws-amplify/amplify-js/issues/2644 https://github.com/aws-amplify/amplify-js/issues/2543 https://github.com/aws-amplify/amplify-js/issues/2525 https://github.com/aws-amplify/amplify-js/issues/2518 https://github.com/aws-amplify/amplify-js/issues/2512 https://github.com/aws-amplify/amplify-js/issues/2503 https://github.com/aws-amplify/amplify-js/issues/2456 https://github.com/aws-amplify/amplify-js/issues/2423 https://github.com/aws-amplify/amplify-js/issues/2283 https://github.com/aws-amplify/amplify-js/issues/2168 https://github.com/aws-amplify/amplify-js/issues/2156 https://github.com/aws-amplify/amplify-js/issues/2115 https://github.com/aws-amplify/amplify-js/issues/1585 https://github.com/aws-amplify/amplify-js/issues/1521 https://github.com/aws-amplify/amplify-js/issues/1392 https://github.com/aws-amplify/amplify-js/issues/1386 https://github.com/aws-amplify/amplify-js/issues/1281

Phase 1: Add User Pool Federation to federatedSignIn()

Amplify has an Auth.federatedSignIn() method today which allows customers to pass tokens to Cognito Identity and retrieve AWS credentials, which are then used to sign requests (with Signature Version 4) to AWS services. Request signing happens automatically when using other Amplify categories.

UPDATE: A new value of federationTarget will not be needed to the config. Instead in the design we are inferring the behavior from the existing configuration values.

Depending on the presence of Cognito User Pool or Identity Pool value passed to Amplify.configure(), the call to federatedSignIn() will use User Pools or Identity Pools as appropriate passing along the social provider token. In the case where both are present in your configuration, the social provider federation will go to User Pools, and the returned JWT token will be sent to Identity Pools thus federating the User Pool with that Identity Pool and providing AWS credentials to the caller automatically as well.

The existing behavior when only using an Identity Pool remains unchanged, and the only required arguments are the provider and token.

Auth.federatedSignIn(
  'provider',               //Facebook, Google, etc.
  'token',                  //OAuth token from provider
  'user',                   //Optional user attributes {username, phone}
  'expiresIn',              //Optional time to invoke refresh of provider OAuth token
  'IdentityID'              //Optional
);

UPDATED: When using User Pools, there are no arguments required and provider is optional. If a provider is not given the User Pool Hosted UI will be displayed. If a provider is given the page will redirect to the Hosted UI, but we’ll add a query string to signal an immediate redirect to the social provider’s login page (Facebook, G+, etc.). This allows you to build your own UI but still leverage the User Pool federation. In either case after the user signs in with that provider an account will be created in User Pools and a JWT token returned.

The user object contains information for you to use when calling Auth.currentSession() and returns a CognitoUserSession object. If you do not pass this object we will attempt to automatically populate the name, email, and phone_number attributes from the social provider based on known mechanisms (for example - Facebook requires a call to ‘/me’ to retrieve details after authenticating) but if we are unable to retrieve the attributes we’ll populate them as UNDEF.

The expiresIn value controls when Amplify will attempt to refresh the token from the social provider, and when the time comes do so automatically behind the scenes. This value was previously required and is now optional as we will default by default attempt to retrieve the attribute from the social token, and if it does not exist we will set it to 1 hour. If you provide a value then Amplify will honor your provided time.

The IdentityID value is strictly for Cognito Identity Pools and allows you to set an Identity ID to retrieve credentials for a specific Cognito Identity ID: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityCredentials.html#identityId-property

Implementation

Identity Pool federation will stay as-is today, with the only changes being automatic generation of expiresIn logic. For User Pools Amplify.configure() will require domain, redirectSignIn, redirectSignOut, and responseType from https://aws-amplify.github.io/docs/js/authentication#configuring-the-hosted-ui. The scope will be optional (for discussion - should this move into the options object?). Note that in the future the Amplify CLI will set all this up see https://github.com/aws-amplify/amplify-cli/issues/766. Under the covers, we will manage the OAuth redirects on behalf of the developer such as the code below, which must be manually called today:

const { 
    domain,  
    redirectSignIn, 
    redirectSignOut,
    responseType } = config.oauth;

const clientId = config.userPoolWebClientId;
// The url of the Cognito Hosted UI
const url = 'https://' + domain + '/login?redirect_uri=' + redirectSignIn + '&response_type=' + responseType + '&client_id=' + clientId;
// If you only want to log your users in with Google or Facebook, you can construct the url like:
const url_to_google = 'https://' + domain + '/oauth2/authorize?redirect_uri=' + redirectSignIn + '&response_type=' + responseType + '&client_id=' + clientId + '&identity_provider=Google';
const url_to_facebook = 'https://' + domain + '/oauth2/authorize?redirect_uri=' + redirectSignIn + '&response_type=' + responseType + '&client_id=' + clientId + '&identity_provider=Facebook';

// Launch hosted UI
window.location.assign(url);

// Launch Google/Facebook login page
window.location.assign(url_to_google);
window.location.assign(url_to_facebook);

We will provide a config option (or another mechanism) for customers to override what “opening a url” means in the different platforms (e.g. using Expo’s WebBrowser in React Native).

Potential future Option: Add Federation to signIn() and deprecate federatedSignIn() We are not doing this as part of this feature work but are including in the RFC to get early opinions for the future

One future option is to take all of the implementation and functionality as above, however we would move this into Auth.signIn() instead of Auth.federatedSignIn().

PROS: Less APIs to learn, potentially simpler code that is standardized for many situations. Auth codebase could also have a “cascading rule set” depending on config leading to less logic branches.

CONS: This will take a larger effort as it introduces more code complexity into the existing signIn() method. There is also the fundamental question of whether or not the action of “federation” is actually a “sign-in” action (more below in Option 3). We would also need to deprecate the federatedSignIn() method requiring customers to update their code in the future if they upgrade versions. Perhaps the biggest issue though is that there is “no free lunch” and that while the code may become simpler from a customer perspective, you must push the logic somewhere and naturally that would go into Amplify.configure() to know what actions to take. This ultimately means that finding the appropriate API setting will be less intuitive.

Potential future Option: Introduce a new API for Federation We are not doing this as part of this feature work but are including in the RFC to get early opinions for the future

All of the implementation and functionality as above, however we introduce a new API in Auth - Auth.XXX.

The reason for this discussion is should federation be an action tied to Login? The Wikipedia definition of federation (https://en.wikipedia.org/wiki/Federation_(information_technology)) has no terms around authentication but rather a “joining” or “association” of separate systems. In the Amplify case that can be either the joining of separate Identity Providers or it can be joining them to a single “logical identity”, ultimately all in order to provide authorization to resources (via OIDC tokens or AWS Credentials). This begs the question is there a more descriptive API such as simply Auth.federate() and, if one exists, is the name so much better that it makes performing these actions that much easier for customers?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:72
  • Comments:35 (20 by maintainers)

github_iconTop GitHub Comments

11reactions
baffleinccommented, Feb 16, 2019

Cannot +100 this enough 🙏

5reactions
kholacommented, Feb 16, 2019

Yes yes yes! This sounds awesome and will be really helpful. 😍😍😍

Read more comments on GitHub >

github_iconTop Results From Across the Web

Adding user pool sign-in through a third party - Amazon Cognito
Sign-in through a third party (federation) is available in Amazon Cognito user pools. This feature is independent of federation through Amazon Cognito identity ......
Read more >
How to Bypass Cognito-Hosted UI With Federated Sign In
Below is the simple process for skipping over Cognito's hosted UI while still using federated authentication.
Read more >
Common Amazon Cognito scenarios
Identity pools support anonymous guest users, as well as federation through third-party IdPs. Topics. Authenticate with a user pool; Access your server-side ...
Read more >
Single Sign-On (SSO) using AWS Cognito and Azure AD
The app receives the user's authentication token from the SSO service and grants ... AWS Cognito has two main components; the User pools,...
Read more >
Authentication - Hosted UI - Swift - AWS Amplify Docs
Amazon Cognito User Pools provides a customizable user experience via a web "Hosted UI". The Hosted UI provides an OAuth 2.0 flow that...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found