SAF framework look at the metadata type to figure out the authorization rules. Although this is exactly what we want, but is a design flow. The reason I think it is a design flow and needs re-factoring is that it makes the rules to be defined in code.
Let’s imagine we want to seperate the role of Authorization rule definers from the programmers. Although, it is possible now, to implement IMetadataTypeProvider to load some external dll, but it is still bound to types which is not really necessary.
This means, the Grant and Deny attributes should not be limited to be attributes. It is possible with a small re factoring of the current code.
Let’s define a rule provider: IAuthorizationRuleProvider which retrieves rules for a given object. Grant and Deny are IPrincipalAuthorizer. We can give the IAuthorizationRuleProvider instead of to IMetadataProvier to the methods in PermissionHelper.
Then we need to define the AttributeAuthorizationRuleProvider which has a method GetAuthorizers and relies on an IMetadataProvider.
public class AttributeAuthorizationRuleProvider<T> : IAuthorizationRuleProvider { private MetadataProvider _metadataProvider; public AttributeAuthorizatonRuleProvider(MetadataProvider meta) { _metadataProvider = meta; } public IEnumerable<IPrincipalAuthorizer<T>> GetAuthorizers(Type type) { var meta = metadataProvider.GetMetadataType(type); //Get all attributes for the type return meta.GetCustomAttributes(false).OfType<IPrincipalAuthorizer<Permission>>(); } }
We later need an AuthorizationContext as a singleton like:
public class AuthorizationContext { IMetadataProvider _metadataProvider; IAuthorizationRuleProvider _authorizationRuleProvider; public AuthorizationContext(IMetadataProvider meta, IAuthorizationRuleProvider rule) { _metadataProvider = meta; _authorizationRuleProvider = rule; } //Wrap all the methods in Permission Helper. }
Later, we can define a new authorizationRuleProvider called SqlAurhorizationRuleProvider that uses database for authorization rule and in database we can have a table like:
TABLE Authorizations (AuthID, Type, Property)
TABLE AuthorizationRules (RuleID, AuthID, RuleType (Grand/Deny/Custom), ConditionCode, ConditionQuery)
TABLE AuthorizationRuleAssignments (RuleID, Role)
In my providers I avoid using the traditional Provider model because the complexity is not required here and using IoC and a Context object, eliminates the role of Manager for every single provider.
Leave a Reply