JWT オーソライザーを使用した HTTP API へのアクセスの制御 - Amazon API Gateway

JWT オーソライザーを使用した HTTP API へのアクセスの制御

OpenID Connect (OIDC) および OAuth 2.0 フレームワークの一部として JSON ウェブトークン (JWT) を使用して、API へのクライアントアクセスを制限できます。

API のルートに JWT オーソライザーを設定する場合、API Gateway はクライアントが API リクエストとともに送信する JWT を検証します。API Gateway は、トークンの検証、およびオプションでトークン内のスコープに基づいてリクエストを許可または拒否します。ルートのスコープを設定する場合、ルートのスコープを 1 つ以上、トークンに含める必要があります。

API の各ルートに個別のオーソライザーを設定することも、複数のルートに同じオーソライザーを使用することもできます。

注記

JWT アクセストークンを OpenID Connect ID トークンなど他のタイプの JWT と区別する標準的なメカニズムはありません。API 認証に ID トークンが必要でない限り、認可スコープを要求するようにルートを設定することをお勧めします。また、JWT アクセストークンを発行するときにのみ ID プロバイダーが使用する発行者または対象者を要求するように JWT オーソライザーを設定することもできます。

JWT オーソライザーによる API リクエストの承認

API Gateway は、次の一般的なワークフローを使用して、JWT オーソライザーを使用するように設定されたルートへの要求を承認します。

  1. identitySource でトークンを確認します。identitySource には、トークンのみを含めるか、Bearer のプレフィックスが付いたトークンのみを含めることができます。

  2. トークンをデコードします。

  3. 発行者の jwks_uri から取得したパブリックキーを使用して、トークンのアルゴリズムと署名を確認します。現在、RSA ベースのアルゴリズムのみがサポートされています。API Gateway は、パブリックキーを 2 時間キャッシュできます。ベストプラクティスとして、キーをローテーションするときは、古いキーと新しいキーの両方が有効な猶予期間を設けてください。

  4. クレームを検証します。API Gateway は、次のトークンクレームを評価します。

    • kid – トークンには、トークンに署名した jwks_uri のキーと一致するヘッダークレームが必要です。

    • iss – オーソライザーに設定された issuer と一致する必要があります。

    • aud または client_id – オーソライザーに設定された audience エントリの 1 つと一致する必要があります。API Gateway は、aud が存在しない場合にのみ、client_id を検証します。audclient_id の両方が存在する場合、API Gateway は aud を評価します。

    • exp – UTC の現在時刻より後にする必要があります。

    • nbf – UTC の現在時刻より前にする必要があります。

    • iat – UTC の現在時刻より前にする必要があります。

    • scope または scp – トークンには、ルートの authorizationScopes のスコープを少なくとも 1 つ含める必要があります。

これらのいずれかの手順が失敗した場合、API Gateway は API リクエストを拒否します。

API Gateway は JWT を検証した後、トークン内のクレームを API ルートの統合に渡します。JWT クレームには、Lambda 関数などのバックエンドリソースがアクセスできます。例えば、JWT に ID クレーム emailID が含まれている場合、$event.requestContext.authorizer.jwt.claims.emailID で Lambda 統合に使用できます。API Gateway が Lambda 統合に送信するペイロードの詳細については、「HTTP API の AWS Lambda プロキシ統合の使用」を参照してください。

JWT オーソライザーを作成する

JWT オーソライザーを作成する前に、クライアントアプリケーションを ID プロバイダーに登録する必要があります。また、HTTP API を作成しておく必要があります。HTTP API の作成例については、「HTTP API の作成」を参照してください。

コンソールを使用して JWT オーソライザーを作成する

次の手順は、コンソールを使用して JWT オーソライザーを作成する方法を示しています。

コンソールを使用して JWT オーソライザーを作成するには
  1. https://console.aws.amazon.com/apigateway で API Gateway コンソールにサインインします。

  2. HTTP API を選択します。

  3. メインナビゲーションペインで、[認可] を選択します。

  4. [オーソライザーを管理] タブを選択します。

  5. [Create] (作成) を選択します。

  6. [オーソライザーのタイプ] で、[JWT] を選択します。

  7. JWT オーソライザーを設定し、トークンのソースを定義する ID ソースを指定します。

  8. [Create] (作成) を選択します。

AWS CLI を使用して JWT オーソライザーを作成する

次の AWS CLI コマンドは、JWT オーソライザーを作成します。jwt-configuration には、ID プロバイダーの AudienceIssuer を指定します。Amazon Cognito を ID プロバイダーとして使用する場合、IssuerUrlhttps://cognito-idp.us-east-2.amazonaws.com/userPoolID です。

aws apigatewayv2 create-authorizer \ --name authorizer-name \ --api-id api-id \ --authorizer-type JWT \ --identity-source '$request.header.Authorization' \ --jwt-configuration Audience=audience,Issuer=IssuerUrl
AWS CloudFormation を使用して JWT オーソライザーを作成する

