Authorizations in Rest API

We use the SpringBoot starter to deploy the Camunda Rest API and Camunda Process Applications. I wasnt sure if I should post this in the Spring Boot sub forum or in here…

I need to add some sort of authorization mechanism in the Rest API. Specifically for tasks. To make a long story short, I want to make sure that a user can only “see” and “complete” tasks that he/ she has access to. With that being said… I have already developed a custom solution that accomplishes this… through configuration of a couple of custom Filters, however, I do not want recreate functionality if it is already there.

I have been reading several posts here in this forum related to security and authorization for the REST API. However, based on information provided I still feel as though I do not have a clear path/ direction on how I should implement.

A little bit of background:

  1. Our authentication mechanism is through JWT. Our clients obtain Auth tokens through a separate micro service prior to calling our service. We have already configured Spring security to reject any request that does not have a valid token. I have also configured a filter to ensure that the Token contains appropriate authorities to access various API paths. Therefore only authenticated users have access to the API and I have already added some level of authorization.
  2. We do not/ will not maintain users or Groups in the Camunda database.
  3. Our user tasks will be configured with candidateGroups only. No assignees.
  4. This is only for the Rest API. We anticipate that most task interactions will be through the API. We will likely not use the task list UI application.

My question is this:

Do mechanism already exist to override the default behavior of the REST API to accomplish the following:

When a client calls in to get tasks “/task” or “/task/{id}”, return only the tasks/ task that have candidate groups that map to the user groups that are present in the JWT payload.

When a user calls in to complete or update a task POST “/task/{id}/complete/”, only permit the action if the task has candidate groups that map to the user groups that are present in the JWT payload.

Given that authentication is already handled by the Spring Security, would I get any added benefit by enabling auth and implementing a custom org.camunda.bpm.engine.rest.security.auth.AuthenticationProvider?

If I enable auth, once a rest client is authenticated, does the Rest API use authorization details about that user to authorize calls? In other words, would a get to “/task” only return tasks that the user has access to?

Again… my use case is very specific, and I doubt that the code base already has support for this. I just want to make sure of that this is the case before fully implementing our custom solution.

Any help with this matter would be greatly appreciated!

Hi I believe, that camunda knows how to do what you want out of the box. I have been playing around with camunda built in authorization last week, and if I got it correctly, if you don’t set the groups/tenants in identityService.setAuthentication, then camunda won’t consider any groups that the user, that is set as authenticated through identityService, has been set in the database. From this finding, I have come to conclusion, that you’re are the boss of defining to which groups the user belongs.
I have even tested a scenario, where the user is not in the database, cause that is one of our usecases, and the authorization worked as expected. With no given group, he had no rights but the ones generated when task are created. Which is the task READ,UPDATE permission is granted to every user that is in the candidate users or assignee.
If I set the groups in the setAuthentication service, the “nonexisting” user has all the rights that the group had.
So basically, the only thing you need to the to call the method based on your OAUTH authentication.

1 Like

Hi @joechromo,

As @tomorrow said, you could simply use the built-in authorization mechanism of camunda. Therefore it is not necessary to maintain users or groups in the camunda database. To answer you question:

Yes, you would get only tasks that the user has access to.

Cheers,
Roman

Thanks for your response. This has gotten me closer to where I want to be. But I think I am missing something.

The problem is that if I set the current authentication… it only uses the tenants from the auth to attempt to filter out tasks. I need it to use the groups.

Per your recommendation I am setting groups on the current authentication. Below are hard coded groups to demonstrate what I am doing… in reality I am getting these from the authenticated user.

List tenants = CollectionUtils.arrayToList(new String[] { “tenant1”, “tenant2” });
List groups = CollectionUtils.arrayToList(new String[] { “admin”});
String userName = “userName”;
Authentication currentAuthentication = new Authentication(userName, groups, tenants);
identityService.setAuthentication(currentAuthentication);

Then if I call GET /task

The following sql query is executed (from DEBUG logs)

select distinct […sql removed for readability…] from ACT_RU_TASK RES WHERE (RES.TENANT_ID_ is null or RES.TENANT_ID_ in ( ? , ? ) ) order by RES.ID_ asc LIMIT ? OFFSET ?
Parameters: tenant1(String), tenant2(String), 2147483647(Integer), 0(Integer)

This returns ALL of the tasks. Which is not what I want.

What I really want is to only get tasks that are configured with the candidateGroup “admin”.

For example, I can get these if I call /task?candidateGroup=admin thus producing the following debug output:

select distinct […sql removed for readability…] from ACT_RU_TASK RES inner join ACT_RU_IDENTITYLINK I on I.TASK_ID_ = RES.ID_ WHERE RES.ASSIGNEE_ is null and I.TYPE_ = ‘candidate’ and ( I.GROUP_ID_ IN ( ? ) ) and (RES.TENANT_ID_ is null or RES.TENANT_ID_ in ( ? , ? ) ) order by RES.ID_ asc LIMIT ? OFFSET ?
Parameters: admin(String), tenant1(String), tenant2(String), 2147483647(Integer), 0(Integer)

So it looks like I may be missing something… note that I did not implement the AuthenticationProvider… I am setting the current auth in a custom Filter.

Do you guys know if I am missing something?

So basically, to make a long story short, I need Camunda to automatically set the candidate groups in the sql statement like so:

and ( I.GROUP_ID_ IN ( ? ) )

Not the tenant.

Alright guys… you can scratch the last message… I figured out what was missing.

In addition to setting the current authenticated user in the id service… I was able to affect behavior of the task query by setting the authorization enabled to “true” in the process engine configuration… this impacted the query greatly.

I am debugging this now.

1 Like

Roman:

Unless I am missing something… I am not getting the right behavior… see problems with auth query

Maybe I am missing something?

Hi I am just guessing, but you’re setting group admin for the authenticated user. Have the admin group been created by you or camunda. Because if by camunda, that group admin has right for everything, which means user with this group has right to see everything, not just task, to which he is assigned.

E.g. here were looking at task. For task, you have permission READ, UPDATE, task specific …

Camunda creates for admin group following task right: task ALL *. The asterisk means, that the users in this group have ALL permission on every task, which basically you won’t set for standard users in production. In real world, the simple users won’t have any rights set for task resource through group directly.

Instead, on creation of task, and other actions too, camunda inserts automatically concrete permissions for concrete resources, not asterisk in resource id, but concrete id of the task. If the users won’t have any other permission for task, than they should be able to list only those task, that they have been assigned to or are candidate users.

This https://docs.camunda.org/manual/7.6/user-guide/process-engine/authorization-service/ and https://docs.camunda.org/manual/7.6/webapps/admin/authorization-management/ should point you in the direction. Try playing with setting various authorization via admin webapp. That way you will understand how camunda works. I have done the same.

@joechromo Have you found any solution for that problem? If yes, I appreciate if you gave a brief of how it was solved. I’ve the same requirement, I’ve the REST APIs embedded within my spring boot application, which acts as a resource server (validating authentication through a sso authentication server). So basically the APIs are now protected and no un-authenticated user can reach them, however the problem is that, I need the REST APIs to detect the group of the authenticated user, and decide whether that user is authorized to call that API or not, and as you stated above in your example, if a call is made to “Get Tasks” API, then only the tasks that the user can see will be returned (based on his authentication and his group). I’m not sure how to achieve this, do I need to write custom code, or this is already provided as an out-of-the-box feature with Camunda?

2 Likes