从lambda授权者响应中提取身份

时间:2019-03-04 16:59:55

标签: asp.net-core asp.net-identity amazon-cognito aws-sdk-net lambda-authorizer

我制作了一个自定义的lambda授权器,用于验证JWT并返回Allow策略。

 var context = new APIGatewayCustomAuthorizerContextOutput();

 var tokenUse = ExtractClaims(claims, "token_use");
 context["tokenType"] = tokenUse;
 var response = new APIGatewayCustomAuthorizerResponse
 {
     PrincipalID = "asd",
     PolicyDocument = new APIGatewayCustomAuthorizerPolicy
     {
         Version = "2012-10-17",
         Statement = new List<APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement>()
         {
             new APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement
             {
                 Action = new HashSet<string>() {"execute-api:Invoke"},
                 Effect = "Allow",
                 Resource = new HashSet<string>() {"***"} // resource arn here
              }
          },
      },
      Context = context
 };

 return response;

现在,我需要在资源服务器上使用此身份。

问题是我放在授权者上下文中的声明直接出现在authorizer

 "authorizer": {
            "cognito:groups": "Admin", ...
 }

但是我的Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction期望authorizer.claims以下的人。

像这样:

 "authorizer": {
            "claims": {
                "cognito:groups": "Admin", ... 
             }
  }

我知道,因为当我使用内置的Cognito用户池授权器时,它就可以正常工作了。

我设法发现Lambda Authorizer不允许将嵌套对象添加到上下文中(并测试了这样做是否抛出authorizer error。)

我还发现,APIGatewayProxyFunction提取身份时,它会查看Authorizer.Claims。

因此,我需要以某种方式绕过Claims属性在我的资源服务器上提取它们,或者将一个嵌套对象添加到授权者响应中,这是不允许的。

做什么?

1 个答案:

答案 0 :(得分:0)

因此,我通过在PostCreateContext上覆盖LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction方法来解决了这个问题。

protected override void PostCreateContext(
        HostingApplication.Context context,
        APIGatewayProxyRequest apiGatewayRequest, ILambdaContext lambdaContext)
{
        // handling output from cognito user pool authorizer
        if (apiGatewayRequest?.RequestContext?.Authorizer?.Claims != null)
        {
            var identity = new ClaimsIdentity(apiGatewayRequest.RequestContext.Authorizer.Claims.Select(
                entry => new Claim(entry.Key, entry.Value.ToString())), "AuthorizerIdentity");

            context.HttpContext.User = new ClaimsPrincipal(identity);
            return;
        }

        // handling output from lambda authorizer
        if (apiGatewayRequest?.RequestContext?.Authorizer != null)
        {
            var identity = new ClaimsIdentity(apiGatewayRequest.RequestContext.Authorizer.Select(
                entry => new Claim(entry.Key, entry.Value.ToString())), "AuthorizerIdentity");

            context.HttpContext.User = new ClaimsPrincipal(identity);
        }
    }

编辑:还向aws-lambda-dotnet库提交了一个拉动请求,以解决此问题。