透過閘道中HTTPAPIsAPI的JWT授權者控制存取 - Amazon API Gateway

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

透過閘道中HTTPAPIsAPI的JWT授權者控制存取

您可以使用JSON網絡令牌(JWTs)作為 OpenID Connect(OIDC)OAuth2.0 框架的一部分來限制客戶端訪問您的APIs.

如果您為您的路由設定JWT授權者API,APIGateway 會驗證用戶端透過要求提交JWTs的用API戶端。APIGateway 根據令牌驗證允許或拒絕請求,並可選擇允許或拒絕令牌中的範圍。如果您設定某個路由的範圍,字符至少必須包含其中一個路由的範圍。

您可以為每個路由配置不同的授權者API,或對多個路由使用相同的授權者。

注意

沒有標準機制可以區分JWT訪問令牌 Connect 其他類型的訪問令牌JWTs,例如 OpenID 令牌。除非您需要 ID 令牌進行API授權,否則我們建議您配置路由以需要授權範圍。您還可以將JWT授權者配置為要求身份提供者僅在發行JWT訪問令牌時使用的發行者或受眾。

向授權者授權API請求 JWT

APIGateway 會使用下列一般工作流程來授權要求,傳送設定為使用授權JWT者的路由。

  1. 檢查權杖的 identitySourceidentitySource 只能包含字符,或字首加上 Bearer 的字符。

  2. 解碼字符

  3. 使用從發行者的 jwks_uri 獲取的公開金鑰檢查字符的演算法和簽章。目前,僅支持RSA基於算法。API閘道器可以快取公開金鑰兩小時。最佳作法是,當您輪換金鑰時,允許寬限期,在此期間,舊金鑰和新金鑰都有效。

  4. 驗證宣告。API網關評估以下令牌聲明:

    • kid – 權杖必須有符合簽署權杖之 jwks_uri 中金鑰的標頭宣告。

    • iss – 必須符合為授權方設定的 issuer

    • audclient_id – 必須符合為授權方設定的其中一個 audience 項目。API閘道client_id僅在不存在時進aud行驗證。當aud和都存client_id在時,API閘道評估aud

    • exp— 必須在中的目前時間之後UTC。

    • nbf— 必須在中的當前時間之前UTC。

    • iat— 必須在中的當前時間之前UTC。

    • scopescp – 權杖至少必須包含路由的 authorizationScopes 的其中一個範圍。

如果其中任何一個步驟失敗,APIGateway 會拒絕要API求。

驗證之後JWT,APIGateway 會將權杖中的宣告傳遞至API路由的整合。後端資源 (例如 Lambda 函數) 可以存取JWT宣告。例如,如果JWT包含身分聲明emailID,則該聲明 Lambda 用於$event.requestContext.authorizer.jwt.claims.emailID. 如需API閘道傳送至 Lambda 整合之承載的詳細資訊,請參閱HTTPAPIs在API閘道中建立 AWS Lambda 代理整合

建立JWT授權者

建立JWT授權者之前,您必須向身分識別提供者註冊用戶端應用程式。您還必須創建了一個 HTTPAPI. 如需建立的範例 HTTPAPI,請參閱創建一個 HTTP API

使用控制台創建JWT授權者

以下步驟顯示如何使用控制台創建JWT授權者。

若要使用主控台建立JWT授權者
  1. 請在 https://console.aws.amazon.com/apigateway 登入API閘道主控台。

  2. 選擇一個 HTTPAPI.

  3. 在主導覽窗格中,選擇 [授權]。

  4. 選擇 [管理授權者] 索引標籤。

  5. 選擇建立

  6. 針對「授權者」類型,選擇JWT

  7. 設定您的JWT授權者,並指定定義權杖來源的身分識別來源。

  8. 選擇建立

使用建立JWT授權者 AWS CLI

下面的 AWS CLI 命令創建一個JWT授權者。對於 jwt-configuration,為您的身分提供者指定 AudienceIssuer。如果您使用 Amazon Cognito 做為身分識別提供者,則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
使用創建JWT授權者 AWS CloudFormation

下列 AWS CloudFormation 範本會建立HTTPAPI具有使用 Amazon Cognito 做為身分識別提供者的JWT授權者。

該 AWS CloudFormation 模板的輸出是 Amazon Cognito 託管的用戶界面,客戶可以在其中註冊並登錄以接收. URL JWT 用戶端登入後,用戶端會使用中的存取權杖重新導向至您HTTPAPI的URL。若要使用API存取權杖叫用,請將#中的變更URL為 a ? 以使用權杖做為查詢字串參數。

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授權者

您可以使用控制台 AWS CLI、或 AWS SDK更新路由以使用JWT授權者。

使用控制台更新路由以使用JWT授權者

下列步驟顯示如何使用主控台更新路由以使用JWT授權者。

若要使用主控台建立JWT授權者
  1. 請在 https://console.aws.amazon.com/apigateway 登入API閘道主控台。

  2. 選擇一個 HTTPAPI.

  3. 在主導覽窗格中,選擇 [授權]。

  4. 選擇方法,然後從下拉式功能表中選取您的授權者,然後選擇 [附加授權者]。

更新路由以使用JWT授權者 AWS CLI

下列指令會更新路由,以使用JWT授權者使用 AWS CLI。

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