You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AWS API Gateway自定义授权器中实现未授权用户重定向(CloudFormation)

实现方案

1. 调整Lambda自定义授权器(Python)

将授权器设置为REQUEST模式(而非默认的TOKEN模式),这样可以在验证失败时返回自定义上下文信息,供后续网关响应使用。

核心逻辑代码示例

import jwt
import os

def lambda_handler(event, context):
    # 从请求头获取Bearer令牌
    auth_header = event.get('headers', {}).get('Authorization')
    token = auth_header.split(' ')[1] if auth_header and 'Bearer' in auth_header else None

    # 令牌验证逻辑(替换为你的实际验证逻辑)
    is_valid = False
    try:
        jwt.decode(token, os.environ['SECRET_KEY'], algorithms=['HS256'])
        is_valid = True
    except:
        pass

    if is_valid:
        # 令牌有效,生成允许访问的策略
        return {
            "principalId": "authenticated-user",
            "policyDocument": {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Action": "execute-api:Invoke",
                        "Effect": "Allow",
                        "Resource": event['methodArn']
                    }
                ]
            }
        }
    else:
        # 令牌无效,返回拒绝策略+重定向URL上下文
        return {
            "principalId": "unauthenticated",
            "policyDocument": {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Action": "execute-api:Invoke",
                        "Effect": "Deny",
                        "Resource": event['methodArn']
                    }
                ]
            },
            "context": {
                "redirectUrl": "https://your-login-domain.com/login"  # 替换为你的登录页URL
            }
        }

2. CloudFormation中配置API Gateway网关响应

定义AWS::ApiGateway::GatewayResponse资源,覆盖默认的401 Unauthorized响应,将其改为302重定向:

AWSTemplateFormatVersion: '2010-09-09'
Resources:
  # ... 其他资源(Lambda授权器、API Gateway RestApi等) ...

  # 自定义未授权响应:重定向到登录页
  UnauthorizedRedirectResponse:
    Type: AWS::ApiGateway::GatewayResponse
    Properties:
      ResponseParameters:
        gatewayresponse.header.Location: "'$context.authorizer.redirectUrl'"
      ResponseTemplates:
        text/html: |
          <html><body>Redirecting to login page...</body></html>
      ResponseType: UNAUTHORIZED
      RestApiId: !Ref YourRestApi  # 替换为你的RestApi资源名
      StatusCode: '302'

3. 配置API Gateway与S3的集成

让授权通过的用户访问S3静态HTML,配置API Gateway方法集成到S3:

示例CloudFormation资源片段

# 通配资源,匹配所有子路径
  StaticResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId: !GetAtt YourRestApi.RootResourceId
      PathPart: "{proxy+}"
      RestApiId: !Ref YourRestApi

  # GET方法关联自定义授权器与S3集成
  StaticGetMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: CUSTOM
      AuthorizerId: !Ref YourCustomAuthorizer  # 关联你的Lambda授权器
      HttpMethod: GET
      Integration:
        IntegrationHttpMethod: GET
        Type: AWS
        Uri: !Sub "arn:aws:apigateway:${AWS::Region}:s3:path/${YourS3Bucket}/{proxy}"  # 替换为你的S3桶名
        Credentials: !GetAtt ApiGatewayS3AccessRole.Arn
        IntegrationResponses:
          - StatusCode: 200
            ResponseParameters:
              method.response.header.Content-Type: integration.response.header.Content-Type
        RequestParameters:
          integration.request.path.proxy: method.request.path.proxy
      RequestParameters:
        method.request.path.proxy: true
      ResourceId: !Ref StaticResource
      RestApiId: !Ref YourRestApi
      MethodResponses:
        - StatusCode: 200
          ResponseParameters:
            method.response.header.Content-Type: true

4. 配置必要的IAM权限

  • API Gateway调用Lambda授权器的权限:
ApiGatewayAuthorizerPermission:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref YourAuthorizerLambda  # 你的授权器Lambda函数名
      Principal: apigateway.amazonaws.com
      SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${YourRestApi}/*/*/*"
  • API Gateway读取S3桶的权限角色:
ApiGatewayS3AccessRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: apigateway.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: S3ReadAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action: s3:GetObject
                Resource: !Sub "${YourS3Bucket.Arn}/*"

关键注意事项

  • 确保Lambda授权器返回的Resource字段与API Gateway方法ARN完全匹配,避免权限范围错误。
  • 登录页URL必须使用绝对路径,防止重定向出现相对路径错误。
  • 修改网关响应后,需要重新部署API Gateway阶段才能生效。

内容的提问来源于stack exchange,提问作者nilskch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 12:54:17