For developers: Security related attributes
Sitefinity's security engine uses attributes to map provider methods to security actions. It is the programmer's responsibility to make this association.
All security-related attributes have a constructor that accepts permission set name and a list of security action names. Applying a permission attribute on a method will result in Sitefinity CMS demanding those actions when the method is invoked or before a transaction is committed.
The type of attribute being used determines on which secured object Sitefinity CMS will demand the specified security actions. Every group of attributes has a section that contains more information.
NOTE: In this topic the suffix "Attribute" is skipped for the sake of simplicity.
IMPORTANT: Sitefinity CMS uses IoC framework to intercept method calls for model events, security and others. It is very important that methods decorated with permission attributes are virtual. If this requirement is not met, Sitefinity CMS won't be able to itercept the methods and therefore those attributes will be effectively ignored.
Here is the hierarchy of Sitefinity's permission attributes:
Overview of typed versions of the attributes
A close look at the class diagram shows that some of the attributes have close names:
MethodPermission
and TypedMethodPermission
ValuePermission
and TypedValuePermission
ParameterPermission
and TypedParameterPermission
EnumeratorPermission
and TypedEnumeratorPermission
Since the attribute functionality is almost the same, they will be explained together. Meaning of the type specification will be noted in each section.
All typed attributes' costructor's first argument is a CLR type. This is the only difference with their more generic counterparts.
Typed attributes demand the specified security actions only if the type given in the attribute matches that of the secured object.
Method permissions
Permissions are demanded on the provider's security root. Such a check would be OK if no granular permissions are needed. In any other case a value permission attribute would be the proper choice.
Typed method permissions work with methods that are generic. The generic argument's type is compared with the attribute's type. Demanding is done only if both types are the same.
NOTE: Using typed method permissions on methods that are not generic will have no effect. If a generic method has more than one generic argument, only the first generic argument's type will be used.
Value permissions
Value permissions make the Sitefinity CMS engine demand permissions on the returned value. The check is performed before the user code receives it, and thus the call is secured.
NOTE: Using value permission attributes with methods that do not return value will result in ignoring the attribute.
Parameter permissions
Parameter permissions make Sitefinity CMS demand on the parameters of the method. If one needs to check against more than one parameter, a separate attribute for every parameter should be used.
NOTE:Using parameter attributes for arguments that are not present in the method will result in raisng an exception.
Enumerator permissions
When this attribute is used, the method must return a collection implementing IEnumerable, whose elements are secured objects.
Sitefinity CMS wraps that collection and demands on every individual element before it can be accessed from the end-user.
Application permissions
Use this attribute when you want to demand application permissions.
Transaction permissions
Certain actions cannot be effectively checked when a method is executed, unless a functional programming language is used. Since there are no methods for every action you can perform, there is the so-called delayed permission checking.
Sitefinity CMS performs these demands when a transaction is committed. Since the idea of a transaction is that either all changes are applied, or a rollback is done, those actions are effectively demanded on.
Cleanup security when deleting a data provider
In the delete
method of a data provider where you have typed versions of attributes, you should call this code:
When you handle this in your types, the table sf_permissions_inheritance_map
can avoid being flooded with unused ids.