Serverless-application-model: Authorization on api?

Created on 26 Nov 2016  路  15Comments  路  Source: aws/serverless-application-model

It seems it's not possible to define authorization (IAM or Custom) on the implicit API created as a lambda event source. And it looks like AWS::Serverless::Api doesn't support it either? Is there any plan to add this feature?

Most helpful comment

Alto I hit the next wall, I can't assign this to the methods, as the serverless function does not support authorizer ? Or do I miss something here ?

All 15 comments

I think this can be done through the Swagger template, just add the following sections, the first one either at the top level of the file, or for individual resources:

security:
  - sigv4: []
securityDefinitions:
  sigv4:
    type: "apiKey"
    name: "Authorization"
    in: "header"
    x-amazon-apigateway-authtype: "awsSigv4"

Also if you want a custom authorizer, try configuring it via the Console, then export the Swagger file with AWS extensions. The relevant sections will be in that file.

Checkout /examples/2016-10-31/api_swagger_cors for example on how to use Swagger with SAM API

I have Authorization working by specifying it in Swagger.
The tricky part is that it's necessary to explicitly permit it to be invoked by API Gateway. I used:

AuthorizerFunctionLambdaPermission:
  Type: AWS::Lambda::Permission
  Properties:
    FunctionName: !Ref Authorizerfunction
    Action: lambda:InvokeFunction
    Principal: apigateway.amazonaws.com

When I add an event to the authorizer function, to let SAM automatically creates the Permission, it looks like the permission isn't granted. I did:

AuthorizerFunction:
  Type: AWS::Serverless::Function
  Properties:
    Events:
      AuthorizerApiRoot: 
        Properties:
          Method: GET
          Path: /
          RestApiId: !Ref ApiGatewayApi
        Type: Api
    Handler: authorizer.handler
    Role: arn:aws:iam::570723136177:role/LambdaExecutionRole
    Runtime: nodejs4.3

But when I try this, in CloudWatch I see Invalid permissions on Lambda function.
I do see the permission created in CloudFormation.

I think issue seem to be replacing dynamically generated lambda function name in swagger.yml file
uri: arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:***78:function:${stageVariables.LambdaFunctionName}/invocations

Works fine if we replace generated function name manually .

Now it stopped working. Using the API Gateway Authorizers console test:

Execution log for request test-request
Fri Dec 09 07:06:27 UTC 2016 : Starting authorizer: h2ur54 for request: test-request
Fri Dec 09 07:06:27 UTC 2016 : Incoming identity: testing123
Fri Dec 09 07:06:27 UTC 2016 : Execution failed due to an internal error
Fri Dec 09 07:06:27 UTC 2016 : Internal server error

When I type in the actual function name in the box and confirm giving the permissions, it works.

@sanathkr I have enabled iam auth on my resource but it doesn't seem to enable auth on the stage, which makes the api still public accessible. What am I doing wrong?

---
swagger: "2.0"
basePath: "/Prod"
schemes:
  - "https"
paths:
  /report:
    get:
      x-amazon-apigateway-auth:
        type: aws_iam
      responses: {}
      x-amazon-apigateway-integration:
        type: "aws_proxy"
        uri: "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:<<my account id>>:function:${stageVariables.LambdaFunctionName}/invocations"
        passthroughBehavior: "when_no_match"
        httpMethod: "POST"
info:
  version: "1.0"
  title: "dev-reporting-test"


Ah got it, as @dinvlad stated above. Not well documented anywhere I could find.

---
swagger: "2.0"
basePath: "/Prod"
schemes:
  - "https"
paths:
  /report:
    get:
      responses: {}
      security:
        - sigv4: []
      x-amazon-apigateway-integration:
        type: "aws_proxy"
        uri: "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:<< account id >>:function:${stageVariables.LambdaFunctionName}/invocations"
        passthroughBehavior: "when_no_match"
        httpMethod: "POST"
info:
  version: "1.0"
  title: "dev-reporting-test"
securityDefinitions:
  sigv4:
    type: "apiKey"
    name: "Authorization"
    in: "header"
    x-amazon-apigateway-authtype: "awsSigv4"



Btw security: - sigv4: [] can be enabled globally by specifying it at the root of the document, if that's what you'd like: http://swagger.io/specification/#swaggerObject

Closing this in favor of #49 as a feature request to add custom authorizers to implicit APIs

With cognito user pool I managed to use it like this: (no swagger here)

"Authorizer": {
      "Type": "AWS::ApiGateway::Authorizer",
      "Properties": {
        "Type": "COGNITO_USER_POOLS",
        "IdentitySource": "method.request.header.Auth",
        "Name": "MagicAuthorizer",
        "ProviderARNs": ["arn:aws:cognito-idp:eu-west-1:<ACCOUNT ID>:userpool/<POOL NAME>"],
        "RestApiId": {
          "Ref": "ServerlessRestApi"
        }
}

so ProviderARNs is basically the arn of the userpool.
The only trick is the RestApiId, which is "generated" when transforming serverless function to cloudformation. I guess it will be always ServerlessRestApi.

Hope it helps someone.

edit: forum motor messes up the "code" section I don't know why... but it json, so you can copy... :/
edit2: because I lame, that's why. Fixed.

Alto I hit the next wall, I can't assign this to the methods, as the serverless function does not support authorizer ? Or do I miss something here ?

It seems you can reference your Authorizer @marczis in swagger e.g.:

...
          "paths": {
            "/services/rest/acls/{entityId}": {
              "patch": {
                "description": "do stuff.",
                "consumes": [
                  "application/json"
                ],
                "parameters": [],
                "responses": {},
                "security": [
                  {
                    "MagicAuthorizer": []
                  }
                ],
...

at least that's the export, but I can't seem to get it to work when deploying. Also noted that sam/cloudformation completely removed the APIGW Authorizer if I updated the inline swagger.

Not sure if this is a new bug, or I should re-open this one.

Spoke too soon: remove the Cloudformation, add it to the swagger resolves my issues:

```
securityDefinitions: {
'MagicAuthorizer': {
type: 'apiKey',
name: 'Authorization',
in: 'header',
'x-amazon-apigateway-authtype': 'cognito_user_pools',
'x-amazon-apigateway-authorizer': {
providerARNs: [
FnGetAtt(:cognitopool, 'Arn')
],
type: 'cognito_user_pools'
}
}
},

See https://github.com/awslabs/serverless-application-model/pull/546 which recently added support for Auth property on explicit/implicit Api resources, (see also api_lambda_*_auth examples here https://github.com/awslabs/serverless-application-model/tree/develop/examples/2016-10-31/)

Was this page helpful?
0 / 5 - 0 ratings