将 Cognito 与 C# 无服务器应用程序结合使用

Using Cognito with C# serverless application

我想创建一个使用 AWS Cognito 进行身份验证的 AWS 无服务器应用程序。我的起点是 Visual Studio 2017 年的 C# AWS Serverless Application with Tests (.NET Core) 模板。部署时,模板会创建一些 Lambda 函数并设置 AWS API 网关,以便我可以通过 REST 连接到 Lambda 函数要求。这行得通。

我在 AWS Cognito 中创建了一个用户池,以及一个允许用户使用 AWS Cognito 登录的 javascript 客户端(单页应用程序)。在 javascript 客户端中,我能够连接到 AWS Cognito 并获取 ID、访问和刷新令牌作为 JWT。我还可以在 Authorization: Bearer eyblablabla... header 中将这些令牌发送到后端(AWS 无服务器应用程序)。因此 javascript 客户端身份验证和 AWS Cognito 设置似乎有效。我还在 AWS API 网关中设置了一个指向 AWS Cognito 用户池的授权方。

我的问题如下:后端似乎没有意识到授权 header。在检查请求时,我没有得到任何针对用户的声明。我特别感兴趣的是获得 sub 声明,以便我可以识别用户。另外,我希望 API 网关为特定方法自动发送 Unauthorized 响应,但我不知道如何设置它。

作为 Lambda 函数签名的一部分,我收到了一个 APIGatewayProxyRequest 请求 object。显然 request.RequestContext.Authorizer.Claims 应该包含用户声明,但 .Authorizer 为空。

我能够获取我从 javascript 客户端发送的任何 JWT y 读取请求 header,因此我可以解析令牌以获取用户声明。但我认为我的设置一定有问题,因为 .Authorizer 没有被填充。

到目前为止我发现的唯一建议涉及 serverless.yml 或 Swagger 模板文件中的内容,它们都不是 AWS 无服务器应用程序 VS2017 模板的一部分。相反,我有一个 serverless.template JSON 文件,并且没有明显的方法向该文件添加身份验证/安全设置。

到目前为止,我的代码与 VS2017 中的 AWS 无服务器应用程序模板相同。

非常感谢任何帮助。

您需要在 API 方法集成请求中启用使用 Lambda 代理集成。 您的 APIGatewayProxyRequest 对象将如下所示:

{
"Resource": "/test",
"Path": "/test",
"HttpMethod": "GET",
"Headers": {
    "Accept": "*/*",
    "accept-encoding": "gzip, deflate",
    "Authorization": "your token",
    "cache-control": "no-cache",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Desktop-Viewer": "true",
    "CloudFront-Is-Mobile-Viewer": "false",
    "CloudFront-Is-SmartTV-Viewer": "false",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Viewer-Country": "US",
    "Host": "xxxxxxx.execute-api.us-east-1.amazonaws.com",
    "Postman-Token": "08820d50-c5d4-498a-bfee-c76994bb91f1",
    "User-Agent": "PostmanRuntime/7.4.0",
    "Via": "1.1 dd169cfdbbafbb3da513bede6bc6640e.cloudfront.net (CloudFront)",
    "X-Amz-Cf-Id": "89ftx9aaVK0k2KOFu-5QESLXzGUGAw17gNCCY03in-hF2hd-LvRhIg==",
    "X-Amzn-Trace-Id": "Root=1-5c125bb9-1e8b9fea8d1beb20147a24d2",
    "X-Forwarded-For": "50.196.109.21, 70.132.33.133",
    "X-Forwarded-Port": "443",
    "X-Forwarded-Proto": "https"
},
"QueryStringParameters": null,
"PathParameters": null,
"StageVariables": null,
"RequestContext": {
    "Path": "/test_oauth/token",
    "AccountId": "xxxxxxxxxxxxx",
    "ResourceId": "luy67k",
    "Stage": "test_oauth",
    "RequestId": "5455133d-fed9-11e8-8f41-ef35907ced2d",
    "Identity": {
        "CognitoIdentityPoolId": null,
        "AccountId": null,
        "CognitoIdentityId": null,
        "Caller": null,
        "ApiKey": null,
        "SourceIp": "50.196.109.21",
        "CognitoAuthenticationType": null,
        "CognitoAuthenticationProvider": null,
        "UserArn": null,
        "UserAgent": "PostmanRuntime/7.4.0",
        "User": null
    },
    "ResourcePath": "/token",
    "HttpMethod": "GET",
    "ApiId": "8xxg9ez961",
    "Authorizer": {
        "claims": {
            "sub": "4560ac4b-54a0-4184-8831-e3cb2583726b",
            "aud": "xxxxxxxxxxxxxxxx",
            "email_verified": "false",
            "event_id": "467633ad-fed9-11e8-88ff-25be6cd15697",
            "token_use": "id",
            "custom:ApplicationId": "12345",
            "auth_time": "1544706978",
            "iss": "https://cognito-idp.us-east-1.amazonaws.com/us-east-xxxxxxxxx",
            "cognito:username": "username",
            "exp": "Thu Dec 13 14:16:18 UTC 2018",
            "iat": "Thu Dec 13 13:16:18 UTC 2018",
            "email": "user@email.com"
        }
    }
},
"Body": null,
"IsBase64Encoded": false
}

请注意,如果您的 API 网关设置为使用 id 令牌与访问令牌(这是在您的 API网关设置)。您还会发现结果取决于您的用户池应用程序客户端的设置 - 启用了哪些允许的 Oauth 范围以及为您的应用程序客户端启用了哪些属性。