In Gravitee 4.2, I'm configuring a V2 API for which I'm extracting the user id from an OAuth2 access token from the incoming request and add an Authorization Basic header to this request with the user:password encoded in base 64 before forwarding it to my backend.
Extracting the user id from the token is working fine using the JSON Web Tokens policy.
To add the Authorization header to the request I'm using the Transform Headers policy. But I cannot manage writing a working Gravitee Expression Language to add the header with the "user:password" part base 64 encoded. And I find it really hard to debug the EL. I didn't find built-in solution to base 64 encode a string.
The documentation states that GEL extends Spring EL but I couldn't find "advanced" example.
I'm trying to use the java.util.Base64
class for the encoding.
This EL doesn't work:
{T(java.util.Base64).getEncoder().encodeToString({T(java.lang.String).valueOf('test:test').getBytes()})}
But this subpart is working. It get the bytes array from the provided String :
{T(java.lang.String).valueOf('test:test').getBytes()}
java.util.Base64
and java.util.Base64$Encoder
).With gravitee.yml
On the gravitee.yml
file of the gateway, you can configure the expression language whitelist in the dedicated section:
el:
# Allows to define which methods or classes are accessible to the Expression Language engine (/!\ caution, changing default whitelist may expose you to security issues).
# A complete list of default whitelist methods can be found here (https://raw.githubusercontent.com/gravitee-io/gravitee-expression-language/master/src/main/resources/whitelist).
whitelist:
# Allows to define if the specified list of method or classes should be append to the default one or should replace it.
# We recommend you to always choose 'append' unless you absolutely know what you are doing.
# mode: append
# Define the list of classes or methods to append (or set) to made accessible to the Expression Language.
# start with 'method' to allow a specific method (complete signature).
# start with 'class' to allow a complete class. All methods of the class will then be accessible.
list:
# Ex: allow access to DateTimeFormatter.ofLocalizedDate(FormatStyle) method
# - method java.time.format.DateTimeFormatter ofLocalizedDate java.time.format.FormatStyle
# Ex: allow access to all methods of DateTimeFormatter class
- class java.util.Base64
- class java.util.Base64$Encoder
With environment variables
You can configure your gateway using those environment variables:
gravitee.el.whitelist.list[0]=class java.util.Base64
gravitee.el.whitelist.list[1]=class java.util.Base64$Encoder
About the expression you used
You can simplify it a bit like that (you do not need to use String.valueOf
):
{T(java.util.Base64).getEncoder().encodeToString('test:test'.getBytes())}
Edit
If the syntax java.util.Base64$Encoder
used in the whitelist doesn't work, replacing the $
by a .
might work instead (especially in case of environment variable declaration in a docker compose yaml file for example):
java.util.Base64.Encoder
Have a good day!