Spring Security #PreAuthorize with application itself as user - spring

I've got a spring application set up with spring security. I've got my service methods annotated with #PreAuthorize(...). So everyone from the web needs some specific rights to access those methods, which is fine.
But now I've got a new use case. There's a #Scheduled method running to do some checks and send messages. Currently only people with ROLE_USER are allowed to send messages. But now also the application itself has to send those messages.
How should I manage to have some kind of invisible user (= the application), which is logged in all the time and has specific rights? Or maybe "all rights" would be nice as well, so it just ignores all those security annotations.
Or maybe I don't need a "user" at all?
Thanks for your help!
EDIT: The main 2 questions are:
Should I create a real user for the application? Means: An entry in the user table of the database? How did you solve this? Maybe you do simply use the user account of the admin user (which is a real person)?
If I now have this "system" user. What's the best way to "use" it? For example I'd use #Autowired User systemUser to access this user wherever I need it. (Of course there's some point in the application config where I create a bean with this specific user).
EDIT2: Some more thoughts:
I think in the future I want to send messages from different subsystems of the application. So it's no choice to use the admin user, because I need a few different users with different names.

I was faced with similar problem and the solution I implemented was an internal and an "external" service implementation. The external one has the internal one autowired in. Any application-internal component, like your scheduled job, would have the internal service wired in. Any Web-exposed components would have the secured "external" service wired in, which would have the #PreAuthorize etc. annotations in place, but otherwise would act just as a delegate to the internal service.
I also log, before passing message onto the internal service, the principal of the authentication object which was used for authorization. You know you'll have one available in the SecurityContext, so pick it out and just make a note in your logs of someone external invoking internal services. I do the below (your principal could be non-username, but still, wanted to share):
final String currentUser = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();

I think that all the answers you provided are fairly common solutions, so it depends very much on your requirements. The app I'm working on has some intense audit requirements so we have a user set up for the application itself to use when it needs to invoke services through a scheduler. This allows us to log against a given principle. Perhaps you should clarify your requirements?

Related

How should hierarchical permissions be implemented efficiently in microservices?

I have a scenario where user permissions are scoped to a particular position in a hierarchy, e.g. a user may have permissions at a building, whereas another user only for a room inside that building. Resources can also be scoped at a particular position in the hierarchy.
I would like to allow for different entity types to define their own rules for whether a user can see a particular resource or not. E.g. a particular resource may be visible by anybody with permissions at or above the scope of the resource, whereas another may have a strict requirement that the user has to have the permission at exactly the scope of that resource.
The approaches I have thought of so far are:
Each microservice has a sidecar service which caches the hierarchy required for working out whether a particular resource is visible, but this then essentially requires the hierarchy to be located with all deployed microservices.
A single authorization service which is called to determine whether permission should be granted to perform an action for a particular resource.
Each microservice queries the hierarchy from the service which owns the hierarchy when needed, in order to retrieve the required information to determine the permission check itself.
Information around this particular style of permission in a microservice environment seems to be limited. What would be the recommended approach for such a situation?
I'd recommend approach 2, for the reason that your application will be unlikely to be the only consumer of the auth service as your architecture expands.
You would query the auth service whenever a user logs into any of your applications, and this would return a JWT with the permissions allocated to the particular user baked into it. Then when the user attempts to access the restricted resource, the Buildings service (or similar) would query the JWT to see if they have the appropriate permissions, and return the content that they have access to.

Tracking user activity in a microservice application

I want to keep track (with persistency) of users interactions with a microservice application developed with spring boot, so that i could consult them if something happened even maybe a year later.. One solution i found was use event sourcing and the problem was gone.. but due to some constraints i cannot go with that solution (in this project) so i was wondering..
Question
How can I track all user interactions and persist them in a spring boot microservice application?
if all the interactions that you want to track are sent to the server, then you can persist them in the database when the request is received in the server. To know who is the user you must need a way to identify him, for example, by using a token if the user is authenticated.
However, although this can be a solution the usual way to do this is using google analytics https://analytics.google.com/analytics/web/provision/#/provision
or snowplow https://snowplowanalytics.com/
Any of them track the actions done by the user in the frontend of the application

