Description
AWS allows authenticating a user through their ALB, and forwards JWT on the header x-amzn-oidc-data
containing user data, which is encoded with ECDSA + P-256 + SHA256 by the ALB
Unfortunately it's incorrectly encoded using base64url with padding characters included, and so signature verification fails when using JOSE library (as the signing input was constructed WITH padding, just removing the padding from the JWT doesn't work)
Ideally they'd fix their encoding to remove the padding, but it looks like it's been 5 years with this issue, so I don't have very high hopes
Would it be possible to support this encoding (Maybe somewhere in JWS.verify check if padding is included, and if so construct the signing input differently here https://github.com/potatosalad/erlang-jose/blob/main/src/jws/jose_jws.erl#L371?)
If not, here's the workaround that I'm using for now. Hopefully can help someone else that encounters the same issue!
#data from x-amzn-oidc-data header, key from "https://public-keys.auth.elb." <> aws_region <> ".amazonaws.com/" <> kid
[header, payload, signature] = String.split(data, ".") |> Enum.map(fn part -> :jose_jwa_base64url.decode(part) end)
signing_input = Base.url_encode64(header) <> "." <> Base.url_encode64(payload)
encoded_key = key |> JOSE.JWK.from_pem() |> JOSE.JWK.to_record()
:jose_jws_alg_ecdsa.verify(encoded_key, signing_input, signature, :ES256)
Relevant discussions
auth0/node-jws#84
https://stackoverflow.com/questions/60246585/unable-to-verify-jwt-coming-from-aws-alb-authentication
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html