1

I am unable to get a developer authenticated identity working at all in Swift...

Ive based my code from a Swift conversion of this guide https://mobile.awsblog.com/post/Tx3E3NJURV1LNV1/Integrating-Amazon-Cognito-using-developer-authenticated-identities-An-end-to-en Found here - https://stackoverflow.com/a/28514719/535363

My inherited AWSAbstractCognitoIdentityProvider class

import AWSCore

class EmailIdentityProvider: AWSAbstractCognitoIdentityProvider {
    var _token: String!
    var _logins: [ NSObject : AnyObject ]!
    override var token: String {
        get {
            return _token
        }
    }

    override var logins: [ NSObject : AnyObject ]! {

        get {
            return _logins
        }
        set {
            _logins = newValue
        }
    }

    override func getIdentityId() -> AWSTask! {

        if self.identityId != nil {
            return AWSTask(result: self.identityId)
        }else{
            return AWSTask(result: nil).continueWithBlock({ (task) -> AnyObject! in
                if self.identityId == nil {
                    return self.refresh()
                }
                return AWSTask(result: self.identityId)
            })
        }
    }

    override func refresh() -> AWSTask! {

        let task = AWSTaskCompletionSource()

        let tmp = NSMutableDictionary()
        tmp.setObject("temp", forKey: "login.continualsuccess.com.motivation")
        self.logins = tmp as [NSObject : AnyObject]

        self.identityId = "us-east-1:xxxxxx-xxxx-xxxx-xxxx-90223fc9333f"
        self._token = "eyJraWQiOiJ....ehTOEVhA"

        return AWSTask(result: self.identityId)
    }
}

Called via

AWSLogger.defaultLogger().logLevel = AWSLogLevel.Verbose

let identityProvider = EmailIdentityProvider()

let cp = AWSCognitoCredentialsProvider(
    regionType: AWSRegionType.USEast1 ,
    identityProvider: identityProvider,
    unauthRoleArn: "Cognito_ContinualSuccessUnauth_Role",
    authRoleArn: "Cognito_ContinualSuccessAuth_Role"

);

let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: cp)
AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration

let syncClient = AWSCognito.defaultCognito()
let dataSet = syncClient.openOrCreateDataset("myDataSet")
dataSet.setString("123", forKey: "new")
dataSet.synchronize()

With the following backend code. Written in Golang

Which I used to generate the string values I put in as self.identityId and self._token I return in refresh()

var testCredentials = credentials.NewStaticCredentials("MY_KEY", "MY_SECRET", "")

    svc := cognitoidentity.New(&aws.Config{Credentials: testCredentials,Region: aws.String("us-east-1")})

    params := &cognitoidentity.GetOpenIdTokenForDeveloperIdentityInput{
        IdentityPoolId: aws.String( "us-east-1:xxxxxxx-xxxx-xxxx-xxxx-2fb2e08f7daf" ), // Required
        Logins: map[string]*string{ // Required
            "login.continualsuccess.com.motivation": aws.String(userid), // Required
            // More values...
        },
        IdentityId:    nil,
        TokenDuration: aws.Int64(82800),
    }
    resp, err := svc.GetOpenIdTokenForDeveloperIdentity(params)

The error im getting is

