簡體   English   中英

AWS 用戶無權通過顯式拒絕訪問此資源

[英]AWS User is not authorized to access this resource with an explicit deny

我正在 AWS 上部署一個無服務器應用程序,在嘗試從前端訪問我的無服務器應用程序時遇到了一些問題。 我的印象是問題出在后端,更具體地說是 serverless.yml 配置文件(參見下面的第一行代碼),或者我的 auth0Authorizer.ts 文件(參見下面的第二行代碼)。 當我登錄到我的前端應用程序時,我收到一條 403 錯誤消息,指出User is not authorized to access this resource with an explicit deny 我真的懷疑這是否與 AWS 上的任何配置有關。

    org: name
app: serverless-todo-app-app
service:
  name: serverless-todo-app
package:
  individually: true

plugins:
  - serverless-webpack
  - serverless-iam-roles-per-function
  - serverless-reqvalidator-plugin
  - serverless-aws-documentation

provider:
  name: aws
  runtime: nodejs8.10
  stage: ${opt:stage, 'dev'}
  region: ${opt:region, 'us-west-1'}

  tracing: true

  environment:
    TODOS_TABLE: Todos-v4-${self:provider.stage}
    USER_ID_INDEX: UserIdIndex
    SIGNED_URL_EXPIRATION: 300 
    IMAGES_S3_BUCKET: 'severless-todo-app-bucket-v1-${self:provider.stage}'
    DYNAMODB_TABLE: TableName 
    TableName: ${self:provider.environment.TODOS_TABLE}
    AUTH_0_SECRET: ***********************************
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:Scan
        - dynamodb:PutItem
        - dynamodb:GetItem
        - codedeploy:*
        - xray:PutTelemetryRecords
        - xray:PutTraceSegments
      Resource:
        - '*'
    - Effect: Allow
      Action:
        - s3:GetObject
        - xray:PutTelemetryRecords
        - xray:PutTraceSegments     
      Resource: arn:aws:s3:::${self:provider.environment.IMAGES_S3_BUCKET}/*

custom:
  documentation:
    api:
      info:
        version: v1.0.0
        title: Udagram API
        description: Serverless application
    models:
      - name: TodoRequest
        contentType: application/json
        schema: ${file(models/create-todo-request.json)}


functions:

  Auth:
    handler: src/lambda/auth/auth0Authorizer.handler

  # TODO: Configure this function
  GetTodos:
    iamRoleStatements:
      - Effect: Allow
        Action:
          - dynamodb:Query
          - dynamodb:GetItem
        Resource: arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.TODOS_TABLE}

    handler: src/lambda/http/getTodos.handler
    events:
      - http:
          authorizer: Auth
          method: get
          path: todos
          cors: true


  # TODO: Configure this function
  CreateTodo:
    handler: src/lambda/http/createTodo.handler
    iamRoleStatements:
      - Effect: Allow
        Action:
          - dynamodb:PutItem
          - xray:PutTelemetryRecords
          - xray:PutTraceSegments
        Resource: arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.TODOS_TABLE}
    events:
      - http:
          authorizer: Auth
          method: post
          path: todos
          cors: true
          reqValidatorName: RequestBodyValidator
          documentation:
            summary: Create a new todo
            description: Create a new todo
            requestModels:
              'application/json': TodoRequest
  # TODO: Configure this function
  UpdateTodo:
    handler: src/lambda/http/updateTodo.handler
    iamRoleStatements:
      - Effect: Allow
        Action:
          - dynamodb:UpdateItem
          - xray:PutTelemetryRecords
          - xray:PutTraceSegments
        Resource: arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.TODOS_TABLE}

    events:
      - http:
          authorizer: Auth
          method: patch
          path: todos/{todoId}
          cors: true
  # TODO: Configure this function
  DeleteTodo:
    handler: src/lambda/http/deleteTodo.handler
    iamRoleStatements:
      - Effect: Allow
        Action:
          - dynamodb:DeleteItem
        Resource: arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.TODOS_TABLE}

    events:
      - http:
          authorizer: Auth
          method: delete
          path: todos/{todoId}
          cors: true

  # TODO: Configure this function
  GenerateUploadUrl:
    handler: src/lambda/http/generateUploadUrl.handler
    iamRoleStatements:
      - Effect: Allow
        Action:
          - s3:PutObject
          - s3:GetObject
          - xray:PutTelemetryRecords
          - xray:PutTraceSegments
        Resource: arn:aws:s3:::${self:provider.environment.IMAGES_S3_BUCKET}/*
      - Effect: Allow
        Action:
          - dynamodb:PutItem
          - dynamodb:GetItem
          - dynamodb:UpdateItem
        Resource: arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.TODOS_TABLE}

    events:
      - http:
          authorizer: Auth
          method: post
          path: todos/{todoId}/attachment
          cors: true

resources:
  Resources:
    # TODO: Add any necessary AWS resources
    AttachmentsBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: ${self:provider.environment.IMAGES_S3_BUCKET}
        CorsConfiguration:
          CorsRules:
            -
              AllowedOrigins:
                - '*'
              AllowedHeaders:
                - '*'
              AllowedMethods:
                - GET
                - PUT
                - POST
                - DELETE
                - HEAD
              MaxAge: 0

    BucketPolicy:
      Type: AWS::S3::BucketPolicy
      Properties:
        PolicyDocument:
          Id: MyPolicy
          Version: "2012-10-17"
          Statement:
            - Sid: PublicReadForGetBucketObjects
              Effect: Allow
              Principal: '*'
              Action: 's3:GetObject'
              Resource: 'arn:aws:s3:::${self:provider.environment.IMAGES_S3_BUCKET}/*'
        Bucket: !Ref AttachmentsBucket


    GatewayResponseDefault4XX:
      Type: AWS::ApiGateway::GatewayResponse
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
          gatewayresponse.header.Access-Control-Allow-Methods: "'GET,OPTIONS,POST'"
        ResponseType: DEFAULT_4XX
        RestApiId:
          Ref: ApiGatewayRestApi

    RequestBodyValidator:
      Type: AWS::ApiGateway::RequestValidator
      Properties:
        Name: 'request-body-validator'
        RestApiId:
          Ref: ApiGatewayRestApi
        ValidateRequestBody: true
        ValidateRequestParameters: false

    TodosDynamoDBTable:
      Type: AWS::DynamoDB::Table
      Properties:
        AttributeDefinitions:
          - AttributeName: todoId
            AttributeType: S
          - AttributeName: userId
            AttributeType: S
        KeySchema:
          - AttributeName: userId
            KeyType: HASH
          - AttributeName: todoId
            KeyType: RANGE
        BillingMode: PAY_PER_REQUEST
        TableName: ${self:provider.environment.TODOS_TABLE}
        GlobalSecondaryIndexes:
          - IndexName: ${self:provider.environment.USER_ID_INDEX}
            KeySchema:
            - AttributeName: userId
              KeyType: HASH

            Projection:
              ProjectionType: ALL
import { CustomAuthorizerEvent, CustomAuthorizerResult, CustomAuthorizerHandler } from 'aws-lambda'
import 'source-map-support/register'
import { verify } from 'jsonwebtoken'
import { JwtToken } from '../../auth/JwtToken'

const auth0Secret = process.env.AUTH_0_SECRET
export const handler: CustomAuthorizerHandler = async (event: CustomAuthorizerEvent): Promise<CustomAuthorizerResult> => {
  try {
    const decodedToken = verifyToken(event.authorizationToken)
    console.log('User was authorized')

    return {
      principalId: decodedToken.sub,
      policyDocument: {
        Version: '2012-10-17',
        Statement: [
          {
            Action: 'execute-api:Invoke',
            Effect: 'Allow',
            Resource: '*'
          }
        ]
      }
    }
  } catch (e) {
    console.log('User was not authorized', e.message)

    return {
      principalId: 'user',
      policyDocument: {
        Version: '2012-10-17',
        Statement: [
          {
            Action: 'execute-api:Invoke',
            Effect: 'Deny',
            Resource: '*'
          }
        ]
      }
    }
  }
}

function verifyToken(authHeader: string): JwtToken {
  if (!authHeader)
    throw new Error('No authentication header')

  if (!authHeader.toLowerCase().startsWith('bearer '))
    throw new Error('Invalid authentication header')

  const split = authHeader.split(' ')
  const token = split[1]

  return verify(token, auth0Secret) as JwtToken
}

當 AWS 說明確拒絕表示 IAM 策略鏈中的某個位置時,該操作有一個拒絕。 在這種情況下,唯一的策略是您的授權方 Lambda 提供的會話策略。 正如評論中提到的@hephalump 並根據您的代碼,它會在出現錯誤時發生,因此請檢查日志以查看需要做什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM