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 个月前1103 查看次数
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 个月前

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则