Announcement Announcement Module
Collapse
No announcement yet.
simple question Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • simple question

    I just came out of a meeting where I attempted to defend the decision to use Acegi Security on my current project and I found myself stuck on a seemingly simple question: how does one ascertain whether the current user has permission to do a certain unit of work based on some piece of input data?

    In other words, in my business service I might have a method approveLoan(LoanApplication). And, if the current user is in ROLE_TELLER, they can approve the loan as long as it's under $10,000. But, they have to have ROLE_MANAGER if it's greater than $10k.

    I stumbled a bit and suggested that this might be accomplished with our own Voter implementation. But that caused concern over needing to start writing a bunch of voters for all sorts of business conditions.

    And, more importantly, there was strong opposition to having to answer the question "can user foo do bar if baz is true" with a wired-in separate class. That is, the other developers say that just want to do this:

    Code:
    if(loan.getAmount > LOAN_CUTOFF) {
        if(user.hasPermission("ROLE_MANAGER") {
           // approve loan
        } else {
            // throw exception
        }
    }
    I could not tell them any way that they can do this simple use case with Acegi. I hope I'm wrong!

    thanks,

    Ben

  • #2
    We'll if the user=='schrepfler' then the loan should be accepted

    Comment


    • #3
      and if user == 'yatesco' the interest rate should be 0

      Comment


      • #4
        Alright, alright guys..... very funny. But does someone have a helpful answer? Is there no way to use Acegi programatically from the business services?

        Ben

        Comment


        • #5
          Acegi Security's biggest strength, and it's biggest weakness, is there are 100 different ways you can do anything.

          Your instinct of using a custom AccessDecisionVoter was actually the most optimal answer. Why? Because it's AOP. Cross-cutting security logic, such as who is allowed work with a particular sized LoanApplication, is usually better put into a LoanApplicationVoter because this abstracts it from application code. This in turn increases testability and allows business logic to be more tightly focused. You could use standard JavaBean properties to modify the different loan levels via Spring IoC.

          However, if you want to do it programatically in your services layer, just use:

          Code:
               // adapted from ContextHolderAwareRequestWrapper
              public static boolean isGranted(Authentication auth, String role) {
                  if ((auth == null) || (auth.getPrincipal() == null)
                      || (auth.getAuthorities() == null)) {
                      return false;
                  }
          
                  for &#40;int i = 0; i < auth.getAuthorities&#40;&#41;.length; i++&#41; &#123;
                      if &#40;role.equals&#40;auth.getAuthorities&#40;&#41;&#91;i&#93;.getAuthority&#40;&#41;&#41;&#41; &#123;
                          return true;
                      &#125;
                  &#125;
          
                  return false;
              &#125;
          
          public void myMethod&#40;&#41; &#123;
            if&#40;loan.getAmount > LOAN_CUTOFF&#41; &#123;
                if&#40;isGranted&#40;SecurityContextHolder.getContext&#40;&#41;.getAuthentication&#40;&#41;, "ROLE_MANAGER"&#41; &#123;
                   // approve loan
                &#125; else &#123;
                    // throw exception
                &#125;
            &#125; 
          &#125;

          Comment


          • #6
            hardcoded roles???

            Hmmm, yeah I see... that looks pretty easy. And I will explore the AOP approach more as well.

            One more thing though... my friend with more security/database experience than myself furrowed his brow at your hard-coded role string. He says that roles should ONLY exist external to the application because roles are simply arbitrary groupings of users and permisssions... the sysadmin should be able change them and even add/delete them at whim! He says the code should only be concerned with "can user foo do bar" and that's it.

            Wondering what you thought of that.

            Comment


            • #7
              I agree with your colleague, although in my defence I was only trying to give you a quick code example... :-) In reality it should be configured via dependency injection, such as via a setRequiredRole(String role) method. This lets the configuration be moved to Spring XML.

              Comment

              Working...
              X