-
Bug Report
-
Resolution: Fixed
-
L3 - Default
-
7.15.3
-
None
Environment:
Spring Boot, camunda-engine-7.15.3-ee, Linux, PostgreSQL
Description:
For authentication, on providing a unmutable list of groups, a NullPointerException is thrown:
2022-01-19 19:44:38.702 ERROR 1 --- [ XNIO-1 task-1] io.undertow.request : UT005023: Exception handling request to /camunda-workflows/app/welcome/default/java.lang.NullPointerException: null at java.base/java.util.Objects.requireNonNull(Objects.java:221) ~[na:na] at java.base/java.util.ImmutableCollections$AbstractImmutableList.indexOf(ImmutableCollections.java:170) ~[na:na] at java.base/java.util.ImmutableCollections$AbstractImmutableList.contains(ImmutableCollections.java:201) ~[na:na] at java.base/java.util.AbstractCollection.retainAll(AbstractCollection.java:419) ~[na:na] at org.camunda.bpm.engine.impl.persistence.entity.AuthorizationManager.filterAuthenticatedGroupIds(AuthorizationManager.java:1107) ~[camunda-engine-7.15.3-ee.jar!/:7.15.3-ee] at org.camunda.bpm.engine.impl.persistence.entity.AuthorizationManager.isAuthorized(AuthorizationManager.java:275) ~[camunda-engine-7.15.3-ee.jar!/:7.15.3-ee] at org.camunda.bpm.engine.impl.persistence.entity.AuthorizationManager.isAuthorized(AuthorizationManager.java:260) ~[camunda-engine-7.15.3-ee.jar!/:7.15.3-ee] at org.camunda.bpm.engine.impl.cmd.AuthorizationCheckCmd.execute(AuthorizationCheckCmd.java:69) ~[camunda-engine-7.15.3-ee.jar!/:7.15.3-ee] at org.camunda.bpm.engine.impl.cmd.AuthorizationCheckCmd.execute(AuthorizationCheckCmd.java:40) ~[camunda-engine-7.15.3-ee.jar!/:7.15.3-ee]
Steps to reproduce:
1. Using a custom AuthenticationProvider:
We build Azure-AD login based on the provided consulting code:
To fetch all permitted roles for the current user, we need to configure the desired roles. That causes to retrieve duplicates which we filtered by using a set instead of the list
and return a List to match the method's return-type:
return List.copyOf(groupIds);
That causes a NPE as shown above. Using this instead works fine
return new LinkedList(groupIds);
2. Having a preconfigured admin:
camunda: bpm: admin-user: id: admin password: admin first-name: Admin last-name: Istrator authorization: enabled: true tenant-check-enabled: false
3. Having additional group-based authentications:
We defined one additional group "camunda-readonly" and assigned authorizations in addition to the predefined group "camunda-admin". But I think the error will also happend without that custom group.
This is the content of the table ACT_RU_AUTHORIZATION:
env3_workflows=> select * from ACT_RU_AUTHORIZATION; id_ | rev_ | type_ | group_id_ | user_id_ | resource_type_ | resource_id_ | perms_ | removal_time_ | root_pr oc_inst_id_ --------------------------------------+------+-------+------------------+----------+----------------+------------------+------------+---------------+-------- ------------ 77be16a2-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | | admin | 1 | admin | 2147483647 | | 77c17203-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 2 | camunda-admin | 2 | | 77c4cd64-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 0 | * | 2147483647 | | 77c67b15-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 1 | * | 2147483647 | | 77c84fd6-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 2 | * | 2147483647 | | 77c9fd87-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 3 | * | 2147483647 | | 77cbd248-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 4 | * | 2147483647 | | 77cdf529-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 5 | * | 2147483647 | | 77cfa2da-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 6 | * | 2147483647 | | 77d1779b-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 7 | * | 2147483647 | | 77d3254c-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 8 | * | 2147483647 | | 77d4abed-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 9 | * | 2147483647 | | 77d6599e-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 10 | * | 2147483647 | | 77d8074f-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 11 | * | 2147483647 | | 77d9b500-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 12 | * | 2147483647 | | 77db3ba1-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 13 | * | 2147483647 | | 77dd1062-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 14 | * | 2147483647 | | 77debe13-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 15 | * | 2147483647 | | 77e06bc4-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 16 | * | 2147483647 | | 77e21975-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 17 | * | 2147483647 | | 77e3a016-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 18 | * | 2147483647 | | 77e526b7-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 19 | * | 2147483647 | | 77e72288-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-admin | | 20 | * | 2147483647 | | 77f5c88c-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 2 | camunda-readonly | 2 | | 77f79d4d-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 0 | * | 32 | | 77f8aebe-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 13 | * | 4098 | | 77f9c02f-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 10 | * | 4098 | | 77fb1fc0-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 9 | * | 2 | | 77fc3131-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 5 | * | 2147483647 | | 77fd69b2-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 2 | * | 2 | | 77fec943-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 20 | * | 2147483647 | | 780028d4-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 19 | * | 2147483647 | | 78011335-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 17 | * | 2147483647 | | 7801fd96-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 6 | * | 4674 | | 78030f07-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 8 | * | 2 | | 78042078-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 7 | * | 2 | | 78050ad9-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 11 | * | 2 | | 7805f53a-7955-11ec-9405-fa9bf01894b4 | 1 | 1 | camunda-readonly | | 1 | * | 2 | | (38 rows)
Observed Behavior:
NPE as shown above.
Expected behavior:
Groups are excepted regardless the type of List.
It would also be cool if the AuthenticationResult would be a Collection rathern than a List but I know, that's a breaking change.
Root Cause:
Once you check the table ACT_RU_AUTHORIZATION you will see that the first record is the admin-user's permission. That doesn't contain a group, so the list of availableAuthorizedGroupIds (see https://github.com/camunda/camunda-bpm-platform/blob/7aaee5fa685376bc09953fa2301408d3e2752821/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/AuthorizationManager.java#L1131) will contain a null value for that admin-user's record having no group-value given.
The reason for that NPE can be found in "retainAll" used in
at org.camunda.bpm.engine.impl.persistence.entity.AuthorizationManager.filterAuthenticatedGroupIds(AuthorizationManager.java:1107)
The JavaDoc of retainAll shows this description of possible Exceptions:
NullPointerException - if this set contains a null element and the specified collection does not permit null elements (optional), or if the specified collection is null
So, the set contains a null element and the unmutable list returned by "List.copyOf(...)" does not permit null values. You can also test this by doing this
List.of("first", null, "second");
which will also show that null values are not permitted for those static List.of and List.copyOf methods.
Solution Ideas:
Adopt the DB query to return null values (https://github.com/camunda/camunda-bpm-platform/blob/7aaee5fa685376bc09953fa2301408d3e2752821/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Authorization.xml#L221)
or filter null values (in https://github.com/camunda/camunda-bpm-platform/blob/7aaee5fa685376bc09953fa2301408d3e2752821/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/AuthorizationManager.java#L1131):
availableAuthorizedGroupIds = getDbEntityManager() .selectList("selectAuthorizedGroupIds") .stream() .filter(groupId -> groupId != null) .collect(Collectors.toSet());