How to integrate AWS Cognito for only Developer authenticated developers? - android

We have done integration of AWS for Unauthenticated access but when we trying for Authenticated access then we getting error of InvalidParameterException: Please provide a valid public provider.
we using following steps for AWS integration into application:
DeveloperAuthenticationProvider developerProvider = new DeveloperAuthenticationProvider(
AppConstants.AWS_ACCOUNT_ID, AppConstants.IdentityPoolId, Regions.EU_WEST_1
);
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
getActivity(),
developerProvider,
Regions.EU_WEST_1);
//set Logings for Authenticated Access
HashMap<String, String> loginsMap = new HashMap<String, String>();
loginsMap.put(developerProvider.getProviderName(), Token);
credentialsProvider.setLogins(loginsMap);
credentialsProvider.refresh();
We have done with DeveloperAuthenticationProvider class, which extends AWSAbstractCognitoDeveloperIdentityProvider; where we provide developer provider name(developerProvider.getProviderName()) and Token is as a OpenID token.
But I getting below errors:
Caused by: com.amazonaws.services.cognitoidentity.model.InvalidParameterException: Please provide a valid public provider
and sometimes I getting errors of:
Identity ID is forbidden.
I couldn't understand causes of these errors. I referred following URLs:
https://docs.aws.amazon.com/cognito/devguide/identity/developer-authenticated-identities/, https://mobile.awsblog.com/post/Tx3E3NJURV1LNV1/Integrating-Amazon-Cognito-using-developer-authenticated-identities-An-end-to-en.
Please suggest me how can I solve out these errors and give some updated references where I can understand causes of these errors.

It looks like you are setting the token in the logins map, instead of the token field of your developer provider as noted in the developer guide. You may also want to refer to our end-to-end example available on GitHub which includes example code for both iOS and Android.

Hurreyyy, I resolved issue of Developer Authentication for AWS Cognito Service. Its easy to understand but quite hard to implement.
Here is solution :
CognitoSyncClientManager.init(this, cognitoParams);
CognitoSyncClientManager.credentialsProvider.clearCredentials();
CognitoSyncClientManager.addLogins(AppConstants.DEVELOPER_PROVIDER, strToken); and you can get CognitoSyncClientManager from CognitoSyncDemo.
Thanks to all

Make sure that the value you're returning from developerProvider.getProviderName() is the same value that you have registered in the Amazon Cognito console as described in the steps under the Associate Developer Provider section of the Developer Authenticated Identities topic in the Amazon Cognito Developer Guide.

Related

Android AWS Cognito app - User sign-in WITHOUT embedding sensitive info (like secret key)

TL;DR W/o distributed private keys, how can I perform the auth flow for an Android app where the Identity Provider is Cognito itself, and the user only signs-up/in with email/password?
I'm developing an Android app in which I want the user to sign-in with "email and password" (NOT Google, Facebook, etc.) and then be able to download/upload objects from S3. I've worked with AWS for months, but all the while the sign-in functionality of my app was built on the sample app (the source of which has apparently changed substantially), which used the "AWSConfiguration" class to store:
AWS_MOBILEHUB_USER_AGENT
AMAZON_COGNITO_REGION
AMAZON_COGNITO_IDENTITY_POOL_ID
AMAZON_COGNITO_USER_POOL_ID
AMAZON_COGNITO_USER_POOL_CLIENT_ID
AMAZON_COGNITO_USER_POOL_CLIENT_SECRET
I need to implement sign-in and authorization to use AWS modules (like S3) WITHOUT embedding sensitive info.
It seems clear to me that this is going to be a "roll my own" situation so in going back to the good ol' start of the documentation on cognito, I'm already to confused as to why my "Email and password" sign-in model fits neither the bill of a "Public Provider" nor a "Developer Authenticated Identity":
From Mobile Hub:
In Cognito > MyUserPool > App Integration > App client settings it still appears as an identity provider of some kind (also it worked without me having to "enable" it):
The big question:
Is it possible to implement a sign-in flow where the user enters an email and a password, gets signed-in with Cognito, and the app has the necessary info to instantiate something like S3Object = new S3Client(credentialsProvider).getObject(...) without requiring a (separate/proxy) server to process private keys?
Also, are callback/sign-out URLs necessary for an app (and if so, why)?
Regarding your question on the obfuscation of service constants in the SDK, there is no standard method to do this - which offers guaranteed security. There are several third party and server based solutions. However Cognito does not recommend any specific technique for obfuscation.
To implement Sign-In and get credentials to access AWS resources, you can add Cognito as a Authentication Provider for your identity-pool. With this you will be able to use ID token vended by Cognito to access AWS resources. This code snippet shows how to use tokens issued by Cognito UserPools to access AWS resources in Android.
// Get id token from CognitoUserSession.
String idToken = cognitoUserSession.getIdToken().getJWTToken();
// Create a credentials provider, or use the existing provider.
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(context, IDENTITY_POOL_ID, REGION);
// Set up as a credentials provider.
Map<String, String> logins = new HashMap<String, String>();
logins.put("cognito-idp.us-east-1.amazonaws.com/us-east-1_123456789", cognitoUserSession.getIdToken().getJWTToken());
credentialsProvider.setLogins(logins);
See this tutorial for further detail - http://docs.aws.amazon.com/cognito/latest/developerguide/tutorial-integrating-user-pools-android.html#tutorial-integrating-user-pools-getting-aws-credentials-android.

Unauthenticated access is not supported for this identity pool

Error is:
com.amazonaws.services.cognitoidentity.model.NotAuthorizedException: Unauthenticated access is not supported for this identity pool. (Service: AmazonCognitoIdentity; Status Code: 400; Error Code: NotAuthorizedException;
Please Help me out here.
The process of signin was successful and when i enter Amazon lex chat bot window, I get the above error Unauthenticated access is not supported for this identity pool. This actually makes sense because i have unchecked unauthenticated access to my bot so i know that without authentication no user will be allowed to interact with the Lex ChatBot. But now my signin is successful and still i have this error.
My question is do we need to maintain the user session who has signed in?? If yes how do i do that.
Or
How do i link Login to Cognito Authenticated Identity.
We get this error when the Identity Pool has unauthenticated access disabled and no id token was found in the login map for the application. For example, in Android applications, after initializing CognitoCachingCredentialsProvider you also need to call the setLogins() method and provide a login map.
//Relevant imports
import com.amazonaws.auth.CognitoCachingCredentialsProvider;
import com.amazonaws.regions.Regions;
//Initialize credentials provider
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(),
"IDENTITY_POOL_ID",
Regions.US_EAST_1
);
//Create a login map
Map<String, String> logins = new HashMap<String, String>();
logins.put("www.amazon.com", "login with Amazon token");
//Set login map
credentialsProvider.setLogins(logins);
credentialsProvider.getCredentials();
//Create clients for AWS services with credentialsProvider as a parameter in the constructor
In the above example, I assumed that 'Login with Amazon' was used. For different providers, change the key "www.amazon.com" with the appropriate token. To know the key, just decode the id token at https://jwt.io and look for iss claim. The value without https:// will be the key for the login map.
As to where to put this code, check if it is using a CognitoCachingCredentialsProvider object anywhere and then add a login map to it. To forcibily refresh credentials, call the refresh() method
for aws amplify enable multiauth
finally,
Do you want to edit your add-to-group function now? (Y/n) n
In your command line run
amplify update auth
then follow the prompt as it is done in the image below
Happy coding...

Android, Cognito: can sign in, but can't make authenticated AWS calls

In an Android app, I can successfully authenticate with Cognito, which returns a CognitoIdToken and a CognitoAccessToken.
But I can't figure out how to use that to make actual authenticated call to, say Lambda or S3. It seems that there's a chasm between CognitoIdentityProvider (which I seem to be able to work with) and CognitoCredentialsProvider (which I do not).
Thanks for ideas, or even a pointer to a sample that uses Cognito and authenticated calls / roles.
[edit] Bonus question: Can someone explain why there is an AWSCognito* and an AmazonCognito*, and why they seem almost completely unrelated?
Take a look at your Federated identities pool in the aws console. Look in the identity browser for the identityId that you are getting authenticated with (from your logs).
Here is the key thing: if the identity id does not show logins, then you never have gotten authenticated. *When I say logins, there is a login count on each identity, and it shows the identityProviderName that the authentication occured with if you click on the identityID.
This is a simple test, if you have logins you are authenticated. if you don't, you aren't. Now why none of the documentation at AWS says that... well.. who knows.
if you ARE authenticated, then the SDK stores the tokens, and you don't need to worry about it you can begin working with aws with your service configuration.
(The response is based upon the IOS sdk, but I believe for these matters, they are the same - The diagrams in here may help you, but these are my notes for IOS SDK, and I admit I have not tried this in Android).
I finally determined that I was missing calls to set the tokens into the credentials provider:
final CognitoCachingCredentialsProvider credentialsProvider = getCredentialsProvider(applicationContext);
Map<String, String> logins = new HashMap<String, String>();
logins.put(Constants.COGNITO_USER_POOL_LOGIN_STRING, cognitoUserSession.getIdToken().getJWTToken());
credentialsProvider.setLogins(logins);
where Constants.COGNITO_USER_POOL_LOGIN_STRING is like "cognito-idp.us-west-2.amazonaws.com/" + MY_COGNITO_USER_POOL_ID. After doing that, a TransferUtility object was able to download with authentication. The TransferUtility was previously obtained like this (edited):
CognitoCredentialsProvider cp = . . .
AmazonS3Client s3Client = new AmazonS3Client(cp);
TransferUtility s3transferUtility = new TransferUtility(s3Client);

