I am trying to create a custom Lambda authorizer that will be shared between a few different services/serverless stacks. If I understand the documentation here https://serverless.com/framework/docs/providers/aws/events/apigateway/#note-while-using-authorizers-with-shared-api-gateway, that means that I need to create a shared authorizer resource in a “common resources” service/serverless stack, and then refer to that shared authorizer from my other services. First of all: Is my understanding correct?
If my understanding is correct, my next question becomes: How do I do this? The documentation doesn’t provide a clear example for lambda authorizers, so here’s how I tried to customize it:
functions:
authorizerFunc:
handler: authorizer/authorizer.handler
runtime: nodejs8.10
resources:
Resources:
authorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
AuthorizerResultTtlInSeconds: 0
Name: Authorizer
Type: REQUEST
AuthorizerUri: ???
RestApiId:
Fn::ImportValue: myRestApiId
I don’t understand what the syntax for AuthorizerUri is supposed to be. I’ve tried “Ref: authorizerFunc”, “Fn::GetAtt: [authorizerFunc, Arn]” etc. to no avail.
When I get the authorizerUri working, do I just add an Output for my authorizer resource, then Fn::ImportValue it from the services containing my API Lambdas?
Link to my question on the Serverless forum for posterity: https://forum.serverless.com/t/shared-lambda-authorizer/6447
Serverless 1.35.1 For people stumbling across this thread, here is the new way
Wherever you create the user pool, you can go ahead and add
ApiGatewayAuthorizer
Then when you define your functions
I had the same issue that you describe. Or at least I think so. And I managed to get it solved by following the documentation on links you provided.
The serverless documentation states for the authorizer format to be
Per my understanding, my solution (provide below) follows the hard-coded authorizer ID approach.
In the service that has the shared authorizer, it is declared in the serverless.yml in normal fashion, i.e.
Then in the service that wishes to use this shared authorizer, the function in servlerless.yml is declared as
It was crucial to add the name property. It would not work without it, at least at the moment.
For details see
Unfortunately I cannot say whether this approach has some limitations compared to your suggestion of defining authorizer as a resource. In fact, that might make it easier to re-use the same authorizer in multiple functions within same service.
This is how I did my set up since the answer posted above didn't worked for me. May be it could be helpful for someone.
I hope you know how to add an API gateway and import it here like
, since it's already specified in the accepted answer
Changing to a shared custom API Gateway Lambda Authorizer was straightforward once it was working as part of the service. At that point it was just add an arn: to a deployed lambda (authorizer) and remove the "authorizer" definition from the service to a separate deployable service.
Then the other "service" just has some custom authorizers shared by multiple deployed microservices.
Side note:
If you'd want a token type authorizer, which does forward the "authorization: bearer xyzsddfsf" as a simple event:
EDIT: Apparently my answer is now outdated. For newer versions of servicestack, see the other answers. I don't know which answer is best/most up-to-date, but if someone lets me know I'll change which answer is accepted to that one.
I eventually got it to work, so here's how I set up my autherizer's serverless.yml:
Things to note: Even though the authorizer function is called "authorizer", you need to capitalize the first letter and append "LambdaFunction" to its name when using it with GetAtt, so "authorizer" becomes "AuthorizerLambdaFunction" for some reason. I also had to add the lambda permission resource.
The API gateway resource also needs two outputs, its API ID and its API root resource ID. Here's how my API gateway's serverless.yml is set up:
Now you just need to specify to your other services that they should use this API gateway (the imported values are the outputs of the API gateway):
After that, the authorizer can be added to individual functions in this service like so: