Cognito /oauth2/token endpoint returns invalid_grant error

0

I want to get access token (and set to cookie) from authorization code with Lambda function after sign-in by Hosted UI, but /oauth2/token endpoint returns invalid_grant error.

My Amazon Cognito configuration is following:

  • a Client without secret
  • use Hosted UI to sign-in
  • redirect URI is hosted on a function URL associated to a Lambda function
  • the Lambda function sends a POST request to /oauth2/token however invalid_grant error is returned
    • custom runtime image built with code written in Rust (using cargo-lambda)
    • without Authorization header due to no client secret
    • Content-Type is application/x-www-form-urlencoded
    • body includes grant_type: authorization_code, code: code in query parameters, scope: openid, client_id: my Cognito user pool client id, redirect_uri: the same as specified in the sign-in url

Reproduce steps:

  1. Open the Hosted UI of my Cognito User Pool client
  2. Sign-in a user
  3. Redirected to the authentication page handling my Lambda function, that sends a POST /oauth2/token with code in the query parameters, but returned invalid_grant error

The Lambda function's log with debug log:

START RequestId: 81fd9c22-9dfc-4363-ba5c-6f569baca42c Version: $LATEST
oauth2/token req params: [
(
"grant_type",
"authorization_code",
),
(
"code",
"dd95669d-7ba4-4693-91b7-2e955dd505fc",
),
(
"scope",
"openid",
),
(
"client_id",
"14p0d6vb9am0oi72gj5rpmn5f4",
),
(
"redirect_uri",
"https://btnhtnkhposuph346t5hlchuua0cmojc.lambda-url.ap-northeast-1.on.aws/home/authenticate",
),
]
oauth2/token req: Request {
method: POST,
url: Url {
scheme: "https",
cannot_be_a_base: false,
username: "",
password: None,
host: Some(
Domain(
"maverick-stg.auth.ap-northeast-1.amazoncognito.com",
),
),
port: None,
path: "/oauth2/token",
query: None,
fragment: None,
},
headers: {
"content-type": "application/x-www-form-urlencoded",
},
}
oauth2/token resp headers: {
"date": "Sun, 19 Nov 2023 10:33:13 GMT",
"content-type": "application/json;charset=UTF-8",
"content-security-policy-report-only": "script-src https://d3vhah7crmmd43.cloudfront.net https://maverick-stg.auth.ap-northeast-1.amazoncognito.com; style-src https://d3vhah7crmmd43.cloudfront.net https://maverick-stg.auth.ap-northeast-1.amazoncognito.com; img-src https://d3vhah7crmmd43.cloudfront.net https://maverick-stg.auth.ap-northeast-1.amazoncognito.com; report-uri https://maverick-stg.auth.ap-northeast-1.amazoncognito.com/cspreport",
"set-cookie": "XSRF-TOKEN=11302bca-00b5-44ec-981f-a81162eeaa82; Path=/; Secure; HttpOnly; SameSite=Lax",
"x-amz-cognito-request-id": "4a5f2d91-5480-4f93-b311-243d30f42d45",
"x-content-type-options": "nosniff",
"x-xss-protection": "1; mode=block",
"cache-control": "no-cache, no-store, max-age=0, must-revalidate",
"pragma": "no-cache",
"expires": "0",
"strict-transport-security": "max-age=31536000 ; includeSubDomains",
"x-frame-options": "DENY",
"server": "Server",
}
oauth2/token resp body: 
{
    "error": "invalid_grant"
}

END RequestId: 81fd9c22-9dfc-4363-ba5c-6f569baca42c

I saw the Token_POST event in CloudTrail, that shows 400 response was returned:

{
    "eventVersion": "1.09",
    "userIdentity": {
        "accountId": "428546013367"
    },
    "eventTime": "2023-11-19T10:33:13Z",
    "eventSource": "cognito-idp.amazonaws.com",
    "eventName": "Token_POST",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "13.114.22.190",
    "errorCode": "400",
    "requestParameters": null,
    "responseElements": null,
    "additionalEventData": {
        "responseParameters": {
            "status": 400
        },
        "requestParameters": {
            "code": [
                "HIDDEN_DUE_TO_SECURITY_REASONS"
            ],
            "grant_type": [
                "authorization_code"
            ],
            "scope": [
                "HIDDEN_DUE_TO_SECURITY_REASONS"
            ],
            "redirect_uri": [
                "https://btnhtnkhposuph346t5hlchuua0cmojc.lambda-url.ap-northeast-1.on.aws/home/authenticate"
            ],
            "client_id": [
                "14p0d6vb9am0oi72gj5rpmn5f4"
            ]
        },
        "userPoolDomain": "maverick-stg.auth.ap-northeast-1.amazoncognito.com",
        "userPoolId": "ap-northeast-1_c7AbVaAPa"
    },
    "requestID": "4a5f2d91-5480-4f93-b311-243d30f42d45",
    "eventID": "072fb837-f4e3-42fe-b9c3-c41e820dc5a6",
    "readOnly": false,
    "eventType": "AwsServiceEvent",
    "managementEvent": true,
    "recipientAccountId": "428546013367",
    "serviceEventDetails": {
        "serviceAccountId": "346377544927"
    },
    "eventCategory": "Management",
    "tlsDetails": {
        "tlsVersion": "TLSv1.2",
        "cipherSuite": "ECDHE-RSA-AES128-GCM-SHA256",
        "clientProvidedHostHeader": "maverick-stg.auth.ap-northeast-1.amazoncognito.com"
    }
}

https://ap-northeast-1.console.aws.amazon.com/cloudtrail/home?region=ap-northeast-1#/events/072fb837-f4e3-42fe-b9c3-c41e820dc5a6

What's wrong with me?

jun
已提問 6 個月前檢視次數 1106 次
1 個回答
0
已接受的答案

I've resolved it myself, reading the document carefully again: https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html

App client doesn't have read access to all attributes in the requested scope. For example, your app requests the email scope and your app client can read the email attribute, but not email_verified.

After making email_verified readable, the API now returns the tokens!

jun
已回答 6 個月前

您尚未登入。 登入 去張貼答案。

一個好的回答可以清楚地回答問題並提供建設性的意見回饋,同時有助於提問者的專業成長。

回答問題指南