I have problems getting the authorization of my API on AWS for a Cognito User Pool via HTTP headers (without AWS API Gateway SDK) to work.
My setup:
On AWS:
- A REST API implemented on AWS Lambda (deployed via Serverless framework),
- exposed via API Gateway using type LAMBDA_PROXY (no manual mapping)
- Authorization on API Gateway via the provided "Cognito User Pool authorizer" (no "AWS_IAM" option, no custom coded authorizer)
- Testing the API via Postman
On the iOS client
- Registration/Sign-In via AWS Cognito (SDK and UI copied from the AWS Mobile Hub generated demo Xcode project)
- Accessing the REST API via RestKit, not using the AWSAPIGateway SDK
What is working:
The API methods get properly deployed via serverless.
I can call the public (not set to use the user pool) via Postman.
For the private API methods, I can see the Cognito user pool authorizer set up in the API Gateway management console, including "Identity token source" set to method.request.header.Authorization
(the default) as described here
On iOS, I can properly register and log in as user. I can dump the AWS Credentials details to the console, showing AccessKey
, SecretKey
and SessionKey
.
On iOS, I can query the public API via RestKit.
When I try to call a private API method via Postman, I get back an HTTP error 401 with the body {"message": "Unauthorized"}
. (Which is expected, without setting any authorization.)
What fails:
To test the authorization, in Postman, I have tried
- copy/pasting the AWSCredentials'
SessionKey
I got from the iOS client as HTTPAuthorization
header - as defined here (last paragraph - "API Gateway’s Authorizer for Cognito User Pools") - and as
X-Amz-Security-Token
header
The result was always the same 401 error.
What do I need to set as HTTP headers, in order to authorize the calls to the private API? "Authorization" should work - maybe I am missing some role permissions?
How can I better debug the permissions / authorization flow?
SessionKey
; is that in reference to one ofID token
orAccess Token
? in other terms it should be aJSON Web Key Token
as far as I am aware. as per docs.aws.amazon.com/cognito/latest/developerguide/… – Peter PajchlgetSession(username, password: password, validationData: nil, scopes: nil)
which should return asession
object of typeAWSCognitoIdentityUserSession
; token is accessible assession.accessToken?.tokenString
– Peter Pajchl[[AWSIdentityManager defaultIdentityManager] loginWithSignInProvider:[AWSCognitoUserPoolsSignInProvider sharedInstance] completionHandler:...]
I thought I'm saving some time by reusing the code and UI from the AWS demo, but I'm beginning to regret this decision... – thomersAWSCognitoIdentityUserPool *pool = [AWSCognitoIdentityUserPool CognitoIdentityUserPoolForKey:AWSCognitoUserPoolsSignInProviderKey]; AWSCognitoIdentityUser *user = [pool currentUser]; AWSTask<AWSCognitoIdentityUserSession *> *task = [user getSession];
. Then, I can usetask.result.idToken.tokenString as
Authorization` HTTP header, and it works. – thomers