Search code examples
amazon-web-servicesaws-lambdaasp.net-core-webapiaws-api-gatewayserverless-framework

AWS API Gateway .NET 6 Web API with SPA (Angular) hosted from wwwroot with UseStaticFiles() error


We've deployed a .NET 6 Web API project to AWS Lambda behind API Gateway utilizing the Serverless Framework and the Lambda proxy integration approach to run the Web API project in Lambda. We have typically hosted corresponding SPAs out of AWS S3 but decided to go the route of including/hosting the static assets for an Angular SPA in the backend via the wwwroot folder and with UseStaticFiles() in Startup.cs. Additionally, we are using a custom domain name (e.g. dev.myapp.com) associated with our API Gateway.

We are successful in reaching and using the Angular app when we make a request to our domain with "/index.html" (so e.g. https://dev.myapp.com/index.html) but when we do not include "/index.html" (so just dev.myapp.com) we get an error response:

{"message":"Missing Authentication Token"}

I thought this might have something to do with the configuration of a fallback file in Startup.cs but this error seems to be coming from API Gateway and not the .NET app itself.

It seems like there needs to be something configured in API Gateway but its unclear what that might be. The Lambda function that contains the Web API project in serverless.yml is configured:

functions:
    backend-api:
        handler: ABC.API::ABC.API.LambdaEntryPoint::FunctionHandlerAsync
        description: ${self:custom.appConfig.config.stack-description} API for ${opt:stage}
        memorySize: 512
        runtime: dotnet6
        tracing: Active
        timeout: 30
        events:
            - http:
                path: '/{proxy+}'
                method: 'ANY'

Solution

  • The solution was to add an additional event handler explicitly for the root '/' in serverless.yml:

    functions:
        backend-api:
            handler: ABC.API::ABC.API.LambdaEntryPoint::FunctionHandlerAsync
            description: ${self:custom.appConfig.config.stack-description} API for ${opt:stage}
            memorySize: 512
            runtime: dotnet6
            tracing: Active
            timeout: 30
            events:
                - http:
                    path: '/'
                    method: 'ANY'
                - http:
                    path: '/{proxy+}'
                    method: 'ANY'
    

    I also added app.UseDefaultFiles(); before app.UseStaticFiles(); in Startup.cs.