Skip to content

[Bug]: Unable to login when using FusionAuth as a SAML IDP and a SAML populate lambda. #3183

@wied03

Description

@wied03

What happened?

Steps to reproduce

  1. Setup a SAML v2 populate lambda as noted below.
  2. Configure a FusionAuth application with SAML enabled (all that's needed is to set an issuer, redirect URI, the signature if your test SP app requires it, and the lambda you just created for populate lambda.
  3. Attempt a login.

Expected result

Login succeeds.

Actual result

Login fails with this in the browser:

Image

Logs will show this:

2025-09-16 03:50:40.192 PM ERROR io.fusionauth.app.action.samlv2.CallbackAction - Unable to parse SAML encoded state or generate SAMLResponse.
io.fusionauth.api.service.system.LambdaInvocationException: io.fusionauth.api.service.lambda.LambdaScriptException: org.graalvm.polyglot.PolyglotException: TypeError: Cannot read property 'attributes' of undefined
        at io.fusionauth.api.service.lambda.DefaultLambdaInvocationService.invoke(DefaultLambdaInvocationService.java:86)
        at io.fusionauth.api.service.samlv2.DefaultSAMLv2ProviderService.populateResponse(DefaultSAMLv2ProviderService.java:400)
        at io.fusionauth.app.action.samlv2.CallbackAction.get(CallbackAction.java:138)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        at org.primeframework.mvc.util.ReflectionUtils.invoke(ReflectionUtils.java:443)
        at org.primeframework.mvc.action.DefaultActionInvocationWorkflow.execute(DefaultActionInvocationWorkflow.java:77)
        at org.primeframework.mvc.action.DefaultActionInvocationWorkflow.perform(DefaultActionInvocationWorkflow.java:60)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.message.DefaultMessageWorkflow.perform(DefaultMessageWorkflow.java:50)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.validation.DefaultValidationWorkflow.perform(DefaultValidationWorkflow.java:45)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.security.DefaultSecurityWorkflow.perform(DefaultSecurityWorkflow.java:60)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.parameter.DefaultPostParameterWorkflow.perform(DefaultPostParameterWorkflow.java:49)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.content.DefaultContentWorkflow.perform(DefaultContentWorkflow.java:74)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.parameter.DefaultParameterWorkflow.perform(DefaultParameterWorkflow.java:58)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.parameter.DefaultURIParameterWorkflow.perform(DefaultURIParameterWorkflow.java:92)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.scope.DefaultScopeRetrievalWorkflow.perform(DefaultScopeRetrievalWorkflow.java:50)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.action.DefaultActionMappingWorkflow.perform(DefaultActionMappingWorkflow.java:130)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.security.DefaultSavedRequestWorkflow.perform(DefaultSavedRequestWorkflow.java:65)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.cors.CORSFilter.doFilter(CORSFilter.java:188)
        at org.primeframework.mvc.cors.CORSRequestWorkflow.perform(CORSRequestWorkflow.java:66)
        at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
        at org.primeframework.mvc.workflow.DefaultMVCWorkflow.perform(DefaultMVCWorkflow.java:109)
        at org.primeframework.mvc.PrimeMVCRequestHandler.handle(PrimeMVCRequestHandler.java:76)
        at io.fusionauth.http.server.internal.HTTPWorker.run(HTTPWorker.java:181)
        at java.base/java.lang.VirtualThread.run(VirtualThread.java:329)
Caused by: io.fusionauth.api.service.lambda.LambdaScriptException: org.graalvm.polyglot.PolyglotException: TypeError: Cannot read property 'attributes' of undefined
        at io.fusionauth.api.service.lambda.graal.GraalLambdaEngine.executeLambda(GraalLambdaEngine.java:185)
        at io.fusionauth.api.service.lambda.graal.GraalLambdaEngine.invoke(GraalLambdaEngine.java:78)
        at io.fusionauth.api.service.lambda.DefaultLambdaInvocationService.invoke(DefaultLambdaInvocationService.java:57)
        ... 35 common frames omitted
Caused by: org.graalvm.polyglot.PolyglotException: TypeError: Cannot read property 'attributes' of undefined
        at <js>.populate(populate:15)
        at org.graalvm.polyglot.Value.executeVoid(Value.java:952)
        at io.fusionauth.api.service.lambda.graal.GraalLambdaEngine.executeLambda(GraalLambdaEngine.java:173)
        ... 37 common frames omitted

Lambda source

function populate(samlResponse, user, registration) {
  console.info('Hello World!');
  console.info(JSON.stringify(samlResponse)); 
  samlResponse.assertion.attributes['firstName'] = ["John"];
}

Version

1.60.0

Affects Versions

1.60.0

Alternatives / Workarounds

NOTE: This only applies to 1.60.0 is not required on 1.60.0. If this workaround is applied, it will need to be removed prior to upgrading to 1.60.1 or any newer version.

  1. In the SAML populate lambda, address the first assertion in a list of assertions on samlResponse.assertions. In the example above, that means change samlResponse.assertion.attributes['firstName'] = ["John"]; to samlResponse.assertions[0].attributes['firstName'] = ["John"];

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

Status

Delivered

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions