如何通过AWS API Gateway的Lambda Authorizer管控Swagger文档访问权限?
整体思路
直接给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
相关产品推荐
相关产品推荐

