While I can't claim that this is "best practice," this is at least one approach, taken by Rockford Lhotka in Expert C# 2008 Business Objects.
You could have all domain entities eventually derive from some base class. That base class could have a method like this:
public virtual bool CanReadProperty(string propertyName) { ... }
That method could be called by each property before allowing the user to view it (or set it). For better performance, that base class could have the authorization roles cached, so checking wasn't an expensive operation. And, of course now that we have expression trees, CanReadProperty()
could take an expression so that it was strongly-typed.
An example of a property would look like this:
public string Name
{
get
{
if (!CanReadProperty("Name")) { return string.Empty; } // or return null, whatever...
return _name;
}
}
The benefit of this approach is that you don't need many different DTOs for the various scenarios where the viewing of these properties can change.