The basic information and data information in my API is related to the project (Entity). What is a good approach for password flow: to manage the specific permission associated with the project using spring and OAuth2 security?
In this application you have 5 microservices :
- Microservice UAA: authorization server
- Microservice catalog
- Microservice order
- Microservice invoice
- Client microservice
Scaling:

Each user can have many projects and can have permission for each project:
- CAN_MANAGE_CATALOG
- CAN_VIEW_CATALOG
- CAN_MANAGE_ORDER
- CAN_VIEW_ORDER
- CAN_MANAGE_INVOICE
- CAN_VIEW_INVOICE
- ...
I have a lot of ideas, but I'm not sure if I have a good approach:
USE CASE: I want to pin an endpoint:
http:
Only a user with VIEW_CATALOG or MANAGE_CATALOG permission for the project {project_key} can display the entire directory present in the project
My first idea: USE ProjectAccessExpression with pre-authorization
CatalogController.java
@Controller public class CatalogController { @PreAuthorize("@projectAccessExpression.hasPermission(#projectKey, 'manageCatalog', principal)" + " or @projectAccessExpression.hasPermission(#projectKey, 'viewCatalog', principal)") @RequestMapping( value = "/{projectKey}/catalogs", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE ) public @ResponseBody List<Catalog> findByProject(@PathVariable("projectKey") String projectKey) { return catalogService.find(); } }
ProjectAccessExpression.java
@Component public class ProjectAccessExpression { private RestTemplate restTemplate; public boolean havePermission(String projectKey, String permission , String username) { Boolean havePermission = restTemplate.getForObject(String.format("http://uaa-service/permission/check?project=%1&permission=%2&username=%3", projectKey, permission, username ), Boolean.class); return havePermission; } }
Inconvenient: you need to call the UAA service each time
Second idea: USE USER_ROLE
With user_role
- username | Role
- mylogin1 | SHOP1 .CAN_MANAGE_CATALOG
- mylogin1 | SHOP1 .CAN_VIEW_CATALOG
- mylogin1 | Shop2 .CAN_MANAGE_CATALOG
- mylogin1 | Shop2 .CAN_VIEW_CATALOG
- mylogin1 | Shop2 .CAN_MANAGE_ORDER
- mylogin1 | Shop2 .CAN_VIEW_ORDER
- ...
SHOP1 SHOP2 - projectKey
Inconvenient: I'm not sure, but if the user changes the permission, I need to cancel all associated tokens
Third idea: add custom permission in the authentication unit
I do not know how to do this for storage ...
And in the controller annotation:
@PreAuthorize("@ProjectAccessExpression.hasPermission(authentication, 'manageCatalog||viewCatalog', #projectKey)
Inconvenient: the same inconvenient with the second idea