Should I manually set user session when receiving messages?

I have resources that are protected per user. The user themselves are able to edit it, and then some super users are also able to edit it, but other users are not able to.
When it comes to endpoints, I have a user sessions and I can check their permissions to see if they are able to edit the resource or not.
However, when it comes to events/messages the service receives, there is no user sessions involved. So it is not able to edit those resources.
I know that the messages that we receive are safe (Only originate from our own systems), so I'm planning on manually setting the user session myself for all events/messages with a system user account.
I could also split the method to be something like updateResource and updateResourceNoPermissionCheck, but I'd rather not give the ability for anyone (including other developers) the ability to call the wrong method when they weren't supposed to.
Was wondering people's thoughts. Thanks in advance!
Yes, it's quite normal. I've seen cases when developers pass along the token via message headers, but I don't find it necessary. Providing enough user context information in the message contract establishes solid guarantees for the message receiver about who the user is. It is abnormal when your internal messaging system is exposed externally, which, of course, would create security risks as you cannot trust the sender.

Ensure only assigned user can complete task in Camunda

Problem 1: I am integrating Camunda workflow engine in my spring boot application. I have users in a separate business db and need to sync it with Camunda workflow engine to assign the users to particular tasks. The users in the business db are not categorized to groups but have certain roles. I want to sync these roles with the groups in Camunda.
Problem 2: I also want only the assigned users to be able to complete the tasks via REST localhost:8080/rest/task/{id}/complete
How can I be able to achieve this? I cannot find a solid guide that can help me.
Edit: I am able to load the users from my business db to Camunda using this example https://github.com/hashlash/example-camunda-custom-identity-service. This solves problem 1.
Now, I need a way to make sure only the assigned user can complete the assigned task via authorization i.e. Problem 2. Any guides on this?
I don't know if I understood what you want. But I think it makes more sense to associate your users with authorizations than with groups.
If you define in your UserTask the attributes Assignee, Candidate User or Candidate Groups, Camunda will automatically create the authorization for you.
I think you have some additional information on this link:
Additional Task Permissions
You seem to be on the right track. By default Camunda is configured not to enforce authorizations. You need to enabled it using the property:
camunda: bpm:
authorization:
enabled: true
(RE the previous comment: it is better to assign the Camunda authorizations to groups and get the assignment of users to groups from the external identity provider. This way fine grain application-specific authorization management remains in the application.)

How can Spring Security keep user A out of user B's data?

I know that Spring Security has a lot of role-based authorization capability. But what if I have two ordinary users accessing data. How do I keep User A from seeing records belonging to User B? For example, keeping User A from seeing the orders created by all other users?
Please note that this is NOT role-based authorization. User A and User B, etc., are all ordinary users, differing only in their identities.
In an existing Spring application I'm currently getting the job done with a filter in each DAO, ensuring that "... and user_id = $1 ..." is part of the queries. This also reduces the volume of fetched data, lowering database access costs.
In the future I will be breaking up my application into microservices. It seems to me that each microservice request must also have the UserDetails information. This sounds like an anti-pattern.
An API gateway would merely be a consumer of the approaches that I previously mentioned. So, is passing the UserDetails information to each microservice my best approach?
I hope the answer is not "create a role for each ordinary user, like "ROLE_USER_A", "ROLE_USER_B", etc.
Thanks,
Jerome.
In an existing Spring application I'm currently getting the job done
with a filter in each DAO, ensuring that "... and user_id = $1 ..." is
part of the queries. This also reduces the volume of fetched data,
lowering database access costs.
This is the correct approach
In the future I will be breaking up my application into microservices. It seems
to me that each microservice request must also have the UserDetails
information. This sounds like an anti-pattern.
There are several approaches you an use here. You could use spring security oauth, and separate the authentication server out into it's own component. Then the credentials will be stored in a central location. This will save you from having to pass the credentials around.
Another approach would be using perimeter security. Basically your gateway service would authenticate each request and then pass the user details to each component.
There are other approaches, but these two are pretty common.

Resources