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

如何通过AWS API Gateway的Lambda Authorizer管控Swagger文档访问权限?

用AWS Lambda Authorizer保护Swagger UI的落地方案

整体思路

直接给API Gateway上的GET /swagger/*通配符路径绑定Lambda令牌型Authorizer,由Authorizer负责校验请求头里的JWT:没令牌就重定向到OAuth登录页,令牌里没指定角色就拒绝访问,验证通过才放行Swagger相关资源。

具体实现步骤

1. SAM模板配置Authorizer与路径关联

在你的SAM模板里,给API Gateway资源定义好Swagger专用的Lambda Authorizer,然后把它绑定到/swagger/{proxy+}路径的GET方法上——这个路径能匹配所有Swagger的子页面和静态资源:

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Auth:
        DefaultAuthorizer: None  # 其他路径默认不启用授权
        Authorizers:
          SwaggerAuthorizer:
            FunctionArn: !GetAtt SwaggerAuthFunction.Arn
            IdentitySource: method.request.header.Authorization
            Type: TOKEN
            AuthType: Bearer
      DefinitionBody:
        swagger: '2.0'
        paths:
          /swagger/{proxy+}:
            get:
              x-amazon-apigateway-integration:
                uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyLambdaFunction.Arn}/invocations
                httpMethod: POST
                type: aws_proxy
              security:
                - SwaggerAuthorizer: []  # 这个路径强制走SwaggerAuthorizer

2. Lambda Authorizer核心逻辑(Python示例,也可改用.NET编写)

Authorizer要做三件事:提令牌、验令牌、查角色,没通过就返回重定向或拒绝:

import jwt
import os
from jwt.exceptions import InvalidTokenError

def lambda_handler(event, context):
    auth_header = event.get('authorizationToken')
    # 没有Bearer令牌的情况,返回重定向指令
    if not auth_header or not auth_header.startswith('Bearer '):
        return build_redirect_response()
    
    token = auth_header.split(' ')[1]
    try:
        # 实际生产环境要替换成真实的JWT验证逻辑,比如拉取Cognito的JWKS验签
        decoded_token = jwt.decode(
            token,
            os.environ.get('JWT_PUBLIC_KEY'),
            algorithms=['RS256'],
            audience=os.environ.get('JWT_AUDIENCE'),
            issuer=os.environ.get('JWT_ISSUER')
        )
        # 检查令牌里是否包含允许访问Swagger的角色,比如'SwaggerViewer'
        user_roles = decoded_token.get('cognito:groups', [])
        if 'SwaggerViewer' not in user_roles:
            return build_deny_response()
        
        # 验证通过,生成允许访问的策略
        return build_allow_policy(
            event['requestContext']['identity']['userArn'],
            event['methodArn']
        )
    except InvalidTokenError:
        # 令牌无效,同样返回重定向
        return build_redirect_response()

def build_allow_policy(principal_id, resource):
    return {
        'principalId': principal_id,
        'policyDocument': {
            'Version': '2012-10-17',
            'Statement': [{
                'Action': 'execute-api:Invoke',
                'Effect': 'Allow',
                'Resource': resource
            }]
        }
    }

def build_deny_response():
    return {
        'principalId': 'unauthorized-user',
        'policyDocument': {
            'Version': '2012-10-17',
            'Statement': [{
                'Action': 'execute-api:Invoke',
                'Effect': 'Deny',
                'Resource': '*'
            }]
        },
        'context': {'message': '你没有访问Swagger的权限'}
    }

def build_redirect_response():
    # 把重定向URL放在context里,后续API Gateway会用这个值生成302响应
    return {
        'principalId': 'anonymous',
        'policyDocument': {
            'Version': '2012-10-17',
            'Statement': [{
                'Action': 'execute-api:Invoke',
                'Effect': 'Deny',
                'Resource': '*'
            }]
        },
        'context': {
            'redirectUrl': 'https://你的OAuth提供商地址/login?redirect_uri=https://你的API网关地址/swagger'
        }
    }

3. API Gateway配置重定向响应

Lambda Authorizer本身没法直接返回302,得在API Gateway的集成响应里配置:

  • 新增一个401状态码的集成响应
  • 添加响应头Location,值设置为$context.authorizer.redirectUrl(从Authorizer的context里取重定向地址)
  • 把这个集成响应的状态码映射为302

4. .NET 6 Swashbuckle适配调整

确保Swagger的路由前缀是swagger,启动类里的配置要对应:

builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "你的服务名", Version = "v1" });
});

// ...

app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "你的服务名 v1");
    c.RoutePrefix = "swagger"; // 这个前缀要和API Gateway的路径匹配
});

另外要注意,API Gateway做代理时,Swagger UI的静态资源路径要能被正确转发,默认配置就能适配。

关键注意点

  • JWT验签一定要用真实的公钥,示例里的环境变量要替换成你实际OAuth提供商的配置(比如Cognito的JWKS地址)
  • OAuth登录页的回调URL要配置成你的API Gateway的Swagger路径,确保用户登录后能跳回Swagger UI
  • SAM部署时,要给Lambda Authorizer配置足够的权限,比如允许它访问Cognito的JWKS端点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 15:24:09