AWSCognitoSQLiteManager.m line:1455 | -[AWSCognitoSQLiteManager filePath] | Local database is: /Users/Jase/Library/Developer/CoreSimulator/Devices/32D1AE52-E4A4-421D-BBC7-B32F30A03772/data/Containers/Data/Application/61402FEB-F499-4829-A051-013EF45EAF0A/Documents/CognitoData.sqlite3
2015-09-27 19:25:28.322 SlideOutNavigation[42167:635443] AWSiOSSDKv2 [Debug] AWSCognitoSQLiteManager.m line:179 | __51-[AWSCognitoSQLiteManager initializeDatasetTables:]_block_invoke | sqlString = 'INSERT INTO CognitoMetadata(Dataset,ModifiedBy,IdentityId) VALUES (?,?,?)'
2015-09-27 19:25:28.324 SlideOutNavigation[42167:635443] AWSiOSSDKv2 [Debug] AWSCognitoSQLiteManager.m line:282 | __53-[AWSCognitoSQLiteManager loadDatasetMetadata:error:]_block_invoke | query = 'SELECT LastSyncCount, LastModified, ModifiedBy, CreationDate, DataStorage, RecordCount FROM CognitoMetadata WHERE IdentityId = ? and Dataset = ?'
2015-09-27 19:25:28.324 SlideOutNavigation[42167:635443] AWSiOSSDKv2 [Debug] AWSCognitoSQLiteManager.m line:386 | __73-[AWSCognitoSQLiteManager getRecordById_internal:datasetName:error:sync:]_block_invoke | query = 'SELECT LastModified, ModifiedBy, Data, Type, SyncCount, Dirty FROM CognitoData WHERE Key = ? AND IdentityId = ? AND Dataset = ?'
2015-09-27 19:25:33.060 SlideOutNavigation[42167:635690] AWSiOSSDKv2 [Verbose] AWSURLRequestSerialization.m line:483 | -[AWSQueryStringRequestSerializer serializeRequest:headers:parameters:] | Request body: [RoleArn=Cognito_ContinualSuccessAuth_Role&Version=2011-06-15&RoleSessionName=iOS-Provider&Action=AssumeRoleWithWebIdentity&WebIdentityToken=eyJraW....4fehTOEVhA]
2015-09-27 19:25:35.134 SlideOutNavigation[42167:635692] AWSiOSSDKv2 [Debug] AWSURLResponseSerialization.m line:257 | -[AWSXMLResponseSerializer responseObjectForResponse:originalRequest:currentRequest:data:error:] | Response header: [{
    Connection = close;
    "Content-Length" = 269;
    "Content-Type" = "text/xml";
    Date = "Sun, 27 Sep 2015 09:25:34 GMT";
    "x-amzn-RequestId" = "b45aec1d-64f9-11e5-8fbd-d148bd98dc03";
}]
2015-09-27 19:25:35.135 SlideOutNavigation[42167:635692] AWSiOSSDKv2 [Verbose] AWSURLResponseSerialization.m line:262 | -[AWSXMLResponseSerializer responseObjectForResponse:originalRequest:currentRequest:data:error:] | Response body: [<ErrorResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
  <Error>
    <Type>Sender</Type>
    <Code>ValidationError</Code>
    <Message>Request ARN is invalid</Message>
  </Error>
  <RequestId>b45aec1d-64f9-11e5-8fbd-d148bd98dc03</RequestId>
</ErrorResponse>
]
2015-09-27 19:25:35.139 SlideOutNavigation[42167:635692] AWSiOSSDKv2 [Error] AWSCredentialsProvider.m line:527 | __40-[AWSCognitoCredentialsProvider refresh]_block_invoke352 | Unable to refresh. Error is [Error Domain=com.amazonaws.AWSSTSErrorDomain Code=0 "(null)" UserInfo={Type=Sender, Message=Request ARN is invalid, Code=ValidationError, __text=(
    "\n    ",
    "\n    ",
    "\n    ",
    "\n  "
)}]
2015-09-27 19:25:35.140 SlideOutNavigation[42167:635692] AWSiOSSDKv2 [Error] AWSCognitoDataset.m line:315 | __30-[AWSCognitoDataset syncPull:]_block_invoke | Unable to list records: Error Domain=com.amazonaws.AWSSTSErrorDomain Code=0 "(null)" UserInfo={Type=Sender, Message=Request ARN is invalid, Code=ValidationError, __text=(
    "\n    ",
    "\n    ",
    "\n    ",
    "\n  "
)}
Community
  • 1
  • 1
Jase Whatson
  • 4,179
  • 5
  • 36
  • 45
  • hey what did you use for the token ? and did you ever get this to work lol.. – Lamour Jan 28 '16 at 11:08
  • Yes I did eventually get it to work.... I think I just hard coded the token value returned by my backend call from GetOpenIdTokenForDeveloperIdentityInput() in the EmailIdentityProvider swift class. I think that you need to call your backend to get a new token if the current expires...Im going to have to look at this all again, but after the nightmare of trying to get it as far as i did I just wanted to take a break from it... – Jase Whatson Jan 28 '16 at 11:20
  • Do I have to to call my backend, i use the cloud Formation Manager will it do it automatically ? – Lamour Jan 28 '16 at 11:28

1 Answers1

3

It looks like you've used your role name, not the role ARN (Amazon Resource Name) to initialize your credentials provider.

A role ARN will be of the form: arn:aws:iam::1234567890:role/ROLE_NAME.

You can either replace the role names with ARNs in your provider, or alternatively, leave the role values as nil in the credentials provider, which will tell Cognito to use the roles associated with your identity pool.

The later is the enhanced flow; you can learn more about it in our developer guide.

Bob Kinney
  • 8,870
  • 1
  • 27
  • 35
  • Thanks Bob!! I replaced the role name with its ARN in the form you described above. However I now get a UnknownOperationException : full debug error log - https://gist.github.com/anonymous/51b7fc80e2e1b895158d However it does work when I put nil as the unauthRoleArn and authRoleArn parameters :) – Jase Whatson Sep 28 '15 at 01:49
  • @nullptr The UnknownOperationException is due to the fact that the credentials provider doesn't have the identity pool id. – Bob Kinney Sep 28 '15 at 01:53
  • @nullptr Specifically, the Cognito sync client needs to be able to load the identity pool id from the credentials provider, which is accessed from the identity provider, so you'll want to add this to your custom provider. – Bob Kinney Sep 28 '15 at 01:56
  • This answer is still rocking in 2022... thank you for saving me after 2 days of research – holographix Apr 21 '22 at 14:44