AWS API Gateway验证与授权:如何校验请求体UserID与令牌Subject匹配?
userid vs JWT sub Match in AWS API Gateway Got it, let's walk through how to enforce that the userid in your POST request body matches the sub (subject) claim from the JWT token in AWS API Gateway. This is a critical security check to block spoofed requests, and there are two reliable approaches to implement it:
Method 1: Lambda Authorizer (Recommended for Flexibility)
A Lambda authorizer gives you full control over the validation logic—you can parse the JWT, extract the sub claim, compare it to the request body's userid, and return an allow/deny policy accordingly.
Step 1: Create the Lambda Authorization Function
Here's a Node.js example that handles JWT validation (using Cognito as the identity provider) and the userid vs sub check:
const jwt = require('jsonwebtoken'); const jwksClient = require('jwks-rsa'); // Configure JWKS client to fetch public keys for JWT signature verification const client = jwksClient({ jwksUri: 'https://cognito-idp.{your-region}.amazonaws.com/{your-user-pool-id}/.well-known/jwks.json' }); function getSigningKey(header, callback) { client.getSigningKey(header.kid, (err, key) => { const signingKey = key.getPublicKey(); callback(null, signingKey); }); } exports.handler = async (event) => { try { // Extract and validate the JWT from the Authorization header const authHeader = event.headers.Authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { return generatePolicy('unauthorized', 'Deny', event.methodArn); } const token = authHeader.split(' ')[1]; // Verify and decode the JWT const decodedToken = await new Promise((resolve, reject) => { jwt.verify( token, getSigningKey, { audience: '{your-audience}', issuer: '{your-issuer}' }, (err, decoded) => err ? reject(err) : resolve(decoded) ); }); // Parse the request body and extract userid const requestBody = JSON.parse(event.body); const requestUserId = requestBody.userid; // Critical check: Ensure userid matches the JWT's sub claim if (decodedToken.sub !== requestUserId) { console.warn(`Mismatch: Request userid ${requestUserId} vs JWT sub ${decodedToken.sub}`); return generatePolicy('unauthorized', 'Deny', event.methodArn); } // Return allow policy if all checks pass return generatePolicy(decodedToken.sub, 'Allow', event.methodArn); } catch (error) { console.error('Authorization failed:', error); return generatePolicy('unauthorized', 'Deny', event.methodArn); } }; // Helper function to generate IAM policy for API Gateway function generatePolicy(principalId, effect, resource) { return { principalId, policyDocument: { Version: '2012-10-17', Statement: [{ Action: 'execute-api:Invoke', Effect: effect, Resource: resource }] } }; }
Step 2: Configure API Gateway to Use the Lambda Authorizer
- Go to your API Gateway console, select the POST
/v1/detailsmethod - Under Method Request, set the Authorization type to
Lambdaand select your authorizer function - Enable Lambda Proxy Integration in the integration settings—this ensures the request body is passed to the Lambda in
event.body
Method 2: JWT Authorizer + Request Validator (Simpler for Basic Checks)
If you're already using API Gateway's built-in JWT authorizer, you can map the sub claim to a context variable and use a JSON Schema validator to enforce the match.
Step 1: Configure JWT Authorizer Context Mapping
- Create or edit your JWT authorizer in API Gateway
- Under Context, add a mapping:
requestedUserId→$context.authorizer.claims.sub - This passes the JWT's
subvalue to a context variable the validator can access
Step 2: Create a JSON Schema for Request Validation
Write a schema that requires the userid field to exactly match the requestedUserId context variable:
{ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "userid": { "type": "string", "const": "${requestedUserId}" } // Add other required request body fields here }, "required": ["userid"] }
Step 3: Attach the Validator to Your API Method
- In API Gateway, create a new Request Validator and associate it with your JSON Schema
- Under the POST
/v1/detailsmethod's Method Request, select this validator to enforce the request body check
Important Notes for This Method
- This only works for exact string matches
- Ensure your JWT authorizer is properly configured to validate the token's signature, expiration, audience, and issuer before the context variable is set
Key Security Best Practices
- Always validate the full JWT (signature, expiration, audience, issuer) before checking the
userid/submatch—don't skip this step - Handle edge cases like missing
useridin the request body or invalid JWTs gracefully - Log mismatches for auditing purposes to track potential spoof attempts
内容的提问来源于stack exchange,提问作者raaone7

