Announcement Announcement Module
No announcement yet.
Problem extending the expression based security control. Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem extending the expression based security control.

    I'm trying to extend the expression based security control to handle a custom scenario and I’m starting to wonder if this is the correct direction I should be going in. (I’m using Spring 3.0.3 and Security 3.0.5).

    Our application spans a number of customers and each customer has its own database. We have extended AbstractRoutingDataSource and use something suspiciously like SecurityContextHolder to control which database a user access on each request. This leaves us with a single web application that fronts 20+ databases.

    When a user is authenticated, they receive a number of GrantedAuthority with the customer appended e.g. ROLE_ADMIN/CUSTOMER_1, ROLE_CSR/CUSTOMER_1, ROLE_CSR/CUSTOMER_2, etc. It is possible for a single user to have different roles within different customers. So from a security perspective I need to check that a user has the correct role and access to the customer for that role.

    This was easy enough for URL’s. I extended the WebSecurityExpressionRoot and wrote a custom WebSecurityExpressionHandler to use this new CustomerWebSecurityExpressionRoot. A new method on this class simply appends the customer taken from the CustomerContextHolder and calls the existing hasAuthority() method.
    public boolean hasCustomerAuthority(String authority) {
      return hasAuthority(authority + DELIMITER + getCustomer());
    This means that I can use
    <sec:intercept-url pattern="/remoting/**" access="hasCustomerAuthority(‘ROLE_CSR’)" />
    instead of
    <sec:intercept-url pattern="/remoting/**" access="hasAnyAuthority(‘ROLE_CSR/CUSTOMER_1,ROLE_CSR/CUSTOMER_2,etc…’)" />
    I would like to do the same with method security, ie.
    @PreAuthorize(“has CustomerAuthority(‘ROLE_CSR’)”)
    instead of
    @PreAuthorize(“has AnyAuthority(‘ROLE_CSR/CUSTOMER_1,ROLE_CSR/CUSTOMER_2,etc…’)”)
    but MethodSecurityExpressionRoot is package scope. I created my own version and then went to extend the DeafultMethodSecurityExpressionHandler and override the createEvaluationContext method to replace the root with my new one, but the MethodSecurityEvaluationContext is package scope also. This is when I started to doubt what I was doing was the correct way to proceed.

    I had a quick look at creating a new PermissionEvaluator, but that seems to be more about domain object permission and would therefore check each object returned in a list when I know that the user has access to all.

    Should I continue with extending the expression based security? Any thoughts, suggestions, or other directions would be appreciated.

  • #2
    For something like this, you can just use a static method in the expression to implement your hasCustomerAuthority method.

    In the latest codebase there is also a
    method which can be used to create the custom root object.

    You might also want to check out Mike's recent presentation which is linked from the website and has some useful tips on avoiding hard-coding role information directly in your code.


    • #3
      Thanks for the reply Luke.

      I have implement a static method to implement my hasCustomerAuthority method, and after a bit of fun with #{} where the expression was evaluated to false at start up (first time using SpEL) I have got it working for both URL and method. So now I have
      <sec:intercept-url pattern="/remoting/*" access="T('ROLE_CSR')" />
      with no unusual configuration.

      It was Mike's presentation that convinced me to try spring-security a week or two ago, and I wanted to solve this issue before I took on the User/Role/Right issue.

      Thanks again,