PageSourceSearch

https://curity.io/component---src-templates-resource-article-js-co…s-phantom-token-mdx-a88fba836e57f414a5ce.js

js curity.io collected 2026-10-01 11:38:54 UTC 13,770 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkcurity_website=self.webpackChunkcurity_website||[]).push([[3039],{35705:function(e,t,n){var i=n(74848),r=n(28453),o=n(5227);function s(e){return(0,i.jsx)(o.r,{target:"_blank",rel:"noopener noreferrer",href:"https://oauth.tools/?utm_source=curity.io&utm_medium=Link&utm_content={props.utmContent}",children:"OAuth Tools"})}t.A=function(e={}){const{wrapper:t}=Object.assign({},(0,r.RP)(),e.components);return t?(0,i.jsx)(t,Object.assign({},e,{children:(0,i.jsx)(s,e)})):s()}},44204:function(e,t,n){n.r(t),n.d(t,{Head:function(){return w},default:function(){return A}});var i=n(54506),r=n(74848),o=n(28453),s=n(5227),a=n(96370),h=n(50827),c=n(43745),l=n(35705);function d(e){const t=Object.assign({p:"p",h2:"h2",ul:"ul",li:"li",code:"code",h3:"h3",strong:"strong",ol:"ol",img:"img"},(0,o.RP)(),e.components);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(t.p,{children:["The AWS API Gateway is very capable and can also be extended to leverage Lambda functions. More specifically custom ",(0,r.jsx)(s.r,{rel:"noopener noreferrer",href:"https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html",children:"Lambda Authorizers"})," can be configured in order to protect configured APIs."]}),"\n",(0,r.jsxs)(t.p,{children:["This article describes how to deploy and configure a custom Lambda Authorizer and how to configure an API to make use of that custom Lambda Authorizer to achieve the ",(0,r.jsx)(a.A,{file:"api-security/phantom-token-pattern.mdx",children:"Phantom Token Pattern"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The details of the ",(0,r.jsx)(a.A,{file:"api-security/introspect-with-phantom-token.mdx",children:"OAuth Introspection and Phantom Tokens"})," is a useful read before diving fully into how to set up this integration."]}),"\n",(0,r.jsx)(t.h2,{children:"Prerequisites"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"An installation of the Curity Identity Server"}),"\n",(0,r.jsx)(t.li,{children:"Basic understanding of the AWS ecosystem and especially the API Gateway and Lambda functions."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["If you do not have an installation of the Curity Identity Server, follow this tutorial ",(0,r.jsx)(a.A,{file:"getting-started/setup/run-curity-docker.mdx",children:"installation of the Curity Identity Server"})," and configure the installation by running Curity Basic Setup Wizard as outlined in this tutorial ",(0,r.jsx)(a.A,{file:"getting-started/first-config.mdx",children:"Curity Basic Setup Wizard"}),"."]}),"\n",(0,r.jsx)(t.h2,{children:"Configure the Curity Identity Server"}),"\n",(0,r.jsxs)(t.p,{children:["The Curity Identity Server needs to be set up to handle introspection. This is the case by default but review the configuration of the system in use before continuing. This article assumes that the Curity Identity Server is set up to handle the ",(0,r.jsx)(t.code,{children:"application/jwt"})," approach of introspection as outlined in the ",(0,r.jsx)(a.A,{file:"api-security/introspect-with-phantom-token.mdx",children:"OAuth Introspection and Phantom Tokens"})," article."]}),"\n",(0,r.jsx)(t.h2,{children:"Build, Deploy and Configure the Lambda Authorizer Function"}),"\n",(0,r.jsxs)(t.p,{children:["The code for the ",(0,r.jsx)(s.r,{rel:"noopener noreferrer",href:"https://github.com/curityio/aws-phantom-token-lambda-authorizer\n",children:"Curity AWS Phantom Token Lambda Authorizer"})," function is available in the GitHub repository. Full details on building, deploying and configuring the Lambda Authorizer function itself is outlined in the ",(0,r.jsx)(s.r,{rel:"noopener noreferrer",href:"https://github.com/curityio/aws-phantom-token-lambda-authorizer/blob/main/README.md",children:"readme"}),"."]}),"\n",(0,r.jsx)(t.h3,{children:"Create & Configure the Authorizer"}),"\n",(0,r.jsx)(t.p,{children:"With the Lambda Authorizer function configured an Authorizer to be used by the AWS API Gateway can be configured."}),"\n",(0,r.jsxs)(t.p,{children:["In the AWS Management Console, go to ",(0,r.jsx)(t.strong,{children:"API Gateway"}),", choose the API to protect or create a new API."]}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["Select ",(0,r.jsx)(t.strong,{children:"Authorizers"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Click ",(0,r.jsx)(t.strong,{children:"Create New Authorizer"})]}),"\n",(0,r.jsxs)(t.li,{children:["Give it a name, ex. ",(0,r.jsx)(t.code,{children:"curity-authorizer"})]}),"\n",(0,r.jsxs)(t.li,{children:["Make sure the type is set to ",(0,r.jsx)(t.strong,{children:"Lambda"})]}),"\n",(0,r.jsxs)(t.li,{children:["Under the ",(0,r.jsx)(t.strong,{children:"Lambda Function"})," section, make sure the correct ",(0,r.jsx)(t.strong,{children:"Zone"})," is selected, the previously configured Lambda Authorizer with the name ",(0,r.jsx)(t.code,{children:"curity-phantom-token-authorizer"})," should be available in the text field"]}),"\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.strong,{children:"Lambda Event Payload"})," section choose ",(0,r.jsx)(t.code,{children:"Token"})]}),"\n",(0,r.jsxs)(t.li,{children:["For the ",(0,r.jsx)(t.strong,{children:"Token Source"}),", enter ",(0,r.jsx)(t.code,{children:"Authorization"})," in the field"]}),"\n",(0,r.jsxs)(t.li,{children:["If ",(0,r.jsx)(t.strong,{children:"Authorization Caching"})," is left enabled the API Gateway will not invoke the Lambda function if the same Authorization header is used within the time span of the cache configuration (300 seconds by default)","\n",(0,r.jsx)(h.A,{theme:"light",columns:"1",images:[{id:1,title:"Create API Authorizer",path:"/images/resources/howtos/gateway/aws-api-gw/create-api-authorizer.jpg"}]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["Click ",(0,r.jsx)(t.strong,{children:"Create authorizer"})]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{children:"Configure API"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["For the API to protect, go to ",(0,r.jsx)(t.strong,{children:"Resources"})]}),"\n",(0,r.jsx)(t.li,{children:"Select the Resource and the Method to protect"}),"\n",(0,r.jsxs)(t.li,{children:["Click ",(0,r.jsx)(t.strong,{children:"Method Request"})]}),"\n",(0,r.jsxs)(t.li,{children:["Click ",(0,r.jsx)(t.strong,{children:"Edit"}),". For ",(0,r.jsx)(t.strong,{children:"Authorization"}),", choose the previously created Authorizer, ",(0,r.jsx)(t.code,{children:"curity-authorizer"})]}),"\n",(0,r.jsxs)(t.li,{children:["Click ",(0,r.jsx)(t.strong,{children:"Save"})]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(c.A,{kind:"note",title:"Authorizer not available?",children:"The drop-down list is populated when the API method is created. If the Authorizer does not show up, delete the method, re-create it and the Authorizer should show up."}),"\n",(0,r.jsx)(t.img,{src:"/images/resources/howtos/gateway/aws-api-gw/select-authorizer.jpg",alt:"Select Authorizer"})]}),"\n",(0,r.jsxs)(t.ol,{start:"6",children:["\n",(0,r.jsxs)(t.li,{children:["Go to the ",(0,r.jsx)(t.strong,{children:"Integration Request"})," tab and click ",(0,r.jsx)(t.strong,{children:"Edit"})]}),"\n",(0,r.jsxs)(t.li,{children:["Make sure the ",(0,r.jsx)(t.strong,{children:"Integration type"})," is set to ",(0,r.jsx)(t.code,{children:"HTTP"})]}),"\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.strong,{children:"URL request headers parameters"})," section, click ",(0,r.jsx)(t.strong,{children:"Add request header parameter"}),", for ",(0,r.jsx)(t.strong,{children:"Name"})," enter ",(0,r.jsx)(t.code,{children:"Authorization"})," and for ",(0,r.jsx)(t.strong,{children:"Mapped from"})," enter ",(0,r.jsx)(t.code,{children:"context.authorizer.Authorization"}),". Save and enable Caching as needed. This will pass the JWT from the introspection response in the upstream API Authorization header so that the API can consume the JWT.\n",(0,r.jsx)(t.img,{src:"/images/resources/howtos/gateway/aws-api-gw/forward-jwt.jpg",alt:"Add Authorization Header"})]}),"\n"]}),"\n",(0,r.jsx)(c.A,{kind:"note",title:"Deploy the changes",children:(0,r.jsxs)(t.p,{children:["Make sure to deploy the API now that the Authorizer has been added, click ",(0,r.jsx)(t.code,{children:"Deploy API"}),"."]})}),"\n",(0,r.jsx)(t.h3,{children:"Policy Document Paths"}),"\n",(0,r.jsxs)(t.p,{children:["The Curity AWS Phantom Token Lambda Authorizer is by default co
1ded to generate wildcard IAM policies to be able to handle multiple API paths. This handles an issue that is outlined in the ",(0,r.jsx)(s.r,{rel:"noopener noreferrer",href:"https://forum.serverless.com/t/help-really-weird-access-denied-issue/12676/6",children:"Serverless Forum"})," forum."]}),"\n",(0,r.jsxs)(t.p,{children:["On row ",(0,r.jsx)(s.r,{rel:"noopener noreferrer",href:"https://github.com/curityio/aws-phantom-token-lambda-authorizer/blob/main/index.js#L62",children:"62 in index.js"}),", the ",(0,r.jsx)(t.code,{children:"getServiceArn"})," method is called. This will strip the specific path and add a wildcard instead allowing the IAM policy to be applied to other methods and paths of the API. If this behavior is not desired, comment out row 62 and uncomment row ",(0,r.jsx)(s.r,{rel:"noopener noreferrer",href:"https://github.com/curityio/aws-phantom-token-lambda-authorizer/blob/main/index.js#L63",children:"63"}),"."]}),"\n",(0,r.jsx)(t.h2,{children:"Test Using OAuth Tools"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["In ",(0,r.jsx)(l.A,{}),", create a flow to obtain an Access Token."]}),"\n",(0,r.jsxs)(t.li,{children:["Create a ",(0,r.jsx)(t.strong,{children:"Call External API"})," flow. Enter the URL for the AWS API Gateway exposed API. Configure the method according to what’s possible with the API. Select the token retrieved in the previous step from the drop-down list and click ",(0,r.jsx)(t.strong,{children:"Send"}),"."]}),"\n"]}),"\n",(0,r.jsx)(h.A,{theme:"light",columns:"2",images:[{id:1,title:"Obtain Access Token",path:"/images/resources/howtos/gateway/aws-api-gw/ot-obtain-at.png"},{id:2,title:"Call AWS API Gateway",path:"/images/resources/howtos/gateway/aws-api-gw/ot-call-api.png"}]}),"\n",(0,r.jsx)(t.h2,{children:"Resources"}),"\n",(0,r.jsx)(t.p,{children:"Useful resources that cover the topics of this article."}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["An article on ",(0,r.jsx)(a.A,{file:"api-security/introspect-with-phantom-token.mdx",children:"OAuth Introspection and Phantom Tokens"})]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(s.r,{rel:"noopener noreferrer",href:"https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html",children:"AWS Lambda Authorizers"}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(s.r,{rel:"noopener noreferrer",href:"https://aws.amazon.com/api-gateway/",children:"AWS API Gateway"}),"\n"]}),"\n"]})]})}var u=function(e={}){const{wrapper:t}=Object.assign({},(0,o.RP)(),e.components);return t?(0,r.jsx)(t,Object.assign({},e,{children:(0,r.jsx)(d,e)})):d(e)},p=n(55096),m=n(6859),g=n(77528),x=n(63351),j=n(96540),f=n(32413);function y({data:{mdx:e},children:t}){const{frontmatter:n,internal:i}=e,{contentFilePath:r}=e.internal,o=(0,f.au)(r);return j.createElement(j.Fragment,null,j.createElement(m.A,{showArticleSidebarNav:!0,contentType:n.topic}),j.createElement(x.A),j.createElement(p.c,{articleSlug:o,frontmatter:n,children:t,path:i.contentFilePath}))}function A(e){return j.createElement(y,e,j.createElement(u,e))}const w=({data:{mdx:e},location:t})=>{const{frontmatter:n}=e,{contentFilePath:r}=e.internal,o=(0,f.au)(r),s=n.sharing_image?n.sharing_image:"/images/open-graph/homepage-sharing-image.jpg",a={"@context":"https://schema.org","@type":"TechArticle",mainEntityOfPage:{"@type":"WebPage","@id":`https://curity.io${o}`},headline:n.title,image:[`https://curity.io${s}`],datePublished:n.created||n.date,dateModified:n.date,...n.keywords?{keywords:n.keywords}:{},author:(0,f.fy)(n.author),url:`https://curity.io${o}`,description:n.description,publisher:{"@type":"Organization","@id":"https://curity.io/#organization"}},h=n.faq?{"@context":"https://schema.org","@type":"FAQPage",mainEntity:n.faq.map(e=>({"@type":"Question",name:e.question,acceptedAnswer:{"@type":"Answer",text:e.answer}}))}:null,c=Array.isArray(n.howto_steps)?n.howto_steps.filter(e=>e&&e.name&&e.text):[],l=(e=>{if(!e||"string"!=typeof e)return;const t=e.match(/(\d+)\s*(hour|hr|h|minute|min|m)/i);if(!t)return;const n=parseInt(t[1],10);if(Number.isNaN(n))return;return t[2].toLowerCase().startsWith("h")?`PT${n}H`:`PT${n}M`})(n.time),d=c.length>=2?{"@context":"https://schema.org","@type":"HowTo",name:n.title,de
1scription:n.description,...n.sharing_image?{image:`https://curity.io${n.sharing_image}`}:{},...l?{totalTime:l}:{},step:c.map((e,t)=>({"@type":"HowToStep",position:t+1,name:e.name,text:e.text,...e.url?{url:e.url.startsWith("#")?`https://curity.io${o}${e.url}`:e.url}:{}}))}:null,u={"@context":"https://schema.org","@type":"BreadcrumbList",itemListElement:[{"@type":"ListItem",position:1,name:"Home",item:"https://curity.io/"},{"@type":"ListItem",position:2,name:"Resources",item:"https://curity.io/resources/"},{"@type":"ListItem",position:3,name:n.title,item:`https://curity.io${o}`}]},p=[a].concat((0,i.A)(d?[d]:[]),[u],(0,i.A)(h?[h]:[]));return j.createElement(g.A,{title:null!==n.seo_title?n.seo_title:n.title,description:n.description,image:s,schemaMarkup:p,bodyClass:"resources  ",pathname:t.pathname})}},96370:function(e,t,n){var i=n(24794),r=(n(96540),n(32413)),o=n(74848);t.A=({file:e,anchor:t=null,children:n,tooltip:s=null,...a})=>{const h=e.split("/").pop(),c=null!=t?`#${t}`:"",l=-1===h.lastIndexOf(".")?h+".mdx":h,d=`${(0,r.au)(l)}${c}`;return(0,o.jsx)(i.Link,{to:d,className:"ref ref-cross","data-tooltip":s,...a,children:n})}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.