This example demonstrates how to build aspects that automatically encrypt or decrypt parameter values. The only encryption algorithm implemented in this example is string reversal. This is not real encryption, of course! In practice, you would probably use a format-preserving encryption algorithm from a third party.
The FilterAttribute
class is the abstract implementation of the aspect. It is not bound
to any encryption implementation algorithm. To implement a specific algorithm, you need
to derive a new class from FilterAttribute
class. In this example, we just show
a ReserseAttribute
aspect.
In some situations, for instance in ASP.NET MVC controllers, you may need to decrypt or
encrypt properties of a method parameter instead of the parameter itself (encrypting
an object is impossible; you can only either serialize its members with a format-preserving
algorithm, or the serialization of the object using binary encryption). For this scenario,
we have the ApplyFiltersAttribute
, also derived from FilterAttribute
. This custom
attribute causes the parameter value to be deeply decrypted or encrypted. You can apply
any filter attribute (either [Reverse]
or [ApplyFilters]
in this example) to
fields and properties of the parameter class.
What is being demonstrated?
The FilterAttribute
class is more complex than it appears because it must support
two cases: encryption of parameter values and deep encryption of object trees. Under
the cover, the job is done by two separate aspects: FilterMethodArgumentsAspect
and
FilterTypePropertiesAspect
. However, we don't want to ask developers to choose between
the aspects. All we want to show to developers are front-end attributes derived
from the FilterAttribute
class. Therefore, we use FilterAttribute
as an
umbrella, hiding the implementation complexity. The FilterAttribute
class whether
it has to provide a FilterMethodArgumentsAspect
or
FilterTypePropertiesAspect
aspect. This is done by implementing the IAspectProvider
interface.
The FilterMethodArgumentsAspect
class is quite simple and is based on a
MethodInterceptionAspect
. It is worth noting that we want to have a single
instance of the FilterMethodArgumentsAspect
class per method, even if several parameters
are encrypted. The FilterAttribute
has to provide the de-duplication. This is
done by using the IAspectRepositoryService
service from PostSharp, which returns which
aspects have already been added to a declaration.
The FilterTypePropertiesAspect
class is more complex. It introduces the IFilterable
interface into the target type, an interface which has a single method named ApplyFilters
.
To have access to fields and properties at runtime without reflection, the aspect
relies on an IAdviceProvider
which provides a set of ImportLocationAdviceInstance
advices: one for each encrypted property. At runtime, the bindings
field of the aspect class
is populated with a List<ILocationBinding>
, which gives access to all properties.