1
votes

We are using Spring Security with roles and privileges together with Spring ACL. Frontend is rendered by Thymeleaf (version 3). Application user can have either role with different privileges OR direct access to some domain object set by ACL.

Everything is working as expected in the backend part but I am unable to write sec:authorize correctly in the Thymeleaf template, which would combine both hasAuthority() and hasPermission() in one expression. User can have either entity level permissions by certain role or instance level permission by Spring ACL.

Concrete example

I have a table which display domain objects secured by ACL. There are some actions which I would like to restrict by sec:authorize to check, whether current user is allowed to perform this action.

 <th:block th:each="securedObject: ${securedObjects}">
        <button sec:authorize="hasAuthority('DELETE') OR hasPermission(#securedObject,'ADMINISTRATION')">Delete object</button>
 </th:block>

However hasPermission evaluation is not working for some reason here. I simply cannot access the local securedObject there. ACL security treat it as null and denies access. I tried it with different syntax (hasPermission(${securedObject},'ADMINISTRATION') etc. without any success.

Interesting thing is that it works correctly with using sec:authorize-acl correctly:

 <button sec:authorize-acl="${securedObject} :: 'ADMINISTRATION'">
 </button>

However when written this way it is not possible to combine it with permissions on entity level (hasRole()), so:

 <button sec:authorize-acl="${securedObject} :: 'ADMINISTRATION'" sec:authorize="hasRole('DELETE')">
 </button>

creates logical AND between those two so user has to have both - access granted by certain ROLE and by ACL.

1

1 Answers

1
votes

I was finally able to make it working. The domain object within the iteration can be accessed with following expression:

 <div sec:authorize="hasPermission(#vars.securedObject,'ADMINISTRATION')">Delete</div>

However the Permission evaluator was still denying access on the object. It is also required to configure it in Spring Security config class this way:

  @Configuration
  public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private PermissionEvaluator permissionEvaluator;

        @Override
        public void configure(WebSecurity web) throws Exception {
           DefaultWebSecurityExpressionHandler handler = new 
           DefaultWebSecurityExpressionHandler();
           handler.setPermissionEvaluator(permissionEv);
           web.expressionHandler(handler);
         }

         @Override
         protected void configure(HttpSecurity http) throws Exception {
         ....
}