Skip to content

Instantly share code, notes, and snippets.

@inaiat
Created April 25, 2020 16:50
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save inaiat/63a7525dbcf7c8824e7dc1a58927c0ef to your computer and use it in GitHub Desktop.
Save inaiat/63a7525dbcf7c8824e7dc1a58927c0ef to your computer and use it in GitHub Desktop.
Setting request headers with values from a JWT
apiVersion: "security.istio.io/v1beta1"
kind: RequestAuthentication
metadata:
name: echoserver
namespace: default
spec:
selector:
matchLabels:
app: echoserver
jwtRules:
- issuer: "https://securetoken.google.com/<<YOUR_COMPANY>>"
jwksUri: "https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com"
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: echoserver
namespace: default
spec:
selector:
matchLabels:
app: echoserver
action: ALLOW
rules:
- to:
- operation:
paths: ["*"]
from:
- source:
requestPrincipals: ["*"]
when:
- key: request.auth.claims[iss]
values: ["https://securetoken.google.com/<<YOUR_COMPANY>>"]
- to:
- operation:
paths: ["/status"]
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: envoytest
namespace: default
spec:
workloadLabels:
app: echoserver
filters:
- listenerMatch:
portNumber: 80
listenerType: SIDECAR_INBOUND
listenerProtocol: HTTP
filterName: envoy.lua
filterType: HTTP
filterConfig:
inlineCode: |
-- Json Parsing based on https://gist.github.com/tylerneylon/59f4bcf316be525b30ab
-- See modified script on https://gist.github.com/inaiat/02bf5d11732d8e4d7b7546399a3a49af
local a='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'local function b(c)if c>64 then error("Bad number "..c.." to convert to binary")end;local d=tonumber(c)local e=''for f=5,0,-1 do local g=2^f;if d>=g then e=e..'1'd=d-g else e=e..'0'end end;return e end;local function h(e)return tonumber(e,2)end;local function i(j)local k=''local l=''for f=1,string.len(j)do local m,n=string.find(a,string.sub(j,f,f))if m==nil then error("Bad base64 character "..string.sub(j,f,f))end;k=k..b(m-1)end;for f=1,string.len(k),8 do l=l..string.char(h(string.sub(k,f,f+7)))end;return l end;local o={}local function p(q,r,s,t)r=r+#q:match('^%s*',r)if q:sub(r,r)~=s then if t then error('Expected '..s..' near position '..r)end;return r,false end;return r+1,true end;local function u(q,r,v)v=v or''local w='End of input found while parsing string.'if r>#q then error(w)end;local x=q:sub(r,r)if x=='"'then return v,r+1 end;if x~='\\'then return u(q,r+1,v..x)end;local y={b='\b',f='\f',n='\n',r='\r',t='\t'}local z=q:sub(r+1,r+1)if not z then error(w)end;return u(q,r+2,v..(y[z]or z))end;local function A(q,r)local B=q:match('^-?%d+%.?%d*[eE]?[+-]?%d*',r)local v=tonumber(B)if not v then error('Error parsing number at position '..r..'.')end;return v,r+#B end;o.null={}function o.parse(q,r,C)r=r or 1;if r>#q then error('Reached unexpected end of input.')end;local r=r+#q:match('^%s*',r)local D=q:sub(r,r)if D=='{'then local E,F,G={},true,true;r=r+1;while true do F,r=o.parse(q,r,'}')if F==nil then return E,r end;if not G then error('Comma missing between object items.')end;r=p(q,r,':',true)E[F],r=o.parse(q,r)r,G=p(q,r,',')end elseif D=='['then local H,v,G={},true,true;r=r+1;while true do v,r=o.parse(q,r,']')if v==nil then return H,r end;if not G then error('Comma missing between array items.')end;H[#H+1]=v;r,G=p(q,r,',')end elseif D=='"'then return u(q,r+1)elseif D=='-'or D:match('%d')then return A(q,r)elseif D==C then return nil,r+1 else local I={['true']=true,['false']=false,['null']=o.null}for J,K in pairs(I)do local L=r+#J-1;if q:sub(r,L)==J then return K,L+1 end end;local M='position '..r..': '..q:sub(r,r+10)error('Invalid json syntax starting at '..M)end end;local function decode_jwt(O)local f=0;local P={}for Q in(O..'.'):gmatch("(.-)%.")do P[f]=i(Q)f=f+1 end;local R=o.parse(P[0])local S=o.parse(P[1])return{head=R,claims=S}end
function envoy_on_request(request_handle)
request_handle:logInfo("envoy request: trying to get jwt token")
headers = request_handle:headers()
jwt = headers:get("authorization")
if jwt==null then
request_handle:logWarn("there is is no jwt token")
else
local content = decode_jwt(jwt:sub(8))
local claims = content["claims"]
if claims==nil then
request_handle:logWarn("some problems to get jwt attributes"..jwt)
else
headers:add("x-user-id", content["claims"]["sub"])
headers:add("x-user-name", content["claims"]["name"])
headers:add("x-user-email", content["claims"]["email"])
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment