product-is
product-is copied to clipboard
Unable to use parseInt with setCookie in adaptive script
Describe the issue:
When parseInt()
is used with Java 11, it was considered an Integer at java level and can be used for max-age property of setCookie() function (see the below adaptive script sample).
But once migrated to a newer IS version and Java 17 is used, the same parseInt()
returns a double at Java level and the casting into Integer breaks at [1]. It seems somehow when the OpenJdkNashorn is used with Java 17, the behaviour difference has occurred.
As per the community [2], one should not expect a java.lang.Integer
specifically but java.lang.Number
and cast appropriately when using Nashorn.
The following was tried out at [1] and it worked fine for both Java versions.
Optional.ofNullable(properties.get(FrameworkConstants.JSAttributes.JS_COOKIE_MAX_AGE))
.filter(Number.class::isInstance)
.map(Number.class::cast)
.map(Number::intValue)
.ifPresent(cookie::setMaxAge);
Optional.ofNullable(properties.get(FrameworkConstants.JSAttributes.JS_COOKIE_VERSION))
.filter(Number.class::isInstance)
.map(Number.class::cast)
.map(Number::intValue)
.ifPresent(cookie::setVersion);
[1] https://github.com/wso2-extensions/identity-conditional-auth-functions/blob/f7a433a7d1ca328051316bb52382b21927a26088/components/org.wso2.carbon.identity.conditional.auth.functions.http/src/main/java/org/wso2/carbon/identity/conditional/auth/functions/http/SetCookieFunctionImpl.java#L104 [2] https://stackoverflow.com/a/25996818
How to reproduce:
- Setup Java 17 and execute
<IS_HOME>/bin/adaptive.sh
- Create a service provider and add following adaptive script (this is a dummy script to demostate the issue)
var sessionAge;
var onLoginRequest = function(context) {
sessionAge = context.request.params.age[0];
Log.info("Session Age: " + sessionAge);
executeStep(1, {
onSuccess: function(context) {
var username = context.steps[1].subject.username;
if (sessionAge) {
Log.info("Going to invoke setCookie()");
setCookie(context.response, "savedUsername", username, {
"max-age": parseInt(sessionAge),
"path": "/",
"httpOnly": true,
"secure": true,
"sameSite": "STRICT"
});
}
}
});
};
- Start an authentication flow with additional query param
age=1234
- Once step 1 is completed, the following error can be observed
ERROR {org.wso2.carbon.identity.application.authentication.framework.config.model.graph.openjdk.nashorn.JsOpenJdkNashornGraphBuilder} - Error in executing the javascript for service provider : test, Javascript Fragment :
function(context) {
var username = context.steps[1].subject.username;
if (sessionAge) {
Log.info("Going to invoke setCookie()");
setCookie(context.response, "savedUsername", username, {
"max-age": parseInt(sessionAge),
"path": "/",
"httpOnly": true,
"secure": true,
"sameSite": "STRICT"
});
}
} java.lang.ClassCastException: class java.lang.Double cannot be cast to class java.lang.Integer (java.lang.Double and java.lang.Integer are in module java.base of loader 'bootstrap')
at org.wso2.carbon.identity.conditional.auth.functions.http.CookieFunctionImpl.setCookie(CookieFunctionImpl.java:108)
at org.openjdk.nashorn.internal.scripts.Script$Recompilation$14$\^eval\_/0x00000008018ef840.L:1(<eval>:7)
at org.openjdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:648)
at org.openjdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513)
at org.openjdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:520)
at org.openjdk.nashorn.api.scripting.ScriptObjectMirror.call(ScriptObjectMirror.java:111)
at org.wso2.carbon.identity.application.authentication.framework.config.model.graph.openjdk.nashorn.OpenJdkNashornSerializableJsFunction.apply(OpenJdkNashornSerializableJsFunction.java:85)
at org.wso2.carbon.identity.application.authentication.framework.config.model.graph.openjdk.nashorn.JsOpenJdkNashornGraphBuilder$JsBasedEvaluator.evaluate(JsOpenJdkNashornGraphBuilder.java:1208)
at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraphBasedSequenceHandler.executeFunction(GraphBasedSequenceHandler.java:722)
at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraphBasedSequenceHandler.handleDecisionPoint(GraphBasedSequenceHandler.java:685)
at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraphBasedSequenceHandler.handleNode(GraphBasedSequenceHandler.java:200)
at org.wso2.carbon.identity.application.authentication.framework.handler.sequence.impl.GraphBasedSequenceHandler.handle(GraphBasedSequenceHandler.java:152)
at org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultAuthenticationRequestHandler.handle(DefaultAuthenticationRequestHandler.java:194)
at org.wso2.carbon.identity.application.authentication.framework.handler.request.impl.DefaultRequestCoordinator.handle(DefaultRequestCoordinator.java:320)
at org.wso2.carbon.identity.application.authentication.framework.CommonAuthenticationHandler.doPost(CommonAuthenticationHandler.java:50)
at org.wso2.carbon.identity.application.authentication.framework.CommonAuthenticationHandler.doGet(CommonAuthenticationHandler.java:41)
at org.wso2.carbon.identity.oauth.endpoint.authz.OAuth2AuthzEndpoint.handleAuthFlowThroughFramework(OAuth2AuthzEndpoint.java:3557)
at org.wso2.carbon.identity.oauth.endpoint.authz.OAuth2AuthzEndpoint.handleInitialAuthorizationRequest(OAuth2AuthzEndpoint.java:1266)
at org.wso2.carbon.identity.oauth.endpoint.authz.OAuth2AuthzEndpoint.authorize(OAuth2AuthzEndpoint.java:300)
- But this works fine if Java 11 is used (without executing adaptive.sh)
Expected behavior: The adaptive script should work with the same syntax after version migration
Environment information
- Product Version: IS 6.1.0
- Java version: 17