-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Seamlessly Integrate Quarkus/smallrye-jwt with AWS Application Load Balancer (ALB) #34300
Comments
/cc @Ladicek (smallrye), @jmartisk (smallrye), @phillip-kruger (smallrye), @radcortez (smallrye), @sberyozkin (jwt) |
Hi @AdamBien Thanks for opening this issue. I'm not sure right now what is the best way to handle it because JWT signature verification is all about following the JOSE JWS signature verification process - where base64url encoding is essential, in case of and I'd rather a dedicated JOSE library (jose4j in Quarkus's case) handle it - I did that code myself awhile back in another project, indeed, using Java primitives, but now I'd prefer jose4j do it which has some fine checks about correct elliptic curves etc. I'll need to have a look if we can ask Jose4j to verify the already decoded headers/payload, the solution I have in mind is to have a custom AWS factory: https://quarkus.io/guides/security-jwt#custom-factories and ship a dedicated smallrye-jwt-aws module with this factory. I'll experiment and see what we can do about it Cheers |
A good idea! A dedicated extension would be even more convenient, and we could rely more on conventions and streamline the configuration. |
@AdamBien For the moment I was thinking of having an extra module or some kind of customization support at the smallrye-jwt level, I haven't thought yet about a dedicated Quarkus extension (in Quarkiverse). Supporting a custom key resolver would likely make sense as there are cases like Google Firebase etc. Can I clarify something before we try to do something about this case, can it be the case such a token has already been verified at the AWS ALB level, before it reaches Quarkus ? |
@AdamBien I have a unit test where this token is successfully verified: (so the only outstanding issue is a dynamic key resolution, but we might not even require users register a custom key resolver, but simply add a dedicated key format property like AWS_ALB_PEM or something like that to give smallryw-jwt a hint that the the configured key location has to be concatenated with Jose4j is not worried about This is somewhat unexpected though: @b---c, Hi, can you please clarify, I think it is not a problem that jose4j can consume JWS sequences where parts are Base64 encoded as the padding characters are not affecting the signature verification. Thanks |
The ALB documentation notes (https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html):
|
You mean: "the configured key location has to be
|
A minimal AWS configuration in the stock smallrye-jwt is even better. A "core" extension is more trustworthy and easier to maintain. |
:@b---c, sorry, the padding characters in headers and the body are verified, it is only in the signature part they make no difference, which is totally fine since it is just an envelope for the signature part, somehow I got confused, thanks |
@AdamBien FYI, smallrye/smallrye-jwt#707. As far as the padding characters are concerned, all is good, here is copy of what I've typed there: Note the token parts have been Base64 encoded, as opposed to Base64Url encoded, thus extra padding characters are added to the header and body and signature parts. As far as the the header and body integrity verification is concerned, it makes no difference because the padding characters are included in the signing input - while for the signature it does not matter if its encoded form has extra padding characters or not - since the decoded signature is compared against the recalculated signature with the headers and body parts included in the signing input. Base64-only encoded tokens introduce an interoperability problem - i.e not all libraries can consume such tokens - but it is not a problem of Jose4j - rather it is a problem of AWS ALB whose tokens may not be verified by all JOSE libraries (example, the warning from JWT.io). Such tokens are also not URI friendly, as (CC @b---c - please correct if something above is not precise) Thanks |
@sberyozkin I just wanted capture your idea:
From the user perspective, the property above would introduce a "switch," enabling the dynamic key resolution mechanism and, if necessary, a special treatment for the non-standard JWT encoding. This would significantly increase the user's (developer's) experience. |
@AdamBien Thanks, indeed, it looks it can be much simpler to let users set a property and have it working, as opposed to add another module bringing custom verification key resolution logic. |
Description
The AWS Application Load Balancer (ALB) can authenticate users through an identity provider (IdP) that is OpenID Connect (OIDC) compliant (https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html).
However, the AWS Application Load Balancer (ALB) creates invalid JWTs and requires dynamic public key lookups from the kid header. See documentation: (https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html#user-claims-encoding):
"...
Considerations
Standard libraries are not compatible with the padding that is included in the Application Load Balancer authentication token in JWT format.
..."
Token example:
Problem:
Each section ends with an unnecessary padding character, which yields the JWT invalid.
Warnings from jwt.io:
Your JWT signature is not encoded correctly using base64url (https://tools.ietf.org/html/rfc4648#section-5). Note that padding ("=") must be omitted as per https://tools.ietf.org/html/rfc7515#section-2
Your JWT header is not encoded correctly using base64url (https://tools.ietf.org/html/rfc4648#section-5). Note that padding ("=") must be omitted as per https://tools.ietf.org/html/rfc7515#section-2
Your JWT payload is not encoded correctly using base64url (https://tools.ietf.org/html/rfc4648#section-5). Note that padding ("=") must be omitted as per https://tools.ietf.org/html/rfc7515#section-2
Implementation ideas
To make smallrye-jwt work with alb, the following issues have to be resolved:
(minor) The public key has to be looked up dynamically and fetched from the ALB. Quarkus configuration is static and set at build time.
mp.jwt.verify.publickey.location=https://public-keys.auth.elb.eu-central-1.amazonaws.com/[fetch from kid header]
The "kid" resides in the first JWT section (header):
{ "typ": "JWT", "kid": "XXXX-a34d-4255-a779-YYYYYYY", ... }
The key does not change frequently and can be "hardcoded" for evaluation purposes.
(primary) The format of the JWT token issued by the ALB is invalid:
from AWS / ALB documentation: The JWT Signature and the JWT Header contain a padding character "=" which is not allowed by the spec.
Possible solution:
Parse JWT header
Obtain the kid value
Use the value to fetch (and cache) the public key with Java HTTP client: GET https://public-keys.auth.elb.eu-central-1.amazonaws.com/[kid value]
Verify the signature with Java built-in functionality
Remove the padding ("=") characters
Use e.g. Smallrye JWT to parse the token and use the principal/claims.
The extension of the MP / Smallrye JWT (Quarkus) mechanism (quarkus-smallrye-jwt extension) itself would seamlessly integrate ECS (Fargate), EKS, AWS Lambda applications running on quarkus with ALB OIDC functionality. This direct integration increases security, developer experience, and maintainability.
The text was updated successfully, but these errors were encountered: