Authorization returning reason with details about denied action

Authorization returning reason with details about denied action

Old forum URL: forums.lhotka.net/forums/t/11536.aspx


Miroslav Galajda posted on Monday, August 20, 2012

 

Hi all,

I have an UI scenario in which I need to display to user the details about why he was denied to do something, for example not to remove some item in the list because some other objects in other business models might be using it. 

Looking at the Csla authorization code I thought I've found the solution. But not quite.

Authorization is available for the calling code through HasPermission method on the BusinessRules class, which I cannot override without modifing Csla code.

I was thining about the following kind of solution:

1. Create derived AuthorizationContext class with Results list similar to what's in the RuleContext

2. Override HasPermission to supply own instance of AuthorizationContext with support for Results

3. Somehow expose the Results for the calling code

The last two points are the problematic points to do. To be able override HasPermission I would need to create an extension method so that I could be able to expose the result list. I have to use extension method, because there's no way to extended businessrules class without reimplemeting it or modifing it in Csla code.

Secondly to reimplement the HasPermission method as an extension method I would need to access to internal types that are used in that method.

So my solution would require to modify the Csla code.

Are there any other options which I've overlooked?

 

Thanks

Yours sincerely

Miroslav Galajda

 

JonnyBee replied on Monday, August 20, 2012

I would assume this concerns child objects where CSLA never call authorization rules at "object" level f.ex. and the "Delete" method should fail and give an exception and notification to the user?

So how about simply throwing your own SecurityException (or your own derived exception type) that contains the reason from the Execute method of the rule?

Miroslav Galajda replied on Monday, August 20, 2012

Is this the correct way of implementing the authorization rule? If so, I can take it into consideration.

But for me this is the last way to consider. I would prefer not to use the exceptions in this context, because the HasPermission method is not designed this way. It is inteded to answer the question with yes or no result, isn't it? I think it isn't designed that way.

 

Miroslav Galajda

JonnyBee replied on Monday, August 20, 2012

The typical part is that there is only 1 AuthorizationRule per AuthorizationAction and that the actual method does the check (and eventually throws an Exception). Take f.ex CanWriteProperty method in BusinessBase:

    public bool CanWriteProperty(Csla.Core.IPropertyInfo property, bool throwOnFalse)
    {
      bool result = CanWriteProperty(property);
      if (throwOnFalse && result == false)
      {
        System.Security.SecurityException ex = new System.Security.SecurityException(
          String.Format("{0} ({1})", Resources.PropertySetNotAllowed, property.Name));
        throw ex;
      }
      return result;
    }

So - the typical way is to throw an Exception to prevent the method from continuing to execute.

And to prevent a Delete from a child BusinessListBase you would

CSLA does NOT check permission in its list classes (other than IsSavable that should only be checked for a root object) so you must implement this check in your own list classes. 

Miroslav Galajda replied on Monday, August 20, 2012

I'm not sure if I can agree with you about throwing the security exception at the AuthorizationRule level, because it is designed to return true or false as its result. Throwing exception with the same meaning as returning false is abusing the exception mechanism.

And as you have shown in the example from CanWriteProperty throwing the exception is handled on the higher level. And as you can see at this level it is not expected to be exception thrown during this call, because in the other case, there would be the try catch block. But OK, this could be added with easy to secure the CanWriteProperty method to not throw exception when throwOnFalse=false.

But unfortunately this is the simplest and easy to do solution :-(

Probably I will use this method, but I'm not internally satisfied with it.

 

Miroslav Galajda

Copyright (c) Marimer LLC