从 lambda 授权方响应中提取身份
Extracting Identity from lambda authorizer response
我创建了一个自定义的 lambda 授权方来验证 JWT 和 returns 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 error
。)
我还发现,当APIGatewayProxyFunction
提取身份时,它会查看Authorizer.Claims。
所以我需要以某种方式绕过 Claims
属性 在我的资源服务器上提取它们,或者将嵌套对象添加到授权方响应中,这是不允许的。
做什么?
所以我通过覆盖 LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
上的 PostCreateContext
方法解决了这个问题。
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 库提交了一个 pull reqeust 来解决这个问题。
编辑 2:我的 pull request 已经合并了一段时间,如果使用最新的 Amazon.Lambda.AspNetCoreServer
这不再是问题(不确定哪个版本最先有它,但 3.1.0 肯定有它)
我创建了一个自定义的 lambda 授权方来验证 JWT 和 returns 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 error
。)
我还发现,当APIGatewayProxyFunction
提取身份时,它会查看Authorizer.Claims。
所以我需要以某种方式绕过 Claims
属性 在我的资源服务器上提取它们,或者将嵌套对象添加到授权方响应中,这是不允许的。
做什么?
所以我通过覆盖 LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
上的 PostCreateContext
方法解决了这个问题。
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 库提交了一个 pull reqeust 来解决这个问题。
编辑 2:我的 pull request 已经合并了一段时间,如果使用最新的 Amazon.Lambda.AspNetCoreServer
这不再是问题(不确定哪个版本最先有它,但 3.1.0 肯定有它)