samedi 18 juin 2016

Oauth2 / Password flow / check permission for a specific entity

The main data information and information in my API is linked to a project(Entity), What is good approach for password flow: to manage specific permission linked to a project with spring security and OAuth2?

In this application you have 5 micro service:

  • UAA microservice : the authorization server
  • Catalog microservice
  • Order microservice
  • Invoice microservice
  • Customer microservice

Zoom permission :

UUAMICROSERVICE

Each user can have many project, and can have the permission for each project:

  • CAN_MANAGE_CATALOG
  • CAN_VIEW_CATALOG
  • CAN_MANAGE_ORDER
  • CAN_VIEW_ORDER
  • CAN_MANAGE_INVOICE
  • CAN_VIEW_INVOICE
  • ...

I have many idea but i am not sure if i have the good approach :

USE CASE : I want to securise the endpoint :

http://catalog-service/{project_key}/catalogs

Only USER who have permission VIEW_CATALOG OR MANAGE_CATALOG for the project {project_key} can list all catalog present in the project

My first idea : USE ProjectAccessExpression with preauthorize

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;
        }
}

The inconvenient : is need to call UAA Service for 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 is SHOP2 is projectKey

The inconvenient : i am not sure but if user change permission, i need to revoke all token associate

Third idea : add specific permission in authentication blob

I don't know how to do for storing...

And in controller a annotation :

@PreAuthorize("@ProjectAccessExpression.hasPermission(authentication, 'manageCatalog||viewCatalog', #projectKey)

The inconvenient : same inconvenient at second idea

Aucun commentaire:

Enregistrer un commentaire