Amplify-js: SSO implementation

Created on 13 Nov 2018  路  10Comments  路  Source: aws-amplify/amplify-js

* Which Category is your question related to? *
Authentication
* What AWS Services are you utilizing? *
Cognito User pools
* Provide additional details e.g. code snippets *
I want to implement SSO using this package. We have several websites and we want each of those websites to redirect to our Universal login website which is an Angular website uses aws-amplify for authentication against Cognito user pool, once login is successful we want to pass tokens to the requested website. Also requested website may not implement aws-amplify.
What is the correct way to implement this? I think we can't pass all the token using URL Query parameters may not be possible as the length of URL will exceed its limits right?

Auth pending-close-response-required

Most helpful comment

@undefobj we want to implement a central login page where the user should log in once and this page will be used to log on to many apps under different domains. Once the user is successfully logged in then they should be redirected to the original app with id, access and refresh token information as id and access token will be get expired in 1 hour, the app will need to keep calling the central login page which we want to avoid by providing a way to refresh id and access tokens using refresh tokens, this way the app doesn't have to come to sign page until refresh token is expired. In order to achieve this, we need an ability to refresh the id and access tokens using refresh tokens outside of the central login page.

I hope this is clear now?

All 10 comments

I have spent way too much time on this.

There are a few things Cognito is missing: support for the prompt=none parameter for their authorize endpoint and iframe-support for embedding their endpoints. This is how e.g. Auth0 achieves SSO with Auth0's checkSession() method. These have been frequently requested for a long time, but unfortunately they do not want to implement them it seems.

The only way for a a working (silent) SSO implementation is the one you are trying to do. Create your own auth page, get the tokens, and redirect back to a site of yours with the tokens as fragments/hashes in the URL (this is how OAuth Implicit Grant works aswell). Just make sure that no one can abuse this/redirect to a foreign site.

For a fully silent SSO (check whether a user is signed in the first time a user visits one of your domains), you can use something like Zendesk Cross-Storage and let it embed an invisible iframe to your auth site to check whether a user is already logged in/get the tokens without redirecting and basically emulate what other Auth providers like Auth0 are doing for silent SSO.

I wish they would just support this officially though.

Thanks @D2KX for your reply, this is really good information to get started.

@koladilip were you able to pull it off like that? I have a similar situation (80+ sites that need to share the same user pool) and I found this: https://meta.stackexchange.com/questions/64260/how-does-sos-new-auto-login-feature-work/64274#64274
But I'm not sure if the silent iframe checkout will work on Cognito or if there are other things to consider... any insight is helpful!

@camilodelvasto We are not using iframe approach instead we just load the login page in the browser and that will redirect back original page once authenticated.

I have created a pull request for passing refresh token to another site and that site should be able to refresh directly: https://github.com/aws-amplify/amplify-js/pull/2439

I found an easy way to get the ID and access tokens using Cognito refresh token using node-fetch and calling Cognito REST API directly and here is the code for it.

fetch("https://cognito-idp.us-east-1.amazonaws.com/", {
            headers: {
                "X-Amz-Target": "AWSCognitoIdentityProviderService.InitiateAuth",
                "Content-Type": "application/x-amz-json-1.1",
            },
            mode: 'cors',
            cache: 'no-cache',
            method: 'POST',
            body: JSON.stringify({
                ClientId: "<input-user-pool-client-id>",
                AuthFlow: 'REFRESH_TOKEN_AUTH',
                AuthParameters: {
                    REFRESH_TOKEN: "<input-refresh-toke>"
                }
            }),
        }).then((res) => {
            return res.json(); // this will give jwt id and access tokens
        });

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@undefobj we want to implement a central login page where the user should log in once and this page will be used to log on to many apps under different domains. Once the user is successfully logged in then they should be redirected to the original app with id, access and refresh token information as id and access token will be get expired in 1 hour, the app will need to keep calling the central login page which we want to avoid by providing a way to refresh id and access tokens using refresh tokens, this way the app doesn't have to come to sign page until refresh token is expired. In order to achieve this, we need an ability to refresh the id and access tokens using refresh tokens outside of the central login page.

I hope this is clear now?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shinnapatthesix picture shinnapatthesix  路  3Comments

romainquellec picture romainquellec  路  3Comments

DougWoodCDS picture DougWoodCDS  路  3Comments

benevolentprof picture benevolentprof  路  3Comments

ldgarcia picture ldgarcia  路  3Comments