次の AWS CloudFormation テンプレートでは、Amazon Cognito を ID プロバイダーとして使用する JWT オーソライザーで HTTP API を作成します。

AWS CloudFormation テンプレートの出力は、クライアントがサインアップ/サインインして JWT を受け取ることができる、Amazon Cognito がホストする UI の URL です。クライアントは、サインインすると、URL のアクセストークンにより、HTTP API にリダイレクトされます。アクセストークンを使用して API を呼び出すには、URL の #? に変更し、トークンをクエリ文字列パラメータとして使用します。

AWSTemplateFormatVersion: '2010-09-09' Description: | Example HTTP API with a JWT authorizer. This template includes an Amazon Cognito user pool as the issuer for the JWT authorizer and an Amazon Cognito app client as the audience for the authorizer. The outputs include a URL for an Amazon Cognito hosted UI where clients can sign up and sign in to receive a JWT. After a client signs in, the client is redirected to your HTTP API with an access token in the URL. To invoke the API with the access token, change the '#' in the URL to a '?' to use the token as a query string parameter. Resources: MyAPI: Type: AWS::ApiGatewayV2::Api Properties: Description: Example HTTP API Name: api-with-auth ProtocolType: HTTP Target: !GetAtt MyLambdaFunction.Arn DefaultRouteOverrides: Type: AWS::ApiGatewayV2::ApiGatewayManagedOverrides Properties: ApiId: !Ref MyAPI Route: AuthorizationType: JWT AuthorizerId: !Ref JWTAuthorizer JWTAuthorizer: Type: AWS::ApiGatewayV2::Authorizer Properties: ApiId: !Ref MyAPI AuthorizerType: JWT IdentitySource: - '$request.querystring.access_token' JwtConfiguration: Audience: - !Ref AppClient Issuer: !Sub https://cognito-idp.${AWS::Region}.amazonaws.com/${UserPool} Name: test-jwt-authorizer MyLambdaFunction: Type: AWS::Lambda::Function Properties: Runtime: nodejs18.x Role: !GetAtt FunctionExecutionRole.Arn Handler: index.handler Code: ZipFile: | exports.handler = async (event) => { const response = { statusCode: 200, body: JSON.stringify('Hello from the ' + event.routeKey + ' route!'), }; return response; }; APIInvokeLambdaPermission: Type: AWS::Lambda::Permission Properties: FunctionName: !Ref MyLambdaFunction Action: lambda:InvokeFunction Principal: apigateway.amazonaws.com SourceArn: !Sub arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${MyAPI}/$default/$default FunctionExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - 'sts:AssumeRole' ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole UserPool: Type: AWS::Cognito::UserPool Properties: UserPoolName: http-api-user-pool AutoVerifiedAttributes: - email Schema: - Name: name AttributeDataType: String Mutable: true Required: true - Name: email AttributeDataType: String Mutable: false Required: true AppClient: Type: AWS::Cognito::UserPoolClient Properties: AllowedOAuthFlows: - implicit AllowedOAuthScopes: - aws.cognito.signin.user.admin - email - openid - profile AllowedOAuthFlowsUserPoolClient: true ClientName: api-app-client CallbackURLs: - !Sub https://${MyAPI}.execute-api.${AWS::Region}.amazonaws.com ExplicitAuthFlows: - ALLOW_USER_PASSWORD_AUTH - ALLOW_REFRESH_TOKEN_AUTH UserPoolId: !Ref UserPool SupportedIdentityProviders: - COGNITO HostedUI: Type: AWS::Cognito::UserPoolDomain Properties: Domain: !Join - '-' - - !Ref MyAPI - !Ref AppClient UserPoolId: !Ref UserPool Outputs: SignupURL: Value: !Sub https://${HostedUI}.auth.${AWS::Region}.amazoncognito.com/login?client_id=${AppClient}&response_type=token&scope=email+profile&redirect_uri=https://${MyAPI}.execute-api.${AWS::Region}.amazonaws.com

JWT オーソライザーを使用するようにルートを更新する

JWT オーソライザーを使用するようにルートを更新するには、コンソール、AWS CLI、または AWS SDK を使用できます。

コンソールを使用して、JWT オーソライザーを使用するようにルートを更新する

次の手順では、コンソールを使用して、JWT オーソライザーを使用するようにルートを更新する方法を示します。

コンソールを使用して JWT オーソライザーを作成するには
  1. https://console.aws.amazon.com/apigateway で API Gateway コンソールにサインインします。

  2. HTTP API を選択します。

  3. メインナビゲーションペインで、[認可] を選択します。

  4. メソッドを選択し、ドロップダウンメニューからオーソライザーを選択して、[オーソライザーをアタッチ] を選択します。

AWS CLI を使用して、JWT オーソライザーを使用するようにルートを更新する

次のコマンドでは、AWS CLI を使用して、JWT オーソライザーを使用するようにルートを更新します。

aws apigatewayv2 update-route \ --api-id api-id \ --route-id route-id \ --authorization-type JWT \ --authorizer-id authorizer-id \ --authorization-scopes user.email