AWS 用户无权通过显式拒绝访问此资源
Posted
技术标签:
【中文标题】AWS 用户无权通过显式拒绝访问此资源【英文标题】:AWS User is not authorized to access this resource with an explicit deny 【发布时间】:2020-01-04 14:26:05 【问题描述】:我正在 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
【问题讨论】:
您正在代码的错误块中传递会话策略。如果您的代码产生错误,则将应用您在execute-api:Invoke
上的带有 Deny
的会话策略。检查所引发错误的日志。
【参考方案1】:
当 AWS 明确表示拒绝表示 IAM 策略链中的某个位置时,该操作存在拒绝。在这种情况下,唯一的策略是您的授权方 Lambda 提供的会话策略。正如 @hephalump 在 cmets 中提到的那样,根据您的代码,它会在出现错误时发生,因此请检查日志以查看需要做什么。
【讨论】:
以上是关于AWS 用户无权通过显式拒绝访问此资源的主要内容,如果未能解决你的问题,请参考以下文章
403 - 禁止访问: 访问被拒绝。您无权使用所提供的凭据查看此目录或页面。 怎么解决 ?
在 AWS Lambda 中担任角色,在 SSM 调用时拒绝访问