How can i authenticate to my Identity/User Pool with Cognito Identity?

I have been trying to solve this for a few days now but i can't figure out what the problem is.
I have a user pool and an identity pool on AWS Cognito. I have run the sample code and used it to log in and register users with Facebook and Google+ successfully. After login i am able to authenticate using the token to use SNS or the Sync services.
I have registered a user and got a token (after logging in) with Cognito Identity. However the next step is to use the token to authenticate into the identity pool. This is where i keep getting the error
I have followed the instructions from Integrating User Pools with Amazon Cognito Identity and I get a token which I then try to pass it along with the pool id to the credentials provider.
credentialsProvider.clear();
credentialsProvider.withLogins(loginMap).refresh();
My code fails on refresh(). At this point credentialsProvider is a AWSBasicCognitoIdentityProvider and refresh() fails in the super.refresh() which calls getIdentityId() in the abstract parent class AWSAbstractCognitoIdentityProvider
#Override
public String getIdentityId() {
if (identityId == null) {
GetIdRequest getIdRequest = new GetIdRequest()
.withAccountId(getAccountId())
.withIdentityPoolId(getIdentityPoolId())
.withLogins(loginsMap);
appendUserAgent(getIdRequest, getUserAgent());
GetIdResult getIdResult = cib.getId(getIdRequest);
No matter what values i put in the loginsMap, i get the error
Invalid login token. Issuer doesn't match providerName
at cid.getid(getIdRequest).
Most of the code is available to download free if you create an app in the Mobile Hub and generate the code. You can then configure authentication providers - FB, Google , etc.
What am I doing wrong ?
Thanks.
Edit : Here are examples of what i have tried
The token is always the object in the map. Below are the different keys
"cognito-identity.amazonaws.com"
the User Pool id - us-east-1_xxxxxxxxx
the User Pool ARN - cognito-idp:us-east-1:xxxxxxxxxxxx:userpool/us-east-1_xxxxxxxxx
OK i found the answer - I was putting in the wrong key value in the loginMap.
it should be
cognito-idp.<region>.amazonaws.com/<YOUR_USER_POOL_ID>
as it says in the documentation linked in the question
I don't know how I didn't see that.

Android and AWS Cognito Developer Authenticated Identities

I'm building an Android app that will utilize Cognito for user authentication. I'm using Developer Authenticated Identities and retrieving an Identity ID and token from my backend service successfully however I'm not able to figure how to us the Identity ID and token for S3. I have done this successfully in JavaScript like so...
AWS.config.region = 'us-east-1';
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
IdentityId: identityid,
Logins: {
'cognito-identity.amazonaws.com': token
}
});
I've tried with...
Map logins = new HashMap();;
logins.put("cognito-identity.amazonaws.com", token);
credentials = new CognitoCachingCredentialsProvider (
context,
"us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
Regions.US_EAST_1
);
credentials.setLogins(logins);
s3 = new AmazonS3Client(credentials);
List bucket = s3.listBuckets();
but this throws an exception...
Invalid login token. Can't pass in a Cognito token. I've also tried implement my own identity provider class as detailed here...
https://docs.aws.amazon.com/cognito/latest/developerguide/developer-authenticated-identities.html
but this is also unsuccessful. Can someone point my in the right direction?
Thanks in advance.
I did this with Node.js, but I assume Android SDK have a similar API. You get and IdentityId after creating an identity (either with Oauth provider, or without), then you request IAM temporary credentials for that identityId. You will have an accessKey, secretKey and a token, use them to configure the AWS.config.
After that you can use any service from AWS SDK, but you need to make suer that your pool of identities have the right roles/policies attached to it.
NB: give the least and the only needed access, or you will expose your services for malicious use!
The token have expiration date, which you can set, I didn't checked if AWS Cognito refresh it automatically or not.

Categories

Resources