Skip to content
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

InvalidImportException when parsing authenticationExecutions without priority #1071

Closed
thomasdarimont opened this issue Jun 25, 2024 · 1 comment · Fixed by #1072
Closed
Labels

Comments

@thomasdarimont
Copy link
Contributor

Current Behavior

When I try to import a previously working realm configuration with custom authentication flows. Then I get the following exception:

acme-keycloak-provisioning-1  | Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
acme-keycloak-provisioning-1  | 2024-06-25T14:05:17.649Z ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed
acme-keycloak-provisioning-1  | 
acme-keycloak-provisioning-1  | de.adorsys.keycloak.config.exception.InvalidImportException: Unable to parse file 'file:/config/acme-apps.yaml': Cannot invoke "java.lang.Integer.intValue()" because the return value of "org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation.getPriority()" is null
acme-keycloak-provisioning-1  |  at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: de.adorsys.keycloak.config.model.RealmImport["authenticationFlows"]->java.util.ArrayList[1]->de.adorsys.keycloak.config.model.AuthenticationFlowImport["authenticationExecutions"])
acme-keycloak-provisioning-1  | 	at de.adorsys.keycloak.config.provider.KeycloakImportProvider.readRealmImportFromImportResource(KeycloakImportProvider.java:212)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.ArrayList.forEach(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.SortedOps$RefSortingSink.end(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.Sink$ChainedReference.end(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.Sink$ChainedReference.end(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
acme-keycloak-provisioning-1  | 	at de.adorsys.keycloak.config.provider.KeycloakImportProvider.readFromLocations(KeycloakImportProvider.java:126)
acme-keycloak-provisioning-1  | 	at de.adorsys.keycloak.config.KeycloakConfigRunner.run(KeycloakConfigRunner.java:71)
acme-keycloak-provisioning-1  | 	at org.springframework.boot.SpringApplication.lambda$callRunner$5(SpringApplication.java:790)
acme-keycloak-provisioning-1  | 	at org.springframework.util.function.ThrowingConsumer$1.acceptWithException(ThrowingConsumer.java:83)
acme-keycloak-provisioning-1  | 	at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:60)
acme-keycloak-provisioning-1  | 	at org.springframework.util.function.ThrowingConsumer$1.accept(ThrowingConsumer.java:88)
acme-keycloak-provisioning-1  | 	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798)
acme-keycloak-provisioning-1  | 	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:789)
acme-keycloak-provisioning-1  | 	at org.springframework.boot.SpringApplication.lambda$callRunners$3(SpringApplication.java:774)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.SortedOps$SizedRefSortingSink.end(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source)
acme-keycloak-provisioning-1  | 	at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:774)
acme-keycloak-provisioning-1  | 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:341)
acme-keycloak-provisioning-1  | 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354)
acme-keycloak-provisioning-1  | 	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343)
acme-keycloak-provisioning-1  | 	at de.adorsys.keycloak.config.KeycloakConfigApplication.main(KeycloakConfigApplication.java:35)
acme-keycloak-provisioning-1  | 	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
acme-keycloak-provisioning-1  | 	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91)
acme-keycloak-provisioning-1  | 	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53)
acme-keycloak-provisioning-1  | 	at org.springframework.boot.loader.launch.PropertiesLauncher.main(PropertiesLauncher.java:574)
acme-keycloak-provisioning-1  | Caused by: java.lang.IllegalArgumentException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation.getPriority()" is null
acme-keycloak-provisioning-1  |  at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: de.adorsys.keycloak.config.model.RealmImport["authenticationFlows"]->java.util.ArrayList[1]->de.adorsys.keycloak.config.model.AuthenticationFlowImport["authenticationExecutions"])
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4624)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:4555)
acme-keycloak-provisioning-1  | 	at de.adorsys.keycloak.config.provider.KeycloakImportProvider.readContent(KeycloakImportProvider.java:226)
acme-keycloak-provisioning-1  | 	at de.adorsys.keycloak.config.provider.KeycloakImportProvider.readRealmImportFromImportResource(KeycloakImportProvider.java:210)
acme-keycloak-provisioning-1  | 	... 38 common frames omitted
acme-keycloak-provisioning-1  | Caused by: com.fasterxml.jackson.databind.JsonMappingException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation.getPriority()" is null
acme-keycloak-provisioning-1  |  at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: de.adorsys.keycloak.config.model.RealmImport["authenticationFlows"]->java.util.ArrayList[1]->de.adorsys.keycloak.config.model.AuthenticationFlowImport["authenticationExecutions"])
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:276)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:630)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:618)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:143)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:361)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:246)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:30)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:4619)
acme-keycloak-provisioning-1  | 	... 41 common frames omitted
acme-keycloak-provisioning-1  | Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation.getPriority()" is null
acme-keycloak-provisioning-1  | 	at de.adorsys.keycloak.config.model.AuthenticationFlowImport$AuthenticationExecutionExportRepresentationComparator.compare(AuthenticationFlowImport.java:58)
acme-keycloak-provisioning-1  | 	at de.adorsys.keycloak.config.model.AuthenticationFlowImport$AuthenticationExecutionExportRepresentationComparator.compare(AuthenticationFlowImport.java:51)
acme-keycloak-provisioning-1  | 	at java.base/java.util.TimSort.countRunAndMakeAscending(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.TimSort.sort(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.Arrays.sort(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.util.ArrayList.sort(Unknown Source)
acme-keycloak-provisioning-1  | 	at de.adorsys.keycloak.config.model.AuthenticationFlowImport.setAuthenticationExecutions(AuthenticationFlowImport.java:44)
acme-keycloak-provisioning-1  | 	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
acme-keycloak-provisioning-1  | 	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
acme-keycloak-provisioning-1  | 	at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:141)
acme-keycloak-provisioning-1  | 	... 50 common frames omitted

Expected Behavior

Existing realm config files with custom authenticationFlow exceutions should work as before.

Steps To Reproduce

No response

Environment

  • Keycloak Version: 25.0.1
  • keycloak-config-cli Version: 6.0.3-SNAPSHOT (cf28b9d)
  • Java Version: 17.0.11

Anything else?

I build a local version of Keycloak config cli from latest main (cf28b9d)

It seems that the priority comparison in AuthenticationExecutionExportRepresentationComparator is not null-safe.

A simple fix is to use ObjectUtils.compare(first.getPriority(), second.getPriority()); with that I can import the existing realm config file without problems.

@thomasdarimont
Copy link
Contributor Author

jonasvoelcker added a commit that referenced this issue Jun 25, 2024
…-utils-to-compare-authflowexec-prios

Use null-safe comparison in  AuthenticationExecutionExportRepresentationComparator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
1 participant