-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[apigateway] add support for lambda token authorizer #1402
Comments
Looks like a bug |
Happy to do a PR if you can point me in the right direction @eladb |
The code the synthesizes the method resource is here. Not 100% sure why this is not propagating. |
Hi @eladb . Just revisiting this and I wasn't able to see any issue with the code there either. I noticed you removed the gap label. I've done a bit more digging and it looks like the authorizationType is getting populated now but I'm still getting an error. The only difference I can see is that the requestParameters and requestModels is being populated with an empty object in CDK deployment. |
Looking into it |
The label was me, I must have misclicked in the UI. Sorry about that. |
@brianfoody I am trying to understand what the issue is exactly at this point. Any chance you can submit a more complete code snippet so we can try to reproduce? |
Hi @eladb . Yes sorry it's been a confusing one to hunt down. I turned on CloudWatch logs for my API Gateway method and I can see now that the actual error is that APIGateway doesn't have permission to invoke the authorizer. I'm guessing when I do it manually it adds the permissions as well. I just need to figure out how to give the API Gateway method permission to call the authorizer now through CDK. |
Probably ties into #1465 somewhat? Or am I wrong? |
Authorizers are simply not supported by our L2 library yet, so yes- manual permission grants are needed. |
You should be able to use |
Well 6 hours later I have resolved the issue. The grantInvoke didn't actually work for me. I had to create a custom script to attach the right permissions in the end as it required a weird I guess I should close for now if it's a known issue based on L2 library but it would be good if this could be documented somewhere. |
@brianfoody apologies for the unpleasant experience, and thanks for sharing your solution. I am reopening this issue and repurposing it as “support lambda authorizers”. |
I managed to get this working with the following code (along with cors support): The repository is still work in progress... Edit: updated the link to a new location |
@erezrokah is this working for you without doing something else? Not working for me at the moment.. |
I want try to undestand why it doesn't work on python. so I tried to "translate" in python this -> https://github.com/IainCole/aws-cdk/blob/ic_add_apig_authorizer/packages/%40aws-cdk/aws-apigateway/lib/authorizer.ts#L17
but I receive this error: why? please don't tell me "translate from this https://docs.aws.amazon.com/cdk/latest/guide/multiple_languages.html" I've read the doc. How can I use the IAuthorizer? is it possible or a this time do I have to use CfnMethod with CfnAuthorizer? |
I don't really know python but I feel like it should look like this:
Rather than:
|
nope with your solution because I need an authorize_id Invalid authorizer ID specified. Setting the authorization type to CUSTOM or COGNITO_USER_POOLS requires a valid authorizer. (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: **********) I'm trying with cfn resources |
Right but this is still progress, it gets further along than it did before presumably if it's actually making it to cloudformation rather than an error building the CDK app, but for whatever reason it doesn't like the ID that it's getting. What is |
it's the resource. inside of that there's the post method |
I don't really have much to go on here. Are you able to paste the generated template from cdk.out when running my suggested fix? Or at least the API gateway parts? |
ok. I will also send my code and my not working solution with CFN |
error: It didn't upload the autorizer_id in the CF.
this is the piece of yaml:
|
in the code I created two method: GET and POST.
|
Solution founded for python:
you have to use CfnAuthorizer to create the authorizer and the use the CfnMethod explicity set the .CfnMethod.IntegrationProperty |
Below worked for me(TypeScript): const authorizeFunc = new lambda.Function( ... );
const authorizeFuncExecutionRole = new iam.Role(this, 'authorizeFuncExecution', {
assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'),
});
authorizeFunc.grantInvoke(authorizeFuncExecutionRole);
const chargeFunc = new lambda.Function( ... );
const apigwLambdaIntegration = new apigateway.LambdaIntegration(chargeFunc, {
proxy: true,
});
const apigw = new apigateway.RestApi(this, 'api', {
restApiName: 'api',
});
const authorizer = new apigateway.CfnAuthorizer(this, 'authorizer', {
name: 'authorizer',
authorizerUri: `arn:aws:apigateway:${this.region}:lambda:path/2015-03-31/functions/${authorizeFunc.functionArn}/invocations`,
type: 'TOKEN',
authorizerCredentials: authorizeFuncExecutionRole.roleArn,
identitySource: 'method.request.header.Authorization',
restApiId: apigw.restApiId,
});
const chargePath = apigw.root.addResource('charge');
chargePath.addMethod('POST', apigwLambdaIntegration, {
authorizationType: apigateway.AuthorizationType.CUSTOM,
authorizer: {authorizerId: authorizer.ref},
}); I referenced https://stackoverflow.com/a/58170219/8182174. |
how?
what's in ts this? -> authorizer: {authorizerId: authorizer.ref} |
@gidimariastorm export interface IAuthorizer {
readonly authorizerId: string;
} The code results such template.yml:
I'm not sure about the internal detail of CDK but I guess |
I know that authorizerId i'ts an attribute of IAuhtorizer :) . How can you call the IAuthorizer obj (and change its readonly value) without create an instance of it? |
@gidimariastorm
No, it's creating new object. So it's same as: class MyAuthorizer {
public authorizerId: string;
constructor(authorizerId: string) {
this.authorizerId = authorizerId;
}
}
...
authorizer: new MyAuthorizer(authorizer.ref), |
ok, I don't think that in python is possible |
I've started to build first class L2 support for Lambda authorizers. Are there (preferably complete) CDK apps or CF templates that I can use as references for how Lambda request authorizers and Lambda token authorizers are used and set up? |
@gidimariastorm I am also facing the same issue. Only solution, it seems to me, is to directly manipulate CloudFormation properties, as you have demonstrated before. The same issue is also reported here : #723 (comment) The solution I came up with is a hybrid of meth = auto_scaling_res.add_method('POST', authorization_type=apigw.AuthorizationType.CUSTOM)
meth.node.find_child("Resource").add_property_override('AuthorizerId', auth.authorizer_id) The above approach is working in my program. Nonetheless, I really wish I could simply use |
I did the same think. the problem is the Deploy because add_method cannot deploy the new version. you have to create a CFN resource for the deploy |
What do you mean? I was able to deploy the stack, using the above logic. My code: class ApigatewayCognitoStack(core.Stack):
def __init__(self, scope: core.App, id: str, cognito_arn: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
api = apigw.RestApi(self, 'my_API')
test_resource = api.root.add_resource('test')
# Cognito authorizer
cfn_authorizer = apigw.CfnAuthorizer(
self, "my_cognito",
name='API_authorizer',
type='COGNITO_USER_POOLS',
identity_source='method.request.header.Authorization',
rest_api_id=api.rest_api_id,
provider_arns=[cognito_arn]
)
hello_world_handler = _lambda.Function(
self, 'my_handler',
code=_lambda.AssetCode('lambda'),
handler='index.handler',
runtime=_lambda.Runtime.PYTHON_3_7
)
# attach GET method
hello_world_integration = apigw.LambdaIntegration(hello_world_handler)
meth = test_resource.add_method("GET", hello_world_integration,
authorization_type=apigw.AuthorizationType.COGNITO
)
meth.node.find_child('Resource').add_property_override('AuthorizerId', cfn_authorizer.ref) |
Support for lambda token authorizers - #5197 |
In addition to the fantastic solution suggested by @acomagu https://github.com/aws/aws-cdk/issues/1402#issuecomment-544325927, I also found it necessary to add the following line: const authorizeFuncExecutionRole = new iam.Role(this, 'authorizeFuncExecution', {
assumedBy: new iam.ServicePrincipal('apigateway.amazonaws.com'),
});
authorizeFunc.grantInvoke(authorizeFuncExecutionRole);
authorizeFunc.latestVersion.grantInvoke(authorizeFuncExecutionRole); // This line which yields the following policy for your
Not sure if this is necessary for everyone but I've had to do a similar thing in the past with Firehose invoking Lambdas and not having permission to invoke the latest version. Anyway - it fixed my issue so thought I'd share. |
Thanks @nija-at ! |
When I specify an authorizerType of CUSTOM for my Lambda integration it doesn't actually populate when deployed to AWS and I have to manually update.
This is the authorizer spec;
When deployed it only has an authorizerId
however when I manually update the authorizerType is populated and everything works perfectly;
The text was updated successfully, but these errors were encountered: