I've got a requirement to protect my business object properties via a list of separate authorization rules. I want my authorization rules to be suspended during various operations such as converting to DTOs and executing validation rules (validating property values the current user does not have authorization to see).
The approach I'm looking at wraps the calls in a scope object that uses a [ThreadStatic] property to determine whether the authorization rules should be run:
public class SuspendedAuthorizationScope : IDisposable
{
[ThreadStatic]
public static bool AuthorizationRulesAreSuspended;
public SuspendedAuthorizationScope()
{
AuthorizationRulesAreSuspended = true;
}
public void Dispose()
{
AuthorizationRulesAreSuspended = false;
}
}
Here is the IsAuthorized check (from base class):
public bool IsAuthorized(string memberName, AuthorizedAction authorizationAction)
{
if (SuspendedAuthorizationScope.AuthorizationRulesAreSuspended)
return true;
var context = new RulesContext();
_rules.OfType<IAuthorizationRule>()
.Where(r => r.PropertyName == memberName)
.Where(r => r.AuthorizedAction == authorizationAction)
.ToList().ForEach(r => r.Execute(context));
return context.HasNoErrors();
}
Here is the ValidateProperty method demonstrating usage (from the base class):
private void ValidateProperty(string propertyName, IEnumerable<IValidationRule> rules)
{
using (new SuspendedAuthorizationScope())
{
var context = new RulesContext();
rules.ToList().ForEach(rule => rule.Execute(context));
if (HasNoErrors(context))
RemoveErrorsForProperty(propertyName);
else
AddErrorsForProperty(propertyName, context.Results);
}
NotifyErrorsChanged(propertyName);
}
I've got some tests around the scoping object that show that the expected/correct value of SuspendedAuthorizationScope.AuthorizationRulesAreSuspended is used as long as a lambda resolves in the scope of the using statement.
Are there any obvious flaws to this design? Is there anything in ASP.NET that I should be concerned with as far as threading goes?