4

I would like to use permissions or scopes or similar to allow fine grained access to REST resource.

Ideally I would like to do something like:

@PreAuthorize("hasPermission('Brands', 'brands:write')")
ResponseEntity<Brand> getBrand(@PathVariable("brandCode") String brandCode);

where 'Brands' is a keycloak client authorization resource with scopes 'brands:write, brands:read'.

The only annotation that seems to work is @Secured with a role, I do not want to do RBAC.

@Secured({"ROLE_STAFF"})

I have looked at the PolicyEnforcer, it is unclear to me exactly how it is supposed to be used.

I can write code of the form:

KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext();
if (authzContext.hasScopePermission("brands:write")) {

// This works....
}

How can I tie the AuthorizationContext from PolicyEnforcing to the standard Spring security annotations ?

Stéphane GRILLON
  • 11,140
  • 10
  • 85
  • 154
David
  • 251
  • 1
  • 2
  • 5

1 Answers1

1
@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {
@Autowired
private HttpServletRequest request;


@Override
public boolean hasPermission(Authentication auth, Object targetDomainObject, Object permission) {
    if ((auth == null) || (targetDomainObject == null) || !(permission instanceof String)){
        return false;
    }

    KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
    AuthorizationContext authzContext = keycloakSecurityContext.getAuthorizationContext();

    if(targetDomainObject instanceof String) {
        return authzContext.hasPermission((String)targetDomainObject, (String)permission);
    } else if(targetDomainObject == null) {
        return authzContext.hasScopePermission((String)permission);
    } else {
        return false;
    }
}
austindev
  • 56
  • 3