Vibrant discussion about CSLA .NET and using the framework to build great business applications.
I've set up static Auth Rules on my object by creating a method on it:
public static void AddObjectAuthorizationRules()
In which I add to the static BusinessRules collection:
BusinessRules.AddRule(typeof(MyObject), ... etc
I have CSLA set for 3-Tier usage, and I can see that the Authorization rules get checked in the client when the DataPortal is used.
However, when it hits the server DataPortal it doesn't seem check the rules. As this will be a publicly available server, I need it to check the rules on the server too.
Is there an easy way to configure the server DataPortal to also check the Authorization rules? I couldn't see anything in the CSLA books.
I am using 4.5.501.0
IAuthorizeDataPortal is intended to address this scenario. Implement this interface, configure your implementation to be used by the data portal, and your code will be invoked on the server for each data portal request immediately after the request has been deserialized and before the data portal starts to process the request.
Either subclass WcfPortal or provide your Service Portal for public clients.
If your clients are intern/partially trusful you maybe can use one of the two Interfaces:
Csla.Server.IAuthorizeDataPortal: Interface to be implemented by a custom authorization Provider. Csla.Server.IInterceptDataPortal: Implement this interface to create a data portal interceptor that is notified each time the data portal is invoked and completes processing.
void Initialize(Csla.Server.InterceptArgs e) void Complete(Csla.Server.InterceptArgs e)
Server Startup (or static constructor): Csla.Server.DataPortal.InterceptorType = typeof(MyInterceptor);
And CheckRules in Initialize(..), copy the implementation from DataPortalT.
I am already using IAuthorizeDataPortal for an authentication token check, so this isn't too bad for me :)
What exactly do I call from within there to trigger a check of the Authorization Rules based upon the AuthorizeRequest details? Is there anything within CSLA to help me with this or do I need to manually check my permissions?
You need to manually do the check, but you can do it by invoking the same public static methods often used in ASP.NET or other UI code.
I'm not near an actual computer just now, but from memory I think this is all in Csla.Rules.AuthorizationRules.
I had a look at DataPortal<T>.DoFetchAsync to see how it was being called in there and have essentially recreated it in my IAuthorizeDataPortal:
if (!BusinessRules.HasPermission(clientRequest.Operation.ToAuthAction(), clientRequest.ObjectType))
throw new SecurityException(
string.Format(Resources.UserNotAuthorizedException, clientRequest.Operation.ToSecurityActionDescription(), clientRequest.ObjectType.Name)
(With a couple of extension methods to a) map the Operation to AuthorizationAction and b) duplicate the logic from the DataPortal to provide the friendly action in the exception message, such as "get", "create" etc.)
It's a shame that I have to throw the exception myself (and build the message string myself to match what the client data portal does) - a BusinessRules.CheckPermissions method that did this for me would be useful. Just a thought.
You could add a feature request to GitHub for this if you'd like. If you are ambitious you could implement it and do a pull request :)
Ambitious, but busy ;)
I will see what I can do.