So the steps are:
- Set up Cognito to authenticate UNanthenticated users
AND your authentic user Developer Name <- important part
-
Set up DynamoDB (or whatever) to store your Username-Password information
-
Go to IAM and make an
AUTHENTIC
role and anUNAUTHENTIC
role. -
You give the
UNAUTHENTIC
role, assign:AmazonCognitoDeveloperAuthenticatedIdentities AmazonDynamoDBFullAccess (if you want a Login & Register system) AmazonDynamoDBReadOnlyAccess (if you only want login)
- Also go in and do:
Edit Trust Relationship
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "<YOUR_COG_ARN>"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "unauthenticated"
}
}
}]
}
-
Now make your
AUTHENTIC
role, and assign:AmazonCognitoPowerUser AmazonDynamoDBFullAccess AmazonSNSFullAccess - for example, and whatever else you'd like
-
Also go in and do:
Edit Trust Relationship
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "<YOUR_COG_ARN>"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}]
}
PLEASE NOTICE THE ONE CHANGE MADE - "authenticated" and "unauthenticated"
-
Now this should be mobile hubs responsibility, but since they came out with that, everyone thinks they're relieved of responsibility! Not the case! You need to know what
sts:AssumeRoleWithWebIdentity
-
Now that you have everything set up, start your xcode project form Mobile Hub
-
Fill in all the data (if its not there, which it should be because Mobile-Hub is nice to us) for your
AUTHENTICATED ARN
and yourUNATHENTICATED ARN
-
Set up your login page
-
When the user goes to login, (encrypt their password) and send that and the username to DynamoDB.
12B. I really like using Lambda PARTICULARLY for mobile because you can really do a lot more AND you are less prone to errors AND you have more control, etc.
So with that said, go back to to step 4 & 6 IF you want to use Lambda and add and Inline Policy
to the Roles
. IAM -> Roles -> Your Role -> Create Role Policy
And pop in:
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}]
}
Now that you have the base set up, go back to Xcode.
- IF you are using Lambda, send in your username and password, let lambda pull the row from DynamoDB AND do the check on
does the user exist, if so do the passwords match
Should look something like this in Lambda:
const
AWS = require('aws-sdk'),
ddb = new AWS.DynamoDB()
exports.handler = function(event, context) {
var params = {
TableName : '<users>',
KeyConditionExpression : 'userType = :v_type AND username = :v_user',
FilterExpression : 'password = :v_pass',
ExpressionAttributeValues : {
':v_type' : { S : '<superdooper>' },
':v_user' : { S : event.username },
':v_pass' : { S : event.password }
}
//ProjectionExpression: 'email, joinDate, phone' (OPTIONAL)
}
ddb.query (params, function(err, data) {
if (err) {
context.fail (JSON.stringify(err, null, 2));
} else {
if (data.Count !== 0)
context.succeed (data.Items);
else
context.succeed ('Wrong Info');
}
});
};
Once you get your data.Items back in Xcode, call this Lambda function, send in your variables, and when they say "good", call:
credentialsProvider.setLogins({developerAuthenticationProvider.getProviderName(), developerUserIdentifier});
Followed by credentialsProvider.refresh();
That part above should be in your Xcode project from MobileHub.
Now, this is were things get weird. There are a ton o` ways to do this. TVM, Cognito Assume Auth, server side, etc.
I always reassume authentication from Unauthenticated
to Authenticated
, but you have to do a lot of back end stuff if you want to get real analytics from both web side and mobile side if you're making this for both. But once you have your authenticated user, you now have a well authenticated user, ready to access whatever you listed in Step 6 as authenticated!
Hope this helps.
Update --- This is a dirty, unsafe, but fast way to do this. NOT FOR PRODUCTION.
In cognito, don't even make an Authenticated user role
. Give your Unauthenticated user role
all the permissions to do everything (DynamoDBFullAccess
, S3FullAccess
, EC2FullAccess
, etc)
Then handle your authentication in the phone - Check the username and password against DynamoDB and then if it returns the information, set a variable to TRUE
. This is not safe because the user now has access to all your stuff but it would look like this:
BOOL loggedIn = FALSE;
if (loggedIn) {
[self loadView];
} else {
[self loadLoginView];
}
- (void) loadLoginView {
DynamoDBCall (username, password) withCompletion () {
if (allGood) {
_loggedIn = TRUE;
}
}
}