How to set AWS Cognito Tokens in localstorage - javascript

I am implementing SSO Authentication with AWS Cognito, Now I am able to successfully login a user and retrieve id_token, access_token, refresh_tokens..., and redirect the user to home page, So my happy flow is working fine,
Issue I am facing is when when ever a user is redirected to login page I check if any available session for the user with help of getCurrentUser(). Now when I login user with simple username and password I use
var cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
cognitoUser.authenticateUser(...)
Here I know after successful authentication token key are stored in my local-storage by aws-sdk. and these same keys are used by getCurrentUser method to fetch current user session.
Same I am not able to do in my Oauth apporach. I get the code in the query parameter and make a post call to fetch tokens. Now how to set the same token in my local storage to implement retrieveSession functionality.

The cognito sdk is specific to aws and is not a general purpose oauth sdk. Also note that this sdk (https://github.com/amazon-archives/amazon-cognito-identity-js) is now deprecated in favour of aws amplify js (https://github.com/aws-amplify/amplify-js).
If you want to use OAuth and openId connect approach, I would recommend to use oidc-client-js (https://github.com/IdentityModel/oidc-client-js).

Related

Finishing AWS authentication flow

TLDR
I am looking for somewhere to send cognito JWT's from the backend to verify the user's status.
I currently have a react app, with a serverless apollo api, and dynamodb database, all running locally.
The react client uses aws-amplify to register, sign-in etc with
aws-cognito - returning access, id and refresh tokens.
Users can also sign in with facebook and google,
amplify.Auth.federatedSignIn which returns the cognito identity
credentials.
The tokens are then passed to the backend, where they are verified.
So far I cannot find where to send the tokens from the backend, to verify that the user is signed in to cognito.
I have scoured the docs but TBH that has left me more confused.
As far as I can understand, in production API Gateway, or AppSync can intecept the tokens between the front and backend, but since I have verified tokens at the backend currently is there an endpoint or SDK method I can hit with tokens/ access keys etc to check the users status?
Feel free to tell me if I'm going about this the wrong way.
If you need to verify that a token is valid and unexpired, with the JavaScript SDK use
const cognitoServiceProvider = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'});
await cognitoServiceProvider.getUser({
AccessToken: accessToken
}).promise();
This will throw an error if the token is not valid.
If you are using a different SDK, find the equivalent call.

Silent SAML Authentication using Auth0 as Identity Provider

What I'm trying to do is a Silent Authentication with Auth0 as Identity Provider using SAML 2.0 protocol. I don't want to use the Auth0 SDK because the purpose of the Server Provider is to be able to change between Identity Providers. I have read this post and this other.
I updated my login url from
https://{your_domain}.auth0.com/samlp/{client_id}
to
https://{your_domain}.auth0.com/samlp/{client_id}={connection your_db_connection_name}
As mentioned in the first link, but this only allow me to avoid redirections if the user has already an existing session. The second link refers to a parameter in the url:
prompt = none
But this is for OpenId Connect protocol, so I doesn't help me.
The current flow is the following:
User send credentials to my Server Provider (this is useless because
Auth0 requires the credentials in his widget)
The Server Provider requests for SAML authentication to Auth0
Auth0 redirects the user to his login Widget (the user enters the
credentials again)
The user get access
What I want to achieve is:
User send credentials to my Server Provider
The Server Provider Integrates the credentials (here is where I do
not know how) in the SAML 2.0 request
Auth0 receive and authenticate the credentials (without any kind of
redirection)
The user get access
What I'm using:
As Server Provider, Node JS with Express and saml2-js library
As Identity Provider, a Regular Web Application with the SAML2 Web App add-on on Auth0
I am new using SAML and Auth0 and I do not know much yet. Any guide or advice is welcome. Thank you.
(If I have flaws in my English, do not hesitate to comment, thanks)
I have researched about this and discovered that it is not possible to achieve it (not now, perhaps in the future).
The use of HTTP-Post Binding allows to avoid redirection only if a user session already exists. If not, the user will be redirected to the IdP login page (in this case, the login page of Auth0)
There is a profile in the SAML protocol and it is called Enhanced Client or Proxy (ECP), but it is rarely used and recommended for applications that can't use the browser.
Also, only some IdPs support it, like Keycloak and Shibboleth.

Get user Access Token from Twitter in Angular 2+ app

Hi I want to get a twitter user access token/refresh token so that My application can post/read tweets on behalf of the user..
I have a button in my app.. on clicking of the button, I need to show something like below image -
user should be able to provide his/her credential and if it is already logged in to twitter then he/she should only see authorize app button..
I created a new app in my developer twitter account.. but little clueless on how to get user's access token to post/read behalf of him...
Twitter uses OAuth1.0a unlike Facebook which uses OAuth2.0. The difference between OAuth1.0a and OAuth2.0 is that OAuth1.0a is more secure and you should use a server-based authentication flow because it involves api keys and secrets which we shouldn't be sharing with angular app.
On server side (NodeJS/Django, etc) you should use a client library for OAuth1.0 which will help you in complicated process of signing requests befores sending it to twitter.
Here is a useful link (which I also used) for you to implement the server flow:
https://github.com/requests/requests-oauthlib/blob/master/docs/oauth1_workflow.rst
Basically, the OAuth flow for twitter is as follows:
Send a POST request to oauth / request_token
You will get the authroization url from Step 1 like this https://api.twitter.com/oauth/authorize?oauth_token=XXX which you will redirect the user to so that they can authorize your app
Twitter redirects the user to your redirect url (which you sent with the request in previous step) with access_token and verifier.
You need to exchange the access_token and verifier for the actual usable user access token by sending a POST to oauth/access_token.
You can find more details for 3-legged OAuth flow here: https://developer.twitter.com/en/docs/basics/authentication/overview/3-legged-oauth

How do I use SAML to connect AWS Cognito to a remote Shibboleth install?

Disclaimer: I am not well-versed in how Shibboleth or other authentication systems or AWS Cognito works, so for anyone that can help, please explain things in simple terms.
My company recently got a cloud version of our product running on AWS, and we now want to use AWS Cognito and SAML to connect to a remote Shibboleth system to authenticate users logging into our cloud system. The Shibboleth system is located remotely at a client's institution.
Thus far, I've done the following (and I don't know if any of this is correct):
In AWS, I created an IAM Identity Provider of the type SAML. I received a SAML.xml file from the client's IT department, which I connected to the IAM Identity Provider. This seems okay.
When I set up the IAM Identity Provider, AWS autocreated Cognito Auth and Unauth roles, for which I kept the default policies.
I set up a new Federated Identity for the client institution. I also linked the created IAM Identity Provider to this Federated Identity.
Upon creating the Federated Identity, I was taken to a Sample Code page in AWS, where I needed to pick the SDK to use for making a connection, etc. I also got an Identity Pool ID from AWS. I opted to use the JavaScript SDK, so I downloaded the JS SDK as well as another recommended library on GitHub called amazon-cognito-js-master.
I included the necessary JS scripts in a new HTML file and then put the JS code below in the file (with a valid Identity Pool ID).
When I ran the script, I seemed to get back a valid syncClient object from the console.log statement, but from there, I have no clue what to do.
Basically, what do I have to do at this point to make a request from our JS script to the remote Shibboleth system to authenticate a user?
Do I need to have the user's credentials (i.e., username and password) already available before I make an AWS.CognitoSyncManager request, or is there some level of initialization required before that? Is there other information/files I need from the client's institution / IT department to get this set up?
I know so little about this, I'm not even sure which questions to ask. Any help/guidance would be greatly appreciated.
Please note that I have already looked extensively at the AWS docs, but I couldn't make any sense out of what they were saying (I'm not an authentication expert). Thank you.
var IdentityPoolId = 'us-east-2:45679821-9064-45f8-12ac-456132abc789'; // Not a real ID.
// Initialize the Amazon Cognito credentials provider
AWS.config.region = 'us-east-2'; // Region
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: IdentityPoolId,
});
// Initialize the Cognito Sync client
AWS.config.credentials.get(function(){
var syncClient = new AWS.CognitoSyncManager();
console.log(syncClient);
syncClient.openOrCreateDataset('myDataset', function(err, dataset) {
dataset.put('myKey', 'myValue', function(err, record){
dataset.synchronize({
onSuccess: function(data, newRecords) {
// Your handler code here
}
});
});
});
});
Basically, what do I have to do at this point to make a request from our JS script to the remote Shibboleth system to authenticate a user?
Well, you can not. When using Federated Identities, you need to write your own code to display the login UI or redirect to the login page of third-party IdPs like Shibboleth or use their SDK. Ultimately, you need to write your own code, without any AWS SDK to get OpenID tokens or as in your case, SAML assertions. When you do get a token or SAML assertion, use this in the Login map while initializing CognitoIdentityCredentials. See the example here. There is a Logins field where you need to pass the token or assertion received from your IdP. Now, as long as the SAML assertion in the map is valid, you can get temporary AWS credentials & your AWS calls will succeed. This one line in the Login map is the only interaction between Cognito & your Idp like Shibboleth when using Federated Identities. You can not directly make a call from Cognito Federated Identities to Shibboleth with username & password to get a valid token or response.
But what if I want to build an app or a service which needs authentication using Shibboleth. Ideally, if the user is not signed in, I should be shown a UI which should redirect me to Shibboleth where I can enter my username & password. Afterwords, I should be redirected to my app/service with valid credentials.
This can be done too but using Cognito Userpool and not Federated Identities. Add your SAML provider to a Userpool (see this). After this, add the Userpool to your Identity Pool (Federated Identities). Now use the built-in UI of Userpool to login and get the Id token (and not SAML assertion, User --> Userpool built-in UI--> Shibboleth --> Username+Password to login --> Shibboleth sends SAML assertion to Cognito userpool--> Userpool issues a token). Use this Id token in the login map of your CognitoIdentityCredentials.

Facebook Javascript SDK Autologin & Tokens

I am using the Facebook login as an authentication for my PhoneGap application - once a user logs in, their data is retrieved from my database to display information. I am not using the SDK for any other purpose.
I have the Facebook auto login working fine - it retrieves an authResponse and my Facebook information. Since the access token changes with each login, what can I use to store locally and in my database to authenticate the user on my server for future logins?
Here is a flow that I think could work...
User sees logs in screen and enters Facebook credentials
Facebook securely validates and returns user information & access token
The app uses localStorage to store user email and access token
For future autologin, the localStorage values are used as email/password
I feel like this cannot be the correct answer, however.
I figured out a solution - I was confused about storing passwords on my database to fetch user information. Rather, these are the correct steps:
Use Facebook SDK to handle the login and retrieve the authResponse
Update the user table in my database with the temporary access token and retrieve user's information
For every POST or GET the user wishes to perform, I will match the FB.getLoginStatus() results from the database's access token (the check will be done server side)
If the tokens match, perform requests. Otherwise, force the user to login again.

Categories

Resources