CSLA .NET

Vibrant discussion about CSLA .NET and using the framework to build great business applications.

Customize Authorization Rules Messages.

Answered (Verified) This post has 2 verified answers | 4 Replies | 1 Follower

Not Ranked
5 Posts
omarcusido posted on Fri, Oct 14 2011 1:40 PM

Hello all. I'm using Authorization Rules in my Business Objects but when any Authorization Rule is broken the message provided on the exception do not fits my needs. I was reviewing the implementation of the DataPortal class and CSLA throws a Security Exception and loads the exception message from a resource. I really wanted to know if there's a way to change that message to a customized dynamically created message without modify my DataPortal class, I also can't write directly in the resource file because the message is not always the same.

 

Regards.

 

OCP.

Answered (Verified) Verified Answer

Top 75 Contributor
112 Posts
Verified by omarcusido

Hi

As far as I know: no.  The EditObject action would be possible by overriding BusinessBase Save() Method or somthing in this area.

If I got the idea from the ebook ("Creating Business Objects") right, receiving a Security Exception for a broken authorization rule should be an "exception".

It's the UI's responsibility to check if its allowed before doing it: 

  • IsSavable includes test for permission
  • Per instance/property rules through IAuthorizeReadWrite CanRead/WriteProperty CanExecuteMethod
  • and per type access BusinessRules.HasPermission(AuthorizationActions.CreateObject/GetObject/EditObject/DeleteObject, typeof(MyObject) ). 

Also have a look at Csla.Xaml.ViewModelBase, which provides the Can.... Properties.

Here's a post which suggests to use validation rules in some cases rather than authorization rules.
http://forums.lhotka.net/forums/p/5760/28042.aspx

 

Top 10 Contributor
1,815 Posts
Verified by omarcusido

Hi,

CSLA does not provide a direct method for replacing the error message with your own.But you can add the checks in your own code and throw your own exception.

For the DataPortal you will have to implement the authorization check in you own static factory methods, ex:

    public static Root NewEditableRoot()
    {
      if (!Csla.Rules.BusinessRules.HasPermission(AuthorizationActions.CreateObject, typeof(Root)))
          throw new SecurityException("my custom message");
      
      return DataPortal.Create<Root>();
    }

For Save I would recommend that you create your own intermediate base class for ex BusinessBase and override the Save method and you could even promote the message to a property or lambda expression (marked as nonserializable) to allow to just set the message for each object.

  [Serializable]
  public class MyBusinessBase<T> : Csla.BusinessBase<T> where T:MyBusinessBase<T>
  {
    public override T Save()
    {
      T result;
      if (this.IsChild)
        throw new InvalidOperationException(Csla.Properties.Resources.NoSaveChildException);
      if (EditLevel > 0)
        throw new InvalidOperationException(Csla.Properties.Resources.NoSaveEditingException);
      if (!IsValid && !IsDeleted)
        throw new Csla.Rules.ValidationException(Csla.Properties.Resources.NoSaveInvalidException);
      if (IsBusy)
        throw new InvalidOperationException(Csla.Properties.Resources.BusyObjectsMayNotBeSaved);
      if (IsDirty)
      {
        // this is the same check that DataPortal does for object of type BusinessBase
        if (this.IsDeleted)
        {
          if (!Csla.Rules.BusinessRules.HasPermission(Csla.Rules.AuthorizationActions.DeleteObject, this))
            throw new System.Security.SecurityException("custom message - not allowed to delete");
        }
        else
        {
          if (!Csla.Rules.BusinessRules.HasPermission(Csla.Rules.AuthorizationActions.EditObject, this))
            throw new System.Security.SecurityException("custom message - not allowed to save");
        }
        result = (T) DataPortal.Update(this);
      }
      else
        result = (T)this;
      OnSaved(result, nullnull);
      return result;
    }
  }

 

Jonny Bekkum, Norway CslaContrib Coordinator

All Replies

Top 75 Contributor
112 Posts
Verified by omarcusido

Hi

As far as I know: no.  The EditObject action would be possible by overriding BusinessBase Save() Method or somthing in this area.

If I got the idea from the ebook ("Creating Business Objects") right, receiving a Security Exception for a broken authorization rule should be an "exception".

It's the UI's responsibility to check if its allowed before doing it: 

  • IsSavable includes test for permission
  • Per instance/property rules through IAuthorizeReadWrite CanRead/WriteProperty CanExecuteMethod
  • and per type access BusinessRules.HasPermission(AuthorizationActions.CreateObject/GetObject/EditObject/DeleteObject, typeof(MyObject) ). 

Also have a look at Csla.Xaml.ViewModelBase, which provides the Can.... Properties.

Here's a post which suggests to use validation rules in some cases rather than authorization rules.
http://forums.lhotka.net/forums/p/5760/28042.aspx

 

Top 10 Contributor
1,815 Posts
Verified by omarcusido

Hi,

CSLA does not provide a direct method for replacing the error message with your own.But you can add the checks in your own code and throw your own exception.

For the DataPortal you will have to implement the authorization check in you own static factory methods, ex:

    public static Root NewEditableRoot()
    {
      if (!Csla.Rules.BusinessRules.HasPermission(AuthorizationActions.CreateObject, typeof(Root)))
          throw new SecurityException("my custom message");
      
      return DataPortal.Create<Root>();
    }

For Save I would recommend that you create your own intermediate base class for ex BusinessBase and override the Save method and you could even promote the message to a property or lambda expression (marked as nonserializable) to allow to just set the message for each object.

  [Serializable]
  public class MyBusinessBase<T> : Csla.BusinessBase<T> where T:MyBusinessBase<T>
  {
    public override T Save()
    {
      T result;
      if (this.IsChild)
        throw new InvalidOperationException(Csla.Properties.Resources.NoSaveChildException);
      if (EditLevel > 0)
        throw new InvalidOperationException(Csla.Properties.Resources.NoSaveEditingException);
      if (!IsValid && !IsDeleted)
        throw new Csla.Rules.ValidationException(Csla.Properties.Resources.NoSaveInvalidException);
      if (IsBusy)
        throw new InvalidOperationException(Csla.Properties.Resources.BusyObjectsMayNotBeSaved);
      if (IsDirty)
      {
        // this is the same check that DataPortal does for object of type BusinessBase
        if (this.IsDeleted)
        {
          if (!Csla.Rules.BusinessRules.HasPermission(Csla.Rules.AuthorizationActions.DeleteObject, this))
            throw new System.Security.SecurityException("custom message - not allowed to delete");
        }
        else
        {
          if (!Csla.Rules.BusinessRules.HasPermission(Csla.Rules.AuthorizationActions.EditObject, this))
            throw new System.Security.SecurityException("custom message - not allowed to save");
        }
        result = (T) DataPortal.Update(this);
      }
      else
        result = (T)this;
      OnSaved(result, nullnull);
      return result;
    }
  }

 

Jonny Bekkum, Norway CslaContrib Coordinator

Top 75 Contributor
112 Posts

Jonny,

good, clean sample of what I meant to say....

thx

Not Ranked
5 Posts

Thats works for me. Thanks a lot guys.

Page 1 of 1 (5 items) | RSS

Copyright (c) 2006-2010 Marimer LLC. All rights reserved.
Email admin@lhotka.net for